1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;; %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
50 [; Relocation specifiers
63 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
69 (UNSPEC_SET_GOT_OFFSET 17)
74 (UNSPEC_TLS_LD_BASE 20)
77 ; Other random patterns
86 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
87 (UNSPEC_TRUNC_NOOP 39)
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 40)
108 ; Generic math support
110 (UNSPEC_IEEE_MIN 51) ; not commutative
111 (UNSPEC_IEEE_MAX 52) ; not commutative
126 (UNSPEC_FRNDINT_FLOOR 70)
127 (UNSPEC_FRNDINT_CEIL 71)
128 (UNSPEC_FRNDINT_TRUNC 72)
129 (UNSPEC_FRNDINT_MASK_PM 73)
130 (UNSPEC_FIST_FLOOR 74)
131 (UNSPEC_FIST_CEIL 75)
133 ; x87 Double output FP
134 (UNSPEC_SINCOS_COS 80)
135 (UNSPEC_SINCOS_SIN 81)
136 (UNSPEC_XTRACT_FRACT 84)
137 (UNSPEC_XTRACT_EXP 85)
138 (UNSPEC_FSCALE_FRACT 86)
139 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
161 (UNSPEC_INSERTQI 132)
166 (UNSPEC_INSERTPS 135)
168 (UNSPEC_MOVNTDQA 137)
170 (UNSPEC_PHMINPOSUW 139)
176 (UNSPEC_PCMPESTR 144)
177 (UNSPEC_PCMPISTR 145)
180 (UNSPEC_SSE5_INTRINSIC 150)
181 (UNSPEC_SSE5_UNSIGNED_CMP 151)
182 (UNSPEC_SSE5_TRUEFALSE 152)
183 (UNSPEC_SSE5_PERMUTE 153)
184 (UNSPEC_SSE5_ASHIFT 154)
185 (UNSPEC_SSE5_LSHIFT 155)
187 (UNSPEC_CVTPH2PS 157)
188 (UNSPEC_CVTPS2PH 158)
192 (UNSPEC_AESENCLAST 160)
194 (UNSPEC_AESDECLAST 162)
196 (UNSPEC_AESKEYGENASSIST 164)
203 [(UNSPECV_BLOCKAGE 0)
204 (UNSPECV_STACK_PROBE 1)
213 (UNSPECV_CMPXCHG_1 10)
214 (UNSPECV_CMPXCHG_2 11)
217 (UNSPECV_PROLOGUE_USE 14)
220 ;; Constants to represent pcomtrue/pcomfalse variants
230 ;; Registers by name.
246 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
249 ;; In C guard expressions, put expressions which may be compile-time
250 ;; constants first. This allows for better optimization. For
251 ;; example, write "TARGET_64BIT && reload_completed", not
252 ;; "reload_completed && TARGET_64BIT".
255 ;; Processor type. This attribute must exactly match the processor_type
256 ;; enumeration in i386.h.
257 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
258 nocona,core2,generic32,generic64,amdfam10"
259 (const (symbol_ref "ix86_tune")))
261 ;; A basic instruction type. Refinements due to arguments to be
262 ;; provided in other attributes.
265 alu,alu1,negnot,imov,imovx,lea,
266 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
267 icmp,test,ibr,setcc,icmov,
268 push,pop,call,callv,leave,
270 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
271 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
272 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
274 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
275 (const_string "other"))
277 ;; Main data type used by the insn
279 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
280 (const_string "unknown"))
282 ;; The CPU unit operations uses.
283 (define_attr "unit" "integer,i387,sse,mmx,unknown"
284 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
285 (const_string "i387")
286 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
287 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
288 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
290 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
292 (eq_attr "type" "other")
293 (const_string "unknown")]
294 (const_string "integer")))
296 ;; The (bounding maximum) length of an instruction immediate.
297 (define_attr "length_immediate" ""
298 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
301 (eq_attr "unit" "i387,sse,mmx")
303 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
305 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
306 (eq_attr "type" "imov,test")
307 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
308 (eq_attr "type" "call")
309 (if_then_else (match_operand 0 "constant_call_address_operand" "")
312 (eq_attr "type" "callv")
313 (if_then_else (match_operand 1 "constant_call_address_operand" "")
316 ;; We don't know the size before shorten_branches. Expect
317 ;; the instruction to fit for better scheduling.
318 (eq_attr "type" "ibr")
321 (symbol_ref "/* Update immediate_length and other attributes! */
322 gcc_unreachable (),1")))
324 ;; The (bounding maximum) length of an instruction address.
325 (define_attr "length_address" ""
326 (cond [(eq_attr "type" "str,other,multi,fxch")
328 (and (eq_attr "type" "call")
329 (match_operand 0 "constant_call_address_operand" ""))
331 (and (eq_attr "type" "callv")
332 (match_operand 1 "constant_call_address_operand" ""))
335 (symbol_ref "ix86_attr_length_address_default (insn)")))
337 ;; Set when length prefix is used.
338 (define_attr "prefix_data16" ""
339 (if_then_else (ior (eq_attr "mode" "HI")
340 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
344 ;; Set when string REP prefix is used.
345 (define_attr "prefix_rep" ""
346 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
350 ;; Set when 0f opcode prefix is used.
351 (define_attr "prefix_0f" ""
353 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
354 (eq_attr "unit" "sse,mmx"))
358 ;; Set when REX opcode prefix is used.
359 (define_attr "prefix_rex" ""
360 (cond [(and (eq_attr "mode" "DI")
361 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
363 (and (eq_attr "mode" "QI")
364 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
367 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
373 ;; There are also additional prefixes in SSSE3.
374 (define_attr "prefix_extra" "" (const_int 0))
376 ;; Set when modrm byte is used.
377 (define_attr "modrm" ""
378 (cond [(eq_attr "type" "str,leave")
380 (eq_attr "unit" "i387")
382 (and (eq_attr "type" "incdec")
383 (ior (match_operand:SI 1 "register_operand" "")
384 (match_operand:HI 1 "register_operand" "")))
386 (and (eq_attr "type" "push")
387 (not (match_operand 1 "memory_operand" "")))
389 (and (eq_attr "type" "pop")
390 (not (match_operand 0 "memory_operand" "")))
392 (and (eq_attr "type" "imov")
393 (ior (and (match_operand 0 "register_operand" "")
394 (match_operand 1 "immediate_operand" ""))
395 (ior (and (match_operand 0 "ax_reg_operand" "")
396 (match_operand 1 "memory_displacement_only_operand" ""))
397 (and (match_operand 0 "memory_displacement_only_operand" "")
398 (match_operand 1 "ax_reg_operand" "")))))
400 (and (eq_attr "type" "call")
401 (match_operand 0 "constant_call_address_operand" ""))
403 (and (eq_attr "type" "callv")
404 (match_operand 1 "constant_call_address_operand" ""))
409 ;; The (bounding maximum) length of an instruction in bytes.
410 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
411 ;; Later we may want to split them and compute proper length as for
413 (define_attr "length" ""
414 (cond [(eq_attr "type" "other,multi,fistp,frndint")
416 (eq_attr "type" "fcmp")
418 (eq_attr "unit" "i387")
420 (plus (attr "prefix_data16")
421 (attr "length_address")))]
422 (plus (plus (attr "modrm")
423 (plus (attr "prefix_0f")
424 (plus (attr "prefix_rex")
425 (plus (attr "prefix_extra")
427 (plus (attr "prefix_rep")
428 (plus (attr "prefix_data16")
429 (plus (attr "length_immediate")
430 (attr "length_address")))))))
432 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
433 ;; `store' if there is a simple memory reference therein, or `unknown'
434 ;; if the instruction is complex.
436 (define_attr "memory" "none,load,store,both,unknown"
437 (cond [(eq_attr "type" "other,multi,str")
438 (const_string "unknown")
439 (eq_attr "type" "lea,fcmov,fpspc")
440 (const_string "none")
441 (eq_attr "type" "fistp,leave")
442 (const_string "both")
443 (eq_attr "type" "frndint")
444 (const_string "load")
445 (eq_attr "type" "push")
446 (if_then_else (match_operand 1 "memory_operand" "")
447 (const_string "both")
448 (const_string "store"))
449 (eq_attr "type" "pop")
450 (if_then_else (match_operand 0 "memory_operand" "")
451 (const_string "both")
452 (const_string "load"))
453 (eq_attr "type" "setcc")
454 (if_then_else (match_operand 0 "memory_operand" "")
455 (const_string "store")
456 (const_string "none"))
457 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
458 (if_then_else (ior (match_operand 0 "memory_operand" "")
459 (match_operand 1 "memory_operand" ""))
460 (const_string "load")
461 (const_string "none"))
462 (eq_attr "type" "ibr")
463 (if_then_else (match_operand 0 "memory_operand" "")
464 (const_string "load")
465 (const_string "none"))
466 (eq_attr "type" "call")
467 (if_then_else (match_operand 0 "constant_call_address_operand" "")
468 (const_string "none")
469 (const_string "load"))
470 (eq_attr "type" "callv")
471 (if_then_else (match_operand 1 "constant_call_address_operand" "")
472 (const_string "none")
473 (const_string "load"))
474 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
475 (match_operand 1 "memory_operand" ""))
476 (const_string "both")
477 (and (match_operand 0 "memory_operand" "")
478 (match_operand 1 "memory_operand" ""))
479 (const_string "both")
480 (match_operand 0 "memory_operand" "")
481 (const_string "store")
482 (match_operand 1 "memory_operand" "")
483 (const_string "load")
485 "!alu1,negnot,ishift1,
486 imov,imovx,icmp,test,bitmanip,
488 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
489 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
490 (match_operand 2 "memory_operand" ""))
491 (const_string "load")
492 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
493 (match_operand 3 "memory_operand" ""))
494 (const_string "load")
496 (const_string "none")))
498 ;; Indicates if an instruction has both an immediate and a displacement.
500 (define_attr "imm_disp" "false,true,unknown"
501 (cond [(eq_attr "type" "other,multi")
502 (const_string "unknown")
503 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
504 (and (match_operand 0 "memory_displacement_operand" "")
505 (match_operand 1 "immediate_operand" "")))
506 (const_string "true")
507 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
508 (and (match_operand 0 "memory_displacement_operand" "")
509 (match_operand 2 "immediate_operand" "")))
510 (const_string "true")
512 (const_string "false")))
514 ;; Indicates if an FP operation has an integer source.
516 (define_attr "fp_int_src" "false,true"
517 (const_string "false"))
519 ;; Defines rounding mode of an FP operation.
521 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
522 (const_string "any"))
524 ;; Describe a user's asm statement.
525 (define_asm_attributes
526 [(set_attr "length" "128")
527 (set_attr "type" "multi")])
529 ;; All integer comparison codes.
530 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
532 ;; All floating-point comparison codes.
533 (define_code_iterator fp_cond [unordered ordered
534 uneq unge ungt unle unlt ltgt ])
536 (define_code_iterator plusminus [plus minus])
538 ;; Base name for define_insn and insn mnemonic.
539 (define_code_attr addsub [(plus "add") (minus "sub")])
541 ;; Mark commutative operators as such in constraints.
542 (define_code_attr comm [(plus "%") (minus "")])
544 ;; Mapping of signed max and min
545 (define_code_iterator smaxmin [smax smin])
547 ;; Mapping of unsigned max and min
548 (define_code_iterator umaxmin [umax umin])
550 ;; Base name for integer and FP insn mnemonic
551 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
552 (umax "maxu") (umin "minu")])
553 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
555 ;; Mapping of parallel logic operators
556 (define_code_iterator plogic [and ior xor])
558 ;; Base name for insn mnemonic.
559 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
561 ;; Mapping of abs neg operators
562 (define_code_iterator absneg [abs neg])
564 ;; Base name for x87 insn mnemonic.
565 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
567 ;; All single word integer modes.
568 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
570 ;; Instruction suffix for integer modes.
571 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
573 ;; Register class for integer modes.
574 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
576 ;; Immediate operand constraint for integer modes.
577 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
579 ;; General operand predicate for integer modes.
580 (define_mode_attr general_operand
581 [(QI "general_operand")
582 (HI "general_operand")
583 (SI "general_operand")
584 (DI "x86_64_general_operand")])
586 ;; SSE and x87 SFmode and DFmode floating point modes
587 (define_mode_iterator MODEF [SF DF])
589 ;; All x87 floating point modes
590 (define_mode_iterator X87MODEF [SF DF XF])
592 ;; All integer modes handled by x87 fisttp operator.
593 (define_mode_iterator X87MODEI [HI SI DI])
595 ;; All integer modes handled by integer x87 operators.
596 (define_mode_iterator X87MODEI12 [HI SI])
598 ;; All integer modes handled by SSE cvtts?2si* operators.
599 (define_mode_iterator SSEMODEI24 [SI DI])
601 ;; SSE asm suffix for floating point modes
602 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
604 ;; SSE vector mode corresponding to a scalar mode
605 (define_mode_attr ssevecmode
606 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
608 ;; Instruction suffix for REX 64bit operators.
609 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
611 ;; Scheduling descriptions
613 (include "pentium.md")
616 (include "athlon.md")
620 ;; Operand and operator predicates and constraints
622 (include "predicates.md")
623 (include "constraints.md")
626 ;; Compare instructions.
628 ;; All compare insns have expanders that save the operands away without
629 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
630 ;; after the cmp) will actually emit the cmpM.
632 (define_expand "cmpti"
633 [(set (reg:CC FLAGS_REG)
634 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
635 (match_operand:TI 1 "x86_64_general_operand" "")))]
638 if (MEM_P (operands[0]) && MEM_P (operands[1]))
639 operands[0] = force_reg (TImode, operands[0]);
640 ix86_compare_op0 = operands[0];
641 ix86_compare_op1 = operands[1];
645 (define_expand "cmpdi"
646 [(set (reg:CC FLAGS_REG)
647 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
648 (match_operand:DI 1 "x86_64_general_operand" "")))]
651 if (MEM_P (operands[0]) && MEM_P (operands[1]))
652 operands[0] = force_reg (DImode, operands[0]);
653 ix86_compare_op0 = operands[0];
654 ix86_compare_op1 = operands[1];
658 (define_expand "cmpsi"
659 [(set (reg:CC FLAGS_REG)
660 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
661 (match_operand:SI 1 "general_operand" "")))]
664 if (MEM_P (operands[0]) && MEM_P (operands[1]))
665 operands[0] = force_reg (SImode, operands[0]);
666 ix86_compare_op0 = operands[0];
667 ix86_compare_op1 = operands[1];
671 (define_expand "cmphi"
672 [(set (reg:CC FLAGS_REG)
673 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
674 (match_operand:HI 1 "general_operand" "")))]
677 if (MEM_P (operands[0]) && MEM_P (operands[1]))
678 operands[0] = force_reg (HImode, operands[0]);
679 ix86_compare_op0 = operands[0];
680 ix86_compare_op1 = operands[1];
684 (define_expand "cmpqi"
685 [(set (reg:CC FLAGS_REG)
686 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
687 (match_operand:QI 1 "general_operand" "")))]
690 if (MEM_P (operands[0]) && MEM_P (operands[1]))
691 operands[0] = force_reg (QImode, operands[0]);
692 ix86_compare_op0 = operands[0];
693 ix86_compare_op1 = operands[1];
697 (define_insn "cmpdi_ccno_1_rex64"
698 [(set (reg FLAGS_REG)
699 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
700 (match_operand:DI 1 "const0_operand" "n,n")))]
701 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
704 cmp{q}\t{%1, %0|%0, %1}"
705 [(set_attr "type" "test,icmp")
706 (set_attr "length_immediate" "0,1")
707 (set_attr "mode" "DI")])
709 (define_insn "*cmpdi_minus_1_rex64"
710 [(set (reg FLAGS_REG)
711 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
712 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
714 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
715 "cmp{q}\t{%1, %0|%0, %1}"
716 [(set_attr "type" "icmp")
717 (set_attr "mode" "DI")])
719 (define_expand "cmpdi_1_rex64"
720 [(set (reg:CC FLAGS_REG)
721 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
722 (match_operand:DI 1 "general_operand" "")))]
726 (define_insn "cmpdi_1_insn_rex64"
727 [(set (reg FLAGS_REG)
728 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
729 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
730 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
731 "cmp{q}\t{%1, %0|%0, %1}"
732 [(set_attr "type" "icmp")
733 (set_attr "mode" "DI")])
736 (define_insn "*cmpsi_ccno_1"
737 [(set (reg FLAGS_REG)
738 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
739 (match_operand:SI 1 "const0_operand" "n,n")))]
740 "ix86_match_ccmode (insn, CCNOmode)"
743 cmp{l}\t{%1, %0|%0, %1}"
744 [(set_attr "type" "test,icmp")
745 (set_attr "length_immediate" "0,1")
746 (set_attr "mode" "SI")])
748 (define_insn "*cmpsi_minus_1"
749 [(set (reg FLAGS_REG)
750 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
751 (match_operand:SI 1 "general_operand" "ri,mr"))
753 "ix86_match_ccmode (insn, CCGOCmode)"
754 "cmp{l}\t{%1, %0|%0, %1}"
755 [(set_attr "type" "icmp")
756 (set_attr "mode" "SI")])
758 (define_expand "cmpsi_1"
759 [(set (reg:CC FLAGS_REG)
760 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
761 (match_operand:SI 1 "general_operand" "")))]
765 (define_insn "*cmpsi_1_insn"
766 [(set (reg FLAGS_REG)
767 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
768 (match_operand:SI 1 "general_operand" "ri,mr")))]
769 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
770 && ix86_match_ccmode (insn, CCmode)"
771 "cmp{l}\t{%1, %0|%0, %1}"
772 [(set_attr "type" "icmp")
773 (set_attr "mode" "SI")])
775 (define_insn "*cmphi_ccno_1"
776 [(set (reg FLAGS_REG)
777 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
778 (match_operand:HI 1 "const0_operand" "n,n")))]
779 "ix86_match_ccmode (insn, CCNOmode)"
782 cmp{w}\t{%1, %0|%0, %1}"
783 [(set_attr "type" "test,icmp")
784 (set_attr "length_immediate" "0,1")
785 (set_attr "mode" "HI")])
787 (define_insn "*cmphi_minus_1"
788 [(set (reg FLAGS_REG)
789 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
790 (match_operand:HI 1 "general_operand" "ri,mr"))
792 "ix86_match_ccmode (insn, CCGOCmode)"
793 "cmp{w}\t{%1, %0|%0, %1}"
794 [(set_attr "type" "icmp")
795 (set_attr "mode" "HI")])
797 (define_insn "*cmphi_1"
798 [(set (reg FLAGS_REG)
799 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
800 (match_operand:HI 1 "general_operand" "ri,mr")))]
801 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
802 && ix86_match_ccmode (insn, CCmode)"
803 "cmp{w}\t{%1, %0|%0, %1}"
804 [(set_attr "type" "icmp")
805 (set_attr "mode" "HI")])
807 (define_insn "*cmpqi_ccno_1"
808 [(set (reg FLAGS_REG)
809 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
810 (match_operand:QI 1 "const0_operand" "n,n")))]
811 "ix86_match_ccmode (insn, CCNOmode)"
814 cmp{b}\t{$0, %0|%0, 0}"
815 [(set_attr "type" "test,icmp")
816 (set_attr "length_immediate" "0,1")
817 (set_attr "mode" "QI")])
819 (define_insn "*cmpqi_1"
820 [(set (reg FLAGS_REG)
821 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
822 (match_operand:QI 1 "general_operand" "qi,mq")))]
823 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
824 && ix86_match_ccmode (insn, CCmode)"
825 "cmp{b}\t{%1, %0|%0, %1}"
826 [(set_attr "type" "icmp")
827 (set_attr "mode" "QI")])
829 (define_insn "*cmpqi_minus_1"
830 [(set (reg FLAGS_REG)
831 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
832 (match_operand:QI 1 "general_operand" "qi,mq"))
834 "ix86_match_ccmode (insn, CCGOCmode)"
835 "cmp{b}\t{%1, %0|%0, %1}"
836 [(set_attr "type" "icmp")
837 (set_attr "mode" "QI")])
839 (define_insn "*cmpqi_ext_1"
840 [(set (reg FLAGS_REG)
842 (match_operand:QI 0 "general_operand" "Qm")
845 (match_operand 1 "ext_register_operand" "Q")
848 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
849 "cmp{b}\t{%h1, %0|%0, %h1}"
850 [(set_attr "type" "icmp")
851 (set_attr "mode" "QI")])
853 (define_insn "*cmpqi_ext_1_rex64"
854 [(set (reg FLAGS_REG)
856 (match_operand:QI 0 "register_operand" "Q")
859 (match_operand 1 "ext_register_operand" "Q")
862 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
863 "cmp{b}\t{%h1, %0|%0, %h1}"
864 [(set_attr "type" "icmp")
865 (set_attr "mode" "QI")])
867 (define_insn "*cmpqi_ext_2"
868 [(set (reg FLAGS_REG)
872 (match_operand 0 "ext_register_operand" "Q")
875 (match_operand:QI 1 "const0_operand" "n")))]
876 "ix86_match_ccmode (insn, CCNOmode)"
878 [(set_attr "type" "test")
879 (set_attr "length_immediate" "0")
880 (set_attr "mode" "QI")])
882 (define_expand "cmpqi_ext_3"
883 [(set (reg:CC FLAGS_REG)
887 (match_operand 0 "ext_register_operand" "")
890 (match_operand:QI 1 "general_operand" "")))]
894 (define_insn "cmpqi_ext_3_insn"
895 [(set (reg FLAGS_REG)
899 (match_operand 0 "ext_register_operand" "Q")
902 (match_operand:QI 1 "general_operand" "Qmn")))]
903 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
904 "cmp{b}\t{%1, %h0|%h0, %1}"
905 [(set_attr "type" "icmp")
906 (set_attr "mode" "QI")])
908 (define_insn "cmpqi_ext_3_insn_rex64"
909 [(set (reg FLAGS_REG)
913 (match_operand 0 "ext_register_operand" "Q")
916 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
917 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
918 "cmp{b}\t{%1, %h0|%h0, %1}"
919 [(set_attr "type" "icmp")
920 (set_attr "mode" "QI")])
922 (define_insn "*cmpqi_ext_4"
923 [(set (reg FLAGS_REG)
927 (match_operand 0 "ext_register_operand" "Q")
932 (match_operand 1 "ext_register_operand" "Q")
935 "ix86_match_ccmode (insn, CCmode)"
936 "cmp{b}\t{%h1, %h0|%h0, %h1}"
937 [(set_attr "type" "icmp")
938 (set_attr "mode" "QI")])
940 ;; These implement float point compares.
941 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
942 ;; which would allow mix and match FP modes on the compares. Which is what
943 ;; the old patterns did, but with many more of them.
945 (define_expand "cmpxf"
946 [(set (reg:CC FLAGS_REG)
947 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
948 (match_operand:XF 1 "nonmemory_operand" "")))]
951 ix86_compare_op0 = operands[0];
952 ix86_compare_op1 = operands[1];
956 (define_expand "cmp<mode>"
957 [(set (reg:CC FLAGS_REG)
958 (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
959 (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
960 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
962 ix86_compare_op0 = operands[0];
963 ix86_compare_op1 = operands[1];
967 ;; FP compares, step 1:
968 ;; Set the FP condition codes.
970 ;; CCFPmode compare with exceptions
971 ;; CCFPUmode compare with no exceptions
973 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
974 ;; used to manage the reg stack popping would not be preserved.
976 (define_insn "*cmpfp_0"
977 [(set (match_operand:HI 0 "register_operand" "=a")
980 (match_operand 1 "register_operand" "f")
981 (match_operand 2 "const0_operand" "X"))]
983 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
984 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
985 "* return output_fp_compare (insn, operands, 0, 0);"
986 [(set_attr "type" "multi")
987 (set_attr "unit" "i387")
989 (cond [(match_operand:SF 1 "" "")
991 (match_operand:DF 1 "" "")
994 (const_string "XF")))])
996 (define_insn_and_split "*cmpfp_0_cc"
997 [(set (reg:CCFP FLAGS_REG)
999 (match_operand 1 "register_operand" "f")
1000 (match_operand 2 "const0_operand" "X")))
1001 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1002 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1003 && TARGET_SAHF && !TARGET_CMOVE
1004 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1006 "&& reload_completed"
1009 [(compare:CCFP (match_dup 1)(match_dup 2))]
1011 (set (reg:CC FLAGS_REG)
1012 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1014 [(set_attr "type" "multi")
1015 (set_attr "unit" "i387")
1017 (cond [(match_operand:SF 1 "" "")
1019 (match_operand:DF 1 "" "")
1022 (const_string "XF")))])
1024 (define_insn "*cmpfp_xf"
1025 [(set (match_operand:HI 0 "register_operand" "=a")
1028 (match_operand:XF 1 "register_operand" "f")
1029 (match_operand:XF 2 "register_operand" "f"))]
1032 "* return output_fp_compare (insn, operands, 0, 0);"
1033 [(set_attr "type" "multi")
1034 (set_attr "unit" "i387")
1035 (set_attr "mode" "XF")])
1037 (define_insn_and_split "*cmpfp_xf_cc"
1038 [(set (reg:CCFP FLAGS_REG)
1040 (match_operand:XF 1 "register_operand" "f")
1041 (match_operand:XF 2 "register_operand" "f")))
1042 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1044 && TARGET_SAHF && !TARGET_CMOVE"
1046 "&& reload_completed"
1049 [(compare:CCFP (match_dup 1)(match_dup 2))]
1051 (set (reg:CC FLAGS_REG)
1052 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1054 [(set_attr "type" "multi")
1055 (set_attr "unit" "i387")
1056 (set_attr "mode" "XF")])
1058 (define_insn "*cmpfp_<mode>"
1059 [(set (match_operand:HI 0 "register_operand" "=a")
1062 (match_operand:MODEF 1 "register_operand" "f")
1063 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1066 "* return output_fp_compare (insn, operands, 0, 0);"
1067 [(set_attr "type" "multi")
1068 (set_attr "unit" "i387")
1069 (set_attr "mode" "<MODE>")])
1071 (define_insn_and_split "*cmpfp_<mode>_cc"
1072 [(set (reg:CCFP FLAGS_REG)
1074 (match_operand:MODEF 1 "register_operand" "f")
1075 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1076 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1078 && TARGET_SAHF && !TARGET_CMOVE"
1080 "&& reload_completed"
1083 [(compare:CCFP (match_dup 1)(match_dup 2))]
1085 (set (reg:CC FLAGS_REG)
1086 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1088 [(set_attr "type" "multi")
1089 (set_attr "unit" "i387")
1090 (set_attr "mode" "<MODE>")])
1092 (define_insn "*cmpfp_u"
1093 [(set (match_operand:HI 0 "register_operand" "=a")
1096 (match_operand 1 "register_operand" "f")
1097 (match_operand 2 "register_operand" "f"))]
1099 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1100 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1101 "* return output_fp_compare (insn, operands, 0, 1);"
1102 [(set_attr "type" "multi")
1103 (set_attr "unit" "i387")
1105 (cond [(match_operand:SF 1 "" "")
1107 (match_operand:DF 1 "" "")
1110 (const_string "XF")))])
1112 (define_insn_and_split "*cmpfp_u_cc"
1113 [(set (reg:CCFPU FLAGS_REG)
1115 (match_operand 1 "register_operand" "f")
1116 (match_operand 2 "register_operand" "f")))
1117 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1118 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1119 && TARGET_SAHF && !TARGET_CMOVE
1120 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1122 "&& reload_completed"
1125 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1127 (set (reg:CC FLAGS_REG)
1128 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1130 [(set_attr "type" "multi")
1131 (set_attr "unit" "i387")
1133 (cond [(match_operand:SF 1 "" "")
1135 (match_operand:DF 1 "" "")
1138 (const_string "XF")))])
1140 (define_insn "*cmpfp_<mode>"
1141 [(set (match_operand:HI 0 "register_operand" "=a")
1144 (match_operand 1 "register_operand" "f")
1145 (match_operator 3 "float_operator"
1146 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1148 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1149 && TARGET_USE_<MODE>MODE_FIOP
1150 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1151 "* return output_fp_compare (insn, operands, 0, 0);"
1152 [(set_attr "type" "multi")
1153 (set_attr "unit" "i387")
1154 (set_attr "fp_int_src" "true")
1155 (set_attr "mode" "<MODE>")])
1157 (define_insn_and_split "*cmpfp_<mode>_cc"
1158 [(set (reg:CCFP FLAGS_REG)
1160 (match_operand 1 "register_operand" "f")
1161 (match_operator 3 "float_operator"
1162 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1163 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1164 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1165 && TARGET_SAHF && !TARGET_CMOVE
1166 && TARGET_USE_<MODE>MODE_FIOP
1167 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1169 "&& reload_completed"
1174 (match_op_dup 3 [(match_dup 2)]))]
1176 (set (reg:CC FLAGS_REG)
1177 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1179 [(set_attr "type" "multi")
1180 (set_attr "unit" "i387")
1181 (set_attr "fp_int_src" "true")
1182 (set_attr "mode" "<MODE>")])
1184 ;; FP compares, step 2
1185 ;; Move the fpsw to ax.
1187 (define_insn "x86_fnstsw_1"
1188 [(set (match_operand:HI 0 "register_operand" "=a")
1189 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1192 [(set_attr "length" "2")
1193 (set_attr "mode" "SI")
1194 (set_attr "unit" "i387")])
1196 ;; FP compares, step 3
1197 ;; Get ax into flags, general case.
1199 (define_insn "x86_sahf_1"
1200 [(set (reg:CC FLAGS_REG)
1201 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1205 #ifdef HAVE_AS_IX86_SAHF
1208 return ".byte\t0x9e";
1211 [(set_attr "length" "1")
1212 (set_attr "athlon_decode" "vector")
1213 (set_attr "amdfam10_decode" "direct")
1214 (set_attr "mode" "SI")])
1216 ;; Pentium Pro can do steps 1 through 3 in one go.
1217 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1218 (define_insn "*cmpfp_i_mixed"
1219 [(set (reg:CCFP FLAGS_REG)
1220 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1221 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1222 "TARGET_MIX_SSE_I387
1223 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1224 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1225 "* return output_fp_compare (insn, operands, 1, 0);"
1226 [(set_attr "type" "fcmp,ssecomi")
1228 (if_then_else (match_operand:SF 1 "" "")
1230 (const_string "DF")))
1231 (set_attr "athlon_decode" "vector")
1232 (set_attr "amdfam10_decode" "direct")])
1234 (define_insn "*cmpfp_i_sse"
1235 [(set (reg:CCFP FLAGS_REG)
1236 (compare:CCFP (match_operand 0 "register_operand" "x")
1237 (match_operand 1 "nonimmediate_operand" "xm")))]
1239 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1240 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1241 "* return output_fp_compare (insn, operands, 1, 0);"
1242 [(set_attr "type" "ssecomi")
1244 (if_then_else (match_operand:SF 1 "" "")
1246 (const_string "DF")))
1247 (set_attr "athlon_decode" "vector")
1248 (set_attr "amdfam10_decode" "direct")])
1250 (define_insn "*cmpfp_i_i387"
1251 [(set (reg:CCFP FLAGS_REG)
1252 (compare:CCFP (match_operand 0 "register_operand" "f")
1253 (match_operand 1 "register_operand" "f")))]
1254 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1256 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1257 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1258 "* return output_fp_compare (insn, operands, 1, 0);"
1259 [(set_attr "type" "fcmp")
1261 (cond [(match_operand:SF 1 "" "")
1263 (match_operand:DF 1 "" "")
1266 (const_string "XF")))
1267 (set_attr "athlon_decode" "vector")
1268 (set_attr "amdfam10_decode" "direct")])
1270 (define_insn "*cmpfp_iu_mixed"
1271 [(set (reg:CCFPU FLAGS_REG)
1272 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1273 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1274 "TARGET_MIX_SSE_I387
1275 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1276 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1277 "* return output_fp_compare (insn, operands, 1, 1);"
1278 [(set_attr "type" "fcmp,ssecomi")
1280 (if_then_else (match_operand:SF 1 "" "")
1282 (const_string "DF")))
1283 (set_attr "athlon_decode" "vector")
1284 (set_attr "amdfam10_decode" "direct")])
1286 (define_insn "*cmpfp_iu_sse"
1287 [(set (reg:CCFPU FLAGS_REG)
1288 (compare:CCFPU (match_operand 0 "register_operand" "x")
1289 (match_operand 1 "nonimmediate_operand" "xm")))]
1291 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1292 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1293 "* return output_fp_compare (insn, operands, 1, 1);"
1294 [(set_attr "type" "ssecomi")
1296 (if_then_else (match_operand:SF 1 "" "")
1298 (const_string "DF")))
1299 (set_attr "athlon_decode" "vector")
1300 (set_attr "amdfam10_decode" "direct")])
1302 (define_insn "*cmpfp_iu_387"
1303 [(set (reg:CCFPU FLAGS_REG)
1304 (compare:CCFPU (match_operand 0 "register_operand" "f")
1305 (match_operand 1 "register_operand" "f")))]
1306 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1308 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1309 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1310 "* return output_fp_compare (insn, operands, 1, 1);"
1311 [(set_attr "type" "fcmp")
1313 (cond [(match_operand:SF 1 "" "")
1315 (match_operand:DF 1 "" "")
1318 (const_string "XF")))
1319 (set_attr "athlon_decode" "vector")
1320 (set_attr "amdfam10_decode" "direct")])
1322 ;; Move instructions.
1324 ;; General case of fullword move.
1326 (define_expand "movsi"
1327 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1328 (match_operand:SI 1 "general_operand" ""))]
1330 "ix86_expand_move (SImode, operands); DONE;")
1332 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1335 ;; %%% We don't use a post-inc memory reference because x86 is not a
1336 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1337 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1338 ;; targets without our curiosities, and it is just as easy to represent
1339 ;; this differently.
1341 (define_insn "*pushsi2"
1342 [(set (match_operand:SI 0 "push_operand" "=<")
1343 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1346 [(set_attr "type" "push")
1347 (set_attr "mode" "SI")])
1349 ;; For 64BIT abi we always round up to 8 bytes.
1350 (define_insn "*pushsi2_rex64"
1351 [(set (match_operand:SI 0 "push_operand" "=X")
1352 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1355 [(set_attr "type" "push")
1356 (set_attr "mode" "SI")])
1358 (define_insn "*pushsi2_prologue"
1359 [(set (match_operand:SI 0 "push_operand" "=<")
1360 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1361 (clobber (mem:BLK (scratch)))]
1364 [(set_attr "type" "push")
1365 (set_attr "mode" "SI")])
1367 (define_insn "*popsi1_epilogue"
1368 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1369 (mem:SI (reg:SI SP_REG)))
1370 (set (reg:SI SP_REG)
1371 (plus:SI (reg:SI SP_REG) (const_int 4)))
1372 (clobber (mem:BLK (scratch)))]
1375 [(set_attr "type" "pop")
1376 (set_attr "mode" "SI")])
1378 (define_insn "popsi1"
1379 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1380 (mem:SI (reg:SI SP_REG)))
1381 (set (reg:SI SP_REG)
1382 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1385 [(set_attr "type" "pop")
1386 (set_attr "mode" "SI")])
1388 (define_insn "*movsi_xor"
1389 [(set (match_operand:SI 0 "register_operand" "=r")
1390 (match_operand:SI 1 "const0_operand" "i"))
1391 (clobber (reg:CC FLAGS_REG))]
1392 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1394 [(set_attr "type" "alu1")
1395 (set_attr "mode" "SI")
1396 (set_attr "length_immediate" "0")])
1398 (define_insn "*movsi_or"
1399 [(set (match_operand:SI 0 "register_operand" "=r")
1400 (match_operand:SI 1 "immediate_operand" "i"))
1401 (clobber (reg:CC FLAGS_REG))]
1403 && operands[1] == constm1_rtx
1404 && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1406 operands[1] = constm1_rtx;
1407 return "or{l}\t{%1, %0|%0, %1}";
1409 [(set_attr "type" "alu1")
1410 (set_attr "mode" "SI")
1411 (set_attr "length_immediate" "1")])
1413 (define_insn "*movsi_1"
1414 [(set (match_operand:SI 0 "nonimmediate_operand"
1415 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1416 (match_operand:SI 1 "general_operand"
1417 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1418 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1420 switch (get_attr_type (insn))
1423 if (get_attr_mode (insn) == MODE_TI)
1424 return "pxor\t%0, %0";
1425 return "xorps\t%0, %0";
1428 switch (get_attr_mode (insn))
1431 return "movdqa\t{%1, %0|%0, %1}";
1433 return "movaps\t{%1, %0|%0, %1}";
1435 return "movd\t{%1, %0|%0, %1}";
1437 return "movss\t{%1, %0|%0, %1}";
1443 return "pxor\t%0, %0";
1446 if (get_attr_mode (insn) == MODE_DI)
1447 return "movq\t{%1, %0|%0, %1}";
1448 return "movd\t{%1, %0|%0, %1}";
1451 return "lea{l}\t{%1, %0|%0, %1}";
1454 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1455 return "mov{l}\t{%1, %0|%0, %1}";
1459 (cond [(eq_attr "alternative" "2")
1460 (const_string "mmxadd")
1461 (eq_attr "alternative" "3,4,5")
1462 (const_string "mmxmov")
1463 (eq_attr "alternative" "6")
1464 (const_string "sselog1")
1465 (eq_attr "alternative" "7,8,9,10,11")
1466 (const_string "ssemov")
1467 (match_operand:DI 1 "pic_32bit_operand" "")
1468 (const_string "lea")
1470 (const_string "imov")))
1472 (cond [(eq_attr "alternative" "2,3")
1474 (eq_attr "alternative" "6,7")
1476 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1477 (const_string "V4SF")
1478 (const_string "TI"))
1479 (and (eq_attr "alternative" "8,9,10,11")
1480 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1483 (const_string "SI")))])
1485 ;; Stores and loads of ax to arbitrary constant address.
1486 ;; We fake an second form of instruction to force reload to load address
1487 ;; into register when rax is not available
1488 (define_insn "*movabssi_1_rex64"
1489 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1490 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1491 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1493 movabs{l}\t{%1, %P0|%P0, %1}
1494 mov{l}\t{%1, %a0|%a0, %1}"
1495 [(set_attr "type" "imov")
1496 (set_attr "modrm" "0,*")
1497 (set_attr "length_address" "8,0")
1498 (set_attr "length_immediate" "0,*")
1499 (set_attr "memory" "store")
1500 (set_attr "mode" "SI")])
1502 (define_insn "*movabssi_2_rex64"
1503 [(set (match_operand:SI 0 "register_operand" "=a,r")
1504 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1505 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1507 movabs{l}\t{%P1, %0|%0, %P1}
1508 mov{l}\t{%a1, %0|%0, %a1}"
1509 [(set_attr "type" "imov")
1510 (set_attr "modrm" "0,*")
1511 (set_attr "length_address" "8,0")
1512 (set_attr "length_immediate" "0")
1513 (set_attr "memory" "load")
1514 (set_attr "mode" "SI")])
1516 (define_insn "*swapsi"
1517 [(set (match_operand:SI 0 "register_operand" "+r")
1518 (match_operand:SI 1 "register_operand" "+r"))
1523 [(set_attr "type" "imov")
1524 (set_attr "mode" "SI")
1525 (set_attr "pent_pair" "np")
1526 (set_attr "athlon_decode" "vector")
1527 (set_attr "amdfam10_decode" "double")])
1529 (define_expand "movhi"
1530 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1531 (match_operand:HI 1 "general_operand" ""))]
1533 "ix86_expand_move (HImode, operands); DONE;")
1535 (define_insn "*pushhi2"
1536 [(set (match_operand:HI 0 "push_operand" "=X")
1537 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1540 [(set_attr "type" "push")
1541 (set_attr "mode" "SI")])
1543 ;; For 64BIT abi we always round up to 8 bytes.
1544 (define_insn "*pushhi2_rex64"
1545 [(set (match_operand:HI 0 "push_operand" "=X")
1546 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1549 [(set_attr "type" "push")
1550 (set_attr "mode" "DI")])
1552 (define_insn "*movhi_1"
1553 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1554 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1555 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1557 switch (get_attr_type (insn))
1560 /* movzwl is faster than movw on p2 due to partial word stalls,
1561 though not as fast as an aligned movl. */
1562 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1564 if (get_attr_mode (insn) == MODE_SI)
1565 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1567 return "mov{w}\t{%1, %0|%0, %1}";
1571 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1572 (const_string "imov")
1573 (and (eq_attr "alternative" "0")
1574 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1576 (eq (symbol_ref "TARGET_HIMODE_MATH")
1578 (const_string "imov")
1579 (and (eq_attr "alternative" "1,2")
1580 (match_operand:HI 1 "aligned_operand" ""))
1581 (const_string "imov")
1582 (and (ne (symbol_ref "TARGET_MOVX")
1584 (eq_attr "alternative" "0,2"))
1585 (const_string "imovx")
1587 (const_string "imov")))
1589 (cond [(eq_attr "type" "imovx")
1591 (and (eq_attr "alternative" "1,2")
1592 (match_operand:HI 1 "aligned_operand" ""))
1594 (and (eq_attr "alternative" "0")
1595 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1597 (eq (symbol_ref "TARGET_HIMODE_MATH")
1601 (const_string "HI")))])
1603 ;; Stores and loads of ax to arbitrary constant address.
1604 ;; We fake an second form of instruction to force reload to load address
1605 ;; into register when rax is not available
1606 (define_insn "*movabshi_1_rex64"
1607 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1608 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1609 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1611 movabs{w}\t{%1, %P0|%P0, %1}
1612 mov{w}\t{%1, %a0|%a0, %1}"
1613 [(set_attr "type" "imov")
1614 (set_attr "modrm" "0,*")
1615 (set_attr "length_address" "8,0")
1616 (set_attr "length_immediate" "0,*")
1617 (set_attr "memory" "store")
1618 (set_attr "mode" "HI")])
1620 (define_insn "*movabshi_2_rex64"
1621 [(set (match_operand:HI 0 "register_operand" "=a,r")
1622 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1623 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1625 movabs{w}\t{%P1, %0|%0, %P1}
1626 mov{w}\t{%a1, %0|%0, %a1}"
1627 [(set_attr "type" "imov")
1628 (set_attr "modrm" "0,*")
1629 (set_attr "length_address" "8,0")
1630 (set_attr "length_immediate" "0")
1631 (set_attr "memory" "load")
1632 (set_attr "mode" "HI")])
1634 (define_insn "*swaphi_1"
1635 [(set (match_operand:HI 0 "register_operand" "+r")
1636 (match_operand:HI 1 "register_operand" "+r"))
1639 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1641 [(set_attr "type" "imov")
1642 (set_attr "mode" "SI")
1643 (set_attr "pent_pair" "np")
1644 (set_attr "athlon_decode" "vector")
1645 (set_attr "amdfam10_decode" "double")])
1647 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1648 (define_insn "*swaphi_2"
1649 [(set (match_operand:HI 0 "register_operand" "+r")
1650 (match_operand:HI 1 "register_operand" "+r"))
1653 "TARGET_PARTIAL_REG_STALL"
1655 [(set_attr "type" "imov")
1656 (set_attr "mode" "HI")
1657 (set_attr "pent_pair" "np")
1658 (set_attr "athlon_decode" "vector")])
1660 (define_expand "movstricthi"
1661 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1662 (match_operand:HI 1 "general_operand" ""))]
1663 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1665 /* Don't generate memory->memory moves, go through a register */
1666 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1667 operands[1] = force_reg (HImode, operands[1]);
1670 (define_insn "*movstricthi_1"
1671 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1672 (match_operand:HI 1 "general_operand" "rn,m"))]
1673 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1674 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1675 "mov{w}\t{%1, %0|%0, %1}"
1676 [(set_attr "type" "imov")
1677 (set_attr "mode" "HI")])
1679 (define_insn "*movstricthi_xor"
1680 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1681 (match_operand:HI 1 "const0_operand" "i"))
1682 (clobber (reg:CC FLAGS_REG))]
1684 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1686 [(set_attr "type" "alu1")
1687 (set_attr "mode" "HI")
1688 (set_attr "length_immediate" "0")])
1690 (define_expand "movqi"
1691 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1692 (match_operand:QI 1 "general_operand" ""))]
1694 "ix86_expand_move (QImode, operands); DONE;")
1696 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1697 ;; "push a byte". But actually we use pushl, which has the effect
1698 ;; of rounding the amount pushed up to a word.
1700 (define_insn "*pushqi2"
1701 [(set (match_operand:QI 0 "push_operand" "=X")
1702 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1705 [(set_attr "type" "push")
1706 (set_attr "mode" "SI")])
1708 ;; For 64BIT abi we always round up to 8 bytes.
1709 (define_insn "*pushqi2_rex64"
1710 [(set (match_operand:QI 0 "push_operand" "=X")
1711 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1714 [(set_attr "type" "push")
1715 (set_attr "mode" "DI")])
1717 ;; Situation is quite tricky about when to choose full sized (SImode) move
1718 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1719 ;; partial register dependency machines (such as AMD Athlon), where QImode
1720 ;; moves issue extra dependency and for partial register stalls machines
1721 ;; that don't use QImode patterns (and QImode move cause stall on the next
1724 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1725 ;; register stall machines with, where we use QImode instructions, since
1726 ;; partial register stall can be caused there. Then we use movzx.
1727 (define_insn "*movqi_1"
1728 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1729 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1730 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1732 switch (get_attr_type (insn))
1735 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1736 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1738 if (get_attr_mode (insn) == MODE_SI)
1739 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1741 return "mov{b}\t{%1, %0|%0, %1}";
1745 (cond [(and (eq_attr "alternative" "5")
1746 (not (match_operand:QI 1 "aligned_operand" "")))
1747 (const_string "imovx")
1748 (ne (symbol_ref "optimize_size") (const_int 0))
1749 (const_string "imov")
1750 (and (eq_attr "alternative" "3")
1751 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1753 (eq (symbol_ref "TARGET_QIMODE_MATH")
1755 (const_string "imov")
1756 (eq_attr "alternative" "3,5")
1757 (const_string "imovx")
1758 (and (ne (symbol_ref "TARGET_MOVX")
1760 (eq_attr "alternative" "2"))
1761 (const_string "imovx")
1763 (const_string "imov")))
1765 (cond [(eq_attr "alternative" "3,4,5")
1767 (eq_attr "alternative" "6")
1769 (eq_attr "type" "imovx")
1771 (and (eq_attr "type" "imov")
1772 (and (eq_attr "alternative" "0,1")
1773 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1775 (and (eq (symbol_ref "optimize_size")
1777 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1780 ;; Avoid partial register stalls when not using QImode arithmetic
1781 (and (eq_attr "type" "imov")
1782 (and (eq_attr "alternative" "0,1")
1783 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1785 (eq (symbol_ref "TARGET_QIMODE_MATH")
1789 (const_string "QI")))])
1791 (define_expand "reload_outqi"
1792 [(parallel [(match_operand:QI 0 "" "=m")
1793 (match_operand:QI 1 "register_operand" "r")
1794 (match_operand:QI 2 "register_operand" "=&q")])]
1798 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1800 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1801 if (! q_regs_operand (op1, QImode))
1803 emit_insn (gen_movqi (op2, op1));
1806 emit_insn (gen_movqi (op0, op1));
1810 (define_insn "*swapqi_1"
1811 [(set (match_operand:QI 0 "register_operand" "+r")
1812 (match_operand:QI 1 "register_operand" "+r"))
1815 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1817 [(set_attr "type" "imov")
1818 (set_attr "mode" "SI")
1819 (set_attr "pent_pair" "np")
1820 (set_attr "athlon_decode" "vector")
1821 (set_attr "amdfam10_decode" "vector")])
1823 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1824 (define_insn "*swapqi_2"
1825 [(set (match_operand:QI 0 "register_operand" "+q")
1826 (match_operand:QI 1 "register_operand" "+q"))
1829 "TARGET_PARTIAL_REG_STALL"
1831 [(set_attr "type" "imov")
1832 (set_attr "mode" "QI")
1833 (set_attr "pent_pair" "np")
1834 (set_attr "athlon_decode" "vector")])
1836 (define_expand "movstrictqi"
1837 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1838 (match_operand:QI 1 "general_operand" ""))]
1839 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1841 /* Don't generate memory->memory moves, go through a register. */
1842 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1843 operands[1] = force_reg (QImode, operands[1]);
1846 (define_insn "*movstrictqi_1"
1847 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1848 (match_operand:QI 1 "general_operand" "*qn,m"))]
1849 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1850 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1851 "mov{b}\t{%1, %0|%0, %1}"
1852 [(set_attr "type" "imov")
1853 (set_attr "mode" "QI")])
1855 (define_insn "*movstrictqi_xor"
1856 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1857 (match_operand:QI 1 "const0_operand" "i"))
1858 (clobber (reg:CC FLAGS_REG))]
1859 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1861 [(set_attr "type" "alu1")
1862 (set_attr "mode" "QI")
1863 (set_attr "length_immediate" "0")])
1865 (define_insn "*movsi_extv_1"
1866 [(set (match_operand:SI 0 "register_operand" "=R")
1867 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1871 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1872 [(set_attr "type" "imovx")
1873 (set_attr "mode" "SI")])
1875 (define_insn "*movhi_extv_1"
1876 [(set (match_operand:HI 0 "register_operand" "=R")
1877 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1881 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1882 [(set_attr "type" "imovx")
1883 (set_attr "mode" "SI")])
1885 (define_insn "*movqi_extv_1"
1886 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1887 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1892 switch (get_attr_type (insn))
1895 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1897 return "mov{b}\t{%h1, %0|%0, %h1}";
1901 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1902 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1903 (ne (symbol_ref "TARGET_MOVX")
1905 (const_string "imovx")
1906 (const_string "imov")))
1908 (if_then_else (eq_attr "type" "imovx")
1910 (const_string "QI")))])
1912 (define_insn "*movqi_extv_1_rex64"
1913 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1914 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1919 switch (get_attr_type (insn))
1922 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1924 return "mov{b}\t{%h1, %0|%0, %h1}";
1928 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1929 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1930 (ne (symbol_ref "TARGET_MOVX")
1932 (const_string "imovx")
1933 (const_string "imov")))
1935 (if_then_else (eq_attr "type" "imovx")
1937 (const_string "QI")))])
1939 ;; Stores and loads of ax to arbitrary constant address.
1940 ;; We fake an second form of instruction to force reload to load address
1941 ;; into register when rax is not available
1942 (define_insn "*movabsqi_1_rex64"
1943 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1944 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1945 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1947 movabs{b}\t{%1, %P0|%P0, %1}
1948 mov{b}\t{%1, %a0|%a0, %1}"
1949 [(set_attr "type" "imov")
1950 (set_attr "modrm" "0,*")
1951 (set_attr "length_address" "8,0")
1952 (set_attr "length_immediate" "0,*")
1953 (set_attr "memory" "store")
1954 (set_attr "mode" "QI")])
1956 (define_insn "*movabsqi_2_rex64"
1957 [(set (match_operand:QI 0 "register_operand" "=a,r")
1958 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1959 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1961 movabs{b}\t{%P1, %0|%0, %P1}
1962 mov{b}\t{%a1, %0|%0, %a1}"
1963 [(set_attr "type" "imov")
1964 (set_attr "modrm" "0,*")
1965 (set_attr "length_address" "8,0")
1966 (set_attr "length_immediate" "0")
1967 (set_attr "memory" "load")
1968 (set_attr "mode" "QI")])
1970 (define_insn "*movdi_extzv_1"
1971 [(set (match_operand:DI 0 "register_operand" "=R")
1972 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1976 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1977 [(set_attr "type" "imovx")
1978 (set_attr "mode" "DI")])
1980 (define_insn "*movsi_extzv_1"
1981 [(set (match_operand:SI 0 "register_operand" "=R")
1982 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1986 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1987 [(set_attr "type" "imovx")
1988 (set_attr "mode" "SI")])
1990 (define_insn "*movqi_extzv_2"
1991 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1992 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1997 switch (get_attr_type (insn))
2000 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2002 return "mov{b}\t{%h1, %0|%0, %h1}";
2006 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2007 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2008 (ne (symbol_ref "TARGET_MOVX")
2010 (const_string "imovx")
2011 (const_string "imov")))
2013 (if_then_else (eq_attr "type" "imovx")
2015 (const_string "QI")))])
2017 (define_insn "*movqi_extzv_2_rex64"
2018 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2019 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2024 switch (get_attr_type (insn))
2027 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2029 return "mov{b}\t{%h1, %0|%0, %h1}";
2033 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2034 (ne (symbol_ref "TARGET_MOVX")
2036 (const_string "imovx")
2037 (const_string "imov")))
2039 (if_then_else (eq_attr "type" "imovx")
2041 (const_string "QI")))])
2043 (define_insn "movsi_insv_1"
2044 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2047 (match_operand:SI 1 "general_operand" "Qmn"))]
2049 "mov{b}\t{%b1, %h0|%h0, %b1}"
2050 [(set_attr "type" "imov")
2051 (set_attr "mode" "QI")])
2053 (define_insn "*movsi_insv_1_rex64"
2054 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2057 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2059 "mov{b}\t{%b1, %h0|%h0, %b1}"
2060 [(set_attr "type" "imov")
2061 (set_attr "mode" "QI")])
2063 (define_insn "movdi_insv_1_rex64"
2064 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2067 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2069 "mov{b}\t{%b1, %h0|%h0, %b1}"
2070 [(set_attr "type" "imov")
2071 (set_attr "mode" "QI")])
2073 (define_insn "*movqi_insv_2"
2074 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2077 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2080 "mov{b}\t{%h1, %h0|%h0, %h1}"
2081 [(set_attr "type" "imov")
2082 (set_attr "mode" "QI")])
2084 (define_expand "movdi"
2085 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2086 (match_operand:DI 1 "general_operand" ""))]
2088 "ix86_expand_move (DImode, operands); DONE;")
2090 (define_insn "*pushdi"
2091 [(set (match_operand:DI 0 "push_operand" "=<")
2092 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2096 (define_insn "*pushdi2_rex64"
2097 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2098 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2103 [(set_attr "type" "push,multi")
2104 (set_attr "mode" "DI")])
2106 ;; Convert impossible pushes of immediate to existing instructions.
2107 ;; First try to get scratch register and go through it. In case this
2108 ;; fails, push sign extended lower part first and then overwrite
2109 ;; upper part by 32bit move.
2111 [(match_scratch:DI 2 "r")
2112 (set (match_operand:DI 0 "push_operand" "")
2113 (match_operand:DI 1 "immediate_operand" ""))]
2114 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2115 && !x86_64_immediate_operand (operands[1], DImode)"
2116 [(set (match_dup 2) (match_dup 1))
2117 (set (match_dup 0) (match_dup 2))]
2120 ;; We need to define this as both peepholer and splitter for case
2121 ;; peephole2 pass is not run.
2122 ;; "&& 1" is needed to keep it from matching the previous pattern.
2124 [(set (match_operand:DI 0 "push_operand" "")
2125 (match_operand:DI 1 "immediate_operand" ""))]
2126 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2127 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2128 [(set (match_dup 0) (match_dup 1))
2129 (set (match_dup 2) (match_dup 3))]
2130 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2131 operands[1] = gen_lowpart (DImode, operands[2]);
2132 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2137 [(set (match_operand:DI 0 "push_operand" "")
2138 (match_operand:DI 1 "immediate_operand" ""))]
2139 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2140 ? epilogue_completed : reload_completed)
2141 && !symbolic_operand (operands[1], DImode)
2142 && !x86_64_immediate_operand (operands[1], DImode)"
2143 [(set (match_dup 0) (match_dup 1))
2144 (set (match_dup 2) (match_dup 3))]
2145 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2146 operands[1] = gen_lowpart (DImode, operands[2]);
2147 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2151 (define_insn "*pushdi2_prologue_rex64"
2152 [(set (match_operand:DI 0 "push_operand" "=<")
2153 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2154 (clobber (mem:BLK (scratch)))]
2157 [(set_attr "type" "push")
2158 (set_attr "mode" "DI")])
2160 (define_insn "*popdi1_epilogue_rex64"
2161 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2162 (mem:DI (reg:DI SP_REG)))
2163 (set (reg:DI SP_REG)
2164 (plus:DI (reg:DI SP_REG) (const_int 8)))
2165 (clobber (mem:BLK (scratch)))]
2168 [(set_attr "type" "pop")
2169 (set_attr "mode" "DI")])
2171 (define_insn "popdi1"
2172 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2173 (mem:DI (reg:DI SP_REG)))
2174 (set (reg:DI SP_REG)
2175 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2178 [(set_attr "type" "pop")
2179 (set_attr "mode" "DI")])
2181 (define_insn "*movdi_xor_rex64"
2182 [(set (match_operand:DI 0 "register_operand" "=r")
2183 (match_operand:DI 1 "const0_operand" "i"))
2184 (clobber (reg:CC FLAGS_REG))]
2185 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2186 && reload_completed"
2188 [(set_attr "type" "alu1")
2189 (set_attr "mode" "SI")
2190 (set_attr "length_immediate" "0")])
2192 (define_insn "*movdi_or_rex64"
2193 [(set (match_operand:DI 0 "register_operand" "=r")
2194 (match_operand:DI 1 "const_int_operand" "i"))
2195 (clobber (reg:CC FLAGS_REG))]
2196 "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2198 && operands[1] == constm1_rtx"
2200 operands[1] = constm1_rtx;
2201 return "or{q}\t{%1, %0|%0, %1}";
2203 [(set_attr "type" "alu1")
2204 (set_attr "mode" "DI")
2205 (set_attr "length_immediate" "1")])
2207 (define_insn "*movdi_2"
2208 [(set (match_operand:DI 0 "nonimmediate_operand"
2209 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2210 (match_operand:DI 1 "general_operand"
2211 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2212 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2217 movq\t{%1, %0|%0, %1}
2218 movq\t{%1, %0|%0, %1}
2220 movq\t{%1, %0|%0, %1}
2221 movdqa\t{%1, %0|%0, %1}
2222 movq\t{%1, %0|%0, %1}
2224 movlps\t{%1, %0|%0, %1}
2225 movaps\t{%1, %0|%0, %1}
2226 movlps\t{%1, %0|%0, %1}"
2227 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2228 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2231 [(set (match_operand:DI 0 "push_operand" "")
2232 (match_operand:DI 1 "general_operand" ""))]
2233 "!TARGET_64BIT && reload_completed
2234 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2236 "ix86_split_long_move (operands); DONE;")
2238 ;; %%% This multiword shite has got to go.
2240 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2241 (match_operand:DI 1 "general_operand" ""))]
2242 "!TARGET_64BIT && reload_completed
2243 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2244 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2246 "ix86_split_long_move (operands); DONE;")
2248 (define_insn "*movdi_1_rex64"
2249 [(set (match_operand:DI 0 "nonimmediate_operand"
2250 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2251 (match_operand:DI 1 "general_operand"
2252 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2253 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2255 switch (get_attr_type (insn))
2258 if (SSE_REG_P (operands[0]))
2259 return "movq2dq\t{%1, %0|%0, %1}";
2261 return "movdq2q\t{%1, %0|%0, %1}";
2264 if (get_attr_mode (insn) == MODE_TI)
2265 return "movdqa\t{%1, %0|%0, %1}";
2269 /* Moves from and into integer register is done using movd
2270 opcode with REX prefix. */
2271 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2272 return "movd\t{%1, %0|%0, %1}";
2273 return "movq\t{%1, %0|%0, %1}";
2277 return "pxor\t%0, %0";
2283 return "lea{q}\t{%a1, %0|%0, %a1}";
2286 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2287 if (get_attr_mode (insn) == MODE_SI)
2288 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2289 else if (which_alternative == 2)
2290 return "movabs{q}\t{%1, %0|%0, %1}";
2292 return "mov{q}\t{%1, %0|%0, %1}";
2296 (cond [(eq_attr "alternative" "5")
2297 (const_string "mmxadd")
2298 (eq_attr "alternative" "6,7,8,9,10")
2299 (const_string "mmxmov")
2300 (eq_attr "alternative" "11")
2301 (const_string "sselog1")
2302 (eq_attr "alternative" "12,13,14,15,16")
2303 (const_string "ssemov")
2304 (eq_attr "alternative" "17,18")
2305 (const_string "ssecvt")
2306 (eq_attr "alternative" "4")
2307 (const_string "multi")
2308 (match_operand:DI 1 "pic_32bit_operand" "")
2309 (const_string "lea")
2311 (const_string "imov")))
2312 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2313 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2314 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2316 ;; Stores and loads of ax to arbitrary constant address.
2317 ;; We fake an second form of instruction to force reload to load address
2318 ;; into register when rax is not available
2319 (define_insn "*movabsdi_1_rex64"
2320 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2321 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2322 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2324 movabs{q}\t{%1, %P0|%P0, %1}
2325 mov{q}\t{%1, %a0|%a0, %1}"
2326 [(set_attr "type" "imov")
2327 (set_attr "modrm" "0,*")
2328 (set_attr "length_address" "8,0")
2329 (set_attr "length_immediate" "0,*")
2330 (set_attr "memory" "store")
2331 (set_attr "mode" "DI")])
2333 (define_insn "*movabsdi_2_rex64"
2334 [(set (match_operand:DI 0 "register_operand" "=a,r")
2335 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2336 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2338 movabs{q}\t{%P1, %0|%0, %P1}
2339 mov{q}\t{%a1, %0|%0, %a1}"
2340 [(set_attr "type" "imov")
2341 (set_attr "modrm" "0,*")
2342 (set_attr "length_address" "8,0")
2343 (set_attr "length_immediate" "0")
2344 (set_attr "memory" "load")
2345 (set_attr "mode" "DI")])
2347 ;; Convert impossible stores of immediate to existing instructions.
2348 ;; First try to get scratch register and go through it. In case this
2349 ;; fails, move by 32bit parts.
2351 [(match_scratch:DI 2 "r")
2352 (set (match_operand:DI 0 "memory_operand" "")
2353 (match_operand:DI 1 "immediate_operand" ""))]
2354 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2355 && !x86_64_immediate_operand (operands[1], DImode)"
2356 [(set (match_dup 2) (match_dup 1))
2357 (set (match_dup 0) (match_dup 2))]
2360 ;; We need to define this as both peepholer and splitter for case
2361 ;; peephole2 pass is not run.
2362 ;; "&& 1" is needed to keep it from matching the previous pattern.
2364 [(set (match_operand:DI 0 "memory_operand" "")
2365 (match_operand:DI 1 "immediate_operand" ""))]
2366 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2367 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2368 [(set (match_dup 2) (match_dup 3))
2369 (set (match_dup 4) (match_dup 5))]
2370 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2373 [(set (match_operand:DI 0 "memory_operand" "")
2374 (match_operand:DI 1 "immediate_operand" ""))]
2375 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2376 ? epilogue_completed : reload_completed)
2377 && !symbolic_operand (operands[1], DImode)
2378 && !x86_64_immediate_operand (operands[1], DImode)"
2379 [(set (match_dup 2) (match_dup 3))
2380 (set (match_dup 4) (match_dup 5))]
2381 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2383 (define_insn "*swapdi_rex64"
2384 [(set (match_operand:DI 0 "register_operand" "+r")
2385 (match_operand:DI 1 "register_operand" "+r"))
2390 [(set_attr "type" "imov")
2391 (set_attr "mode" "DI")
2392 (set_attr "pent_pair" "np")
2393 (set_attr "athlon_decode" "vector")
2394 (set_attr "amdfam10_decode" "double")])
2396 (define_expand "movti"
2397 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2398 (match_operand:TI 1 "nonimmediate_operand" ""))]
2399 "TARGET_SSE || TARGET_64BIT"
2402 ix86_expand_move (TImode, operands);
2403 else if (push_operand (operands[0], TImode))
2404 ix86_expand_push (TImode, operands[1]);
2406 ix86_expand_vector_move (TImode, operands);
2410 (define_insn "*movti_internal"
2411 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2412 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2413 "TARGET_SSE && !TARGET_64BIT
2414 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2416 switch (which_alternative)
2419 if (get_attr_mode (insn) == MODE_V4SF)
2420 return "xorps\t%0, %0";
2422 return "pxor\t%0, %0";
2425 /* TDmode values are passed as TImode on the stack. Moving them
2426 to stack may result in unaligned memory access. */
2427 if (misaligned_operand (operands[0], TImode)
2428 || misaligned_operand (operands[1], TImode))
2430 if (get_attr_mode (insn) == MODE_V4SF)
2431 return "movups\t{%1, %0|%0, %1}";
2433 return "movdqu\t{%1, %0|%0, %1}";
2437 if (get_attr_mode (insn) == MODE_V4SF)
2438 return "movaps\t{%1, %0|%0, %1}";
2440 return "movdqa\t{%1, %0|%0, %1}";
2446 [(set_attr "type" "sselog1,ssemov,ssemov")
2448 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2449 (ne (symbol_ref "optimize_size") (const_int 0)))
2450 (const_string "V4SF")
2451 (and (eq_attr "alternative" "2")
2452 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2454 (const_string "V4SF")]
2455 (const_string "TI")))])
2457 (define_insn "*movti_rex64"
2458 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2459 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2461 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2463 switch (which_alternative)
2469 if (get_attr_mode (insn) == MODE_V4SF)
2470 return "xorps\t%0, %0";
2472 return "pxor\t%0, %0";
2475 /* TDmode values are passed as TImode on the stack. Moving them
2476 to stack may result in unaligned memory access. */
2477 if (misaligned_operand (operands[0], TImode)
2478 || misaligned_operand (operands[1], TImode))
2480 if (get_attr_mode (insn) == MODE_V4SF)
2481 return "movups\t{%1, %0|%0, %1}";
2483 return "movdqu\t{%1, %0|%0, %1}";
2487 if (get_attr_mode (insn) == MODE_V4SF)
2488 return "movaps\t{%1, %0|%0, %1}";
2490 return "movdqa\t{%1, %0|%0, %1}";
2496 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2498 (cond [(eq_attr "alternative" "2,3")
2500 (ne (symbol_ref "optimize_size")
2502 (const_string "V4SF")
2503 (const_string "TI"))
2504 (eq_attr "alternative" "4")
2506 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2508 (ne (symbol_ref "optimize_size")
2510 (const_string "V4SF")
2511 (const_string "TI"))]
2512 (const_string "DI")))])
2515 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2516 (match_operand:TI 1 "general_operand" ""))]
2517 "reload_completed && !SSE_REG_P (operands[0])
2518 && !SSE_REG_P (operands[1])"
2520 "ix86_split_long_move (operands); DONE;")
2522 ;; This expands to what emit_move_complex would generate if we didn't
2523 ;; have a movti pattern. Having this avoids problems with reload on
2524 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2525 ;; to have around all the time.
2526 (define_expand "movcdi"
2527 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2528 (match_operand:CDI 1 "general_operand" ""))]
2531 if (push_operand (operands[0], CDImode))
2532 emit_move_complex_push (CDImode, operands[0], operands[1]);
2534 emit_move_complex_parts (operands[0], operands[1]);
2538 (define_expand "movsf"
2539 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2540 (match_operand:SF 1 "general_operand" ""))]
2542 "ix86_expand_move (SFmode, operands); DONE;")
2544 (define_insn "*pushsf"
2545 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2546 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2549 /* Anything else should be already split before reg-stack. */
2550 gcc_assert (which_alternative == 1);
2551 return "push{l}\t%1";
2553 [(set_attr "type" "multi,push,multi")
2554 (set_attr "unit" "i387,*,*")
2555 (set_attr "mode" "SF,SI,SF")])
2557 (define_insn "*pushsf_rex64"
2558 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2559 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2562 /* Anything else should be already split before reg-stack. */
2563 gcc_assert (which_alternative == 1);
2564 return "push{q}\t%q1";
2566 [(set_attr "type" "multi,push,multi")
2567 (set_attr "unit" "i387,*,*")
2568 (set_attr "mode" "SF,DI,SF")])
2571 [(set (match_operand:SF 0 "push_operand" "")
2572 (match_operand:SF 1 "memory_operand" ""))]
2574 && MEM_P (operands[1])
2575 && (operands[2] = find_constant_src (insn))"
2580 ;; %%% Kill this when call knows how to work this out.
2582 [(set (match_operand:SF 0 "push_operand" "")
2583 (match_operand:SF 1 "any_fp_register_operand" ""))]
2585 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2586 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2589 [(set (match_operand:SF 0 "push_operand" "")
2590 (match_operand:SF 1 "any_fp_register_operand" ""))]
2592 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2593 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2595 (define_insn "*movsf_1"
2596 [(set (match_operand:SF 0 "nonimmediate_operand"
2597 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2598 (match_operand:SF 1 "general_operand"
2599 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2600 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2601 && (reload_in_progress || reload_completed
2602 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2603 || (!TARGET_SSE_MATH && optimize_size
2604 && standard_80387_constant_p (operands[1]))
2605 || GET_CODE (operands[1]) != CONST_DOUBLE
2606 || memory_operand (operands[0], SFmode))"
2608 switch (which_alternative)
2612 return output_387_reg_move (insn, operands);
2615 return standard_80387_constant_opcode (operands[1]);
2619 return "mov{l}\t{%1, %0|%0, %1}";
2621 if (get_attr_mode (insn) == MODE_TI)
2622 return "pxor\t%0, %0";
2624 return "xorps\t%0, %0";
2626 if (get_attr_mode (insn) == MODE_V4SF)
2627 return "movaps\t{%1, %0|%0, %1}";
2629 return "movss\t{%1, %0|%0, %1}";
2631 return "movss\t{%1, %0|%0, %1}";
2634 case 12: case 13: case 14: case 15:
2635 return "movd\t{%1, %0|%0, %1}";
2638 return "movq\t{%1, %0|%0, %1}";
2644 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2646 (cond [(eq_attr "alternative" "3,4,9,10")
2648 (eq_attr "alternative" "5")
2650 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2652 (ne (symbol_ref "TARGET_SSE2")
2654 (eq (symbol_ref "optimize_size")
2657 (const_string "V4SF"))
2658 /* For architectures resolving dependencies on
2659 whole SSE registers use APS move to break dependency
2660 chains, otherwise use short move to avoid extra work.
2662 Do the same for architectures resolving dependencies on
2663 the parts. While in DF mode it is better to always handle
2664 just register parts, the SF mode is different due to lack
2665 of instructions to load just part of the register. It is
2666 better to maintain the whole registers in single format
2667 to avoid problems on using packed logical operations. */
2668 (eq_attr "alternative" "6")
2670 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2672 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2674 (const_string "V4SF")
2675 (const_string "SF"))
2676 (eq_attr "alternative" "11")
2677 (const_string "DI")]
2678 (const_string "SF")))])
2680 (define_insn "*swapsf"
2681 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2682 (match_operand:SF 1 "fp_register_operand" "+f"))
2685 "reload_completed || TARGET_80387"
2687 if (STACK_TOP_P (operands[0]))
2692 [(set_attr "type" "fxch")
2693 (set_attr "mode" "SF")])
2695 (define_expand "movdf"
2696 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2697 (match_operand:DF 1 "general_operand" ""))]
2699 "ix86_expand_move (DFmode, operands); DONE;")
2701 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2702 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2703 ;; On the average, pushdf using integers can be still shorter. Allow this
2704 ;; pattern for optimize_size too.
2706 (define_insn "*pushdf_nointeger"
2707 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2708 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2709 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2711 /* This insn should be already split before reg-stack. */
2714 [(set_attr "type" "multi")
2715 (set_attr "unit" "i387,*,*,*")
2716 (set_attr "mode" "DF,SI,SI,DF")])
2718 (define_insn "*pushdf_integer"
2719 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2720 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2721 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2723 /* This insn should be already split before reg-stack. */
2726 [(set_attr "type" "multi")
2727 (set_attr "unit" "i387,*,*")
2728 (set_attr "mode" "DF,SI,DF")])
2730 ;; %%% Kill this when call knows how to work this out.
2732 [(set (match_operand:DF 0 "push_operand" "")
2733 (match_operand:DF 1 "any_fp_register_operand" ""))]
2734 "!TARGET_64BIT && reload_completed"
2735 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2736 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2740 [(set (match_operand:DF 0 "push_operand" "")
2741 (match_operand:DF 1 "any_fp_register_operand" ""))]
2742 "TARGET_64BIT && reload_completed"
2743 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2744 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2748 [(set (match_operand:DF 0 "push_operand" "")
2749 (match_operand:DF 1 "general_operand" ""))]
2752 "ix86_split_long_move (operands); DONE;")
2754 ;; Moving is usually shorter when only FP registers are used. This separate
2755 ;; movdf pattern avoids the use of integer registers for FP operations
2756 ;; when optimizing for size.
2758 (define_insn "*movdf_nointeger"
2759 [(set (match_operand:DF 0 "nonimmediate_operand"
2760 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2761 (match_operand:DF 1 "general_operand"
2762 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
2763 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2764 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2765 && (reload_in_progress || reload_completed
2766 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2767 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2768 && !memory_operand (operands[0], DFmode)
2769 && standard_80387_constant_p (operands[1]))
2770 || GET_CODE (operands[1]) != CONST_DOUBLE
2772 || !TARGET_MEMORY_MISMATCH_STALL
2773 || reload_in_progress || reload_completed)
2774 && memory_operand (operands[0], DFmode)))"
2776 switch (which_alternative)
2780 return output_387_reg_move (insn, operands);
2783 return standard_80387_constant_opcode (operands[1]);
2789 switch (get_attr_mode (insn))
2792 return "xorps\t%0, %0";
2794 return "xorpd\t%0, %0";
2796 return "pxor\t%0, %0";
2803 switch (get_attr_mode (insn))
2806 return "movaps\t{%1, %0|%0, %1}";
2808 return "movapd\t{%1, %0|%0, %1}";
2810 return "movdqa\t{%1, %0|%0, %1}";
2812 return "movq\t{%1, %0|%0, %1}";
2814 return "movsd\t{%1, %0|%0, %1}";
2816 return "movlpd\t{%1, %0|%0, %1}";
2818 return "movlps\t{%1, %0|%0, %1}";
2827 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2829 (cond [(eq_attr "alternative" "0,1,2")
2831 (eq_attr "alternative" "3,4")
2834 /* For SSE1, we have many fewer alternatives. */
2835 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2836 (cond [(eq_attr "alternative" "5,6")
2837 (const_string "V4SF")
2839 (const_string "V2SF"))
2841 /* xorps is one byte shorter. */
2842 (eq_attr "alternative" "5")
2843 (cond [(ne (symbol_ref "optimize_size")
2845 (const_string "V4SF")
2846 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2850 (const_string "V2DF"))
2852 /* For architectures resolving dependencies on
2853 whole SSE registers use APD move to break dependency
2854 chains, otherwise use short move to avoid extra work.
2856 movaps encodes one byte shorter. */
2857 (eq_attr "alternative" "6")
2859 [(ne (symbol_ref "optimize_size")
2861 (const_string "V4SF")
2862 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2864 (const_string "V2DF")
2866 (const_string "DF"))
2867 /* For architectures resolving dependencies on register
2868 parts we may avoid extra work to zero out upper part
2870 (eq_attr "alternative" "7")
2872 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2874 (const_string "V1DF")
2875 (const_string "DF"))
2877 (const_string "DF")))])
2879 (define_insn "*movdf_integer_rex64"
2880 [(set (match_operand:DF 0 "nonimmediate_operand"
2881 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2882 (match_operand:DF 1 "general_operand"
2883 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2884 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2885 && (reload_in_progress || reload_completed
2886 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2887 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2888 && standard_80387_constant_p (operands[1]))
2889 || GET_CODE (operands[1]) != CONST_DOUBLE
2890 || memory_operand (operands[0], DFmode))"
2892 switch (which_alternative)
2896 return output_387_reg_move (insn, operands);
2899 return standard_80387_constant_opcode (operands[1]);
2906 switch (get_attr_mode (insn))
2909 return "xorps\t%0, %0";
2911 return "xorpd\t%0, %0";
2913 return "pxor\t%0, %0";
2920 switch (get_attr_mode (insn))
2923 return "movaps\t{%1, %0|%0, %1}";
2925 return "movapd\t{%1, %0|%0, %1}";
2927 return "movdqa\t{%1, %0|%0, %1}";
2929 return "movq\t{%1, %0|%0, %1}";
2931 return "movsd\t{%1, %0|%0, %1}";
2933 return "movlpd\t{%1, %0|%0, %1}";
2935 return "movlps\t{%1, %0|%0, %1}";
2942 return "movd\t{%1, %0|%0, %1}";
2948 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2950 (cond [(eq_attr "alternative" "0,1,2")
2952 (eq_attr "alternative" "3,4,9,10")
2955 /* For SSE1, we have many fewer alternatives. */
2956 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2957 (cond [(eq_attr "alternative" "5,6")
2958 (const_string "V4SF")
2960 (const_string "V2SF"))
2962 /* xorps is one byte shorter. */
2963 (eq_attr "alternative" "5")
2964 (cond [(ne (symbol_ref "optimize_size")
2966 (const_string "V4SF")
2967 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2971 (const_string "V2DF"))
2973 /* For architectures resolving dependencies on
2974 whole SSE registers use APD move to break dependency
2975 chains, otherwise use short move to avoid extra work.
2977 movaps encodes one byte shorter. */
2978 (eq_attr "alternative" "6")
2980 [(ne (symbol_ref "optimize_size")
2982 (const_string "V4SF")
2983 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2985 (const_string "V2DF")
2987 (const_string "DF"))
2988 /* For architectures resolving dependencies on register
2989 parts we may avoid extra work to zero out upper part
2991 (eq_attr "alternative" "7")
2993 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2995 (const_string "V1DF")
2996 (const_string "DF"))
2998 (const_string "DF")))])
3000 (define_insn "*movdf_integer"
3001 [(set (match_operand:DF 0 "nonimmediate_operand"
3002 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3003 (match_operand:DF 1 "general_operand"
3004 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3005 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3006 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3007 && (reload_in_progress || reload_completed
3008 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3009 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3010 && standard_80387_constant_p (operands[1]))
3011 || GET_CODE (operands[1]) != CONST_DOUBLE
3012 || memory_operand (operands[0], DFmode))"
3014 switch (which_alternative)
3018 return output_387_reg_move (insn, operands);
3021 return standard_80387_constant_opcode (operands[1]);
3028 switch (get_attr_mode (insn))
3031 return "xorps\t%0, %0";
3033 return "xorpd\t%0, %0";
3035 return "pxor\t%0, %0";
3042 switch (get_attr_mode (insn))
3045 return "movaps\t{%1, %0|%0, %1}";
3047 return "movapd\t{%1, %0|%0, %1}";
3049 return "movdqa\t{%1, %0|%0, %1}";
3051 return "movq\t{%1, %0|%0, %1}";
3053 return "movsd\t{%1, %0|%0, %1}";
3055 return "movlpd\t{%1, %0|%0, %1}";
3057 return "movlps\t{%1, %0|%0, %1}";
3066 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3068 (cond [(eq_attr "alternative" "0,1,2")
3070 (eq_attr "alternative" "3,4")
3073 /* For SSE1, we have many fewer alternatives. */
3074 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3075 (cond [(eq_attr "alternative" "5,6")
3076 (const_string "V4SF")
3078 (const_string "V2SF"))
3080 /* xorps is one byte shorter. */
3081 (eq_attr "alternative" "5")
3082 (cond [(ne (symbol_ref "optimize_size")
3084 (const_string "V4SF")
3085 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3089 (const_string "V2DF"))
3091 /* For architectures resolving dependencies on
3092 whole SSE registers use APD move to break dependency
3093 chains, otherwise use short move to avoid extra work.
3095 movaps encodes one byte shorter. */
3096 (eq_attr "alternative" "6")
3098 [(ne (symbol_ref "optimize_size")
3100 (const_string "V4SF")
3101 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3103 (const_string "V2DF")
3105 (const_string "DF"))
3106 /* For architectures resolving dependencies on register
3107 parts we may avoid extra work to zero out upper part
3109 (eq_attr "alternative" "7")
3111 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3113 (const_string "V1DF")
3114 (const_string "DF"))
3116 (const_string "DF")))])
3119 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3120 (match_operand:DF 1 "general_operand" ""))]
3122 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3123 && ! (ANY_FP_REG_P (operands[0]) ||
3124 (GET_CODE (operands[0]) == SUBREG
3125 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3126 && ! (ANY_FP_REG_P (operands[1]) ||
3127 (GET_CODE (operands[1]) == SUBREG
3128 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3130 "ix86_split_long_move (operands); DONE;")
3132 (define_insn "*swapdf"
3133 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3134 (match_operand:DF 1 "fp_register_operand" "+f"))
3137 "reload_completed || TARGET_80387"
3139 if (STACK_TOP_P (operands[0]))
3144 [(set_attr "type" "fxch")
3145 (set_attr "mode" "DF")])
3147 (define_expand "movxf"
3148 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3149 (match_operand:XF 1 "general_operand" ""))]
3151 "ix86_expand_move (XFmode, operands); DONE;")
3153 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3154 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3155 ;; Pushing using integer instructions is longer except for constants
3156 ;; and direct memory references.
3157 ;; (assuming that any given constant is pushed only once, but this ought to be
3158 ;; handled elsewhere).
3160 (define_insn "*pushxf_nointeger"
3161 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3162 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3165 /* This insn should be already split before reg-stack. */
3168 [(set_attr "type" "multi")
3169 (set_attr "unit" "i387,*,*")
3170 (set_attr "mode" "XF,SI,SI")])
3172 (define_insn "*pushxf_integer"
3173 [(set (match_operand:XF 0 "push_operand" "=<,<")
3174 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3177 /* This insn should be already split before reg-stack. */
3180 [(set_attr "type" "multi")
3181 (set_attr "unit" "i387,*")
3182 (set_attr "mode" "XF,SI")])
3185 [(set (match_operand 0 "push_operand" "")
3186 (match_operand 1 "general_operand" ""))]
3188 && (GET_MODE (operands[0]) == XFmode
3189 || GET_MODE (operands[0]) == DFmode)
3190 && !ANY_FP_REG_P (operands[1])"
3192 "ix86_split_long_move (operands); DONE;")
3195 [(set (match_operand:XF 0 "push_operand" "")
3196 (match_operand:XF 1 "any_fp_register_operand" ""))]
3198 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3199 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3200 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3203 [(set (match_operand:XF 0 "push_operand" "")
3204 (match_operand:XF 1 "any_fp_register_operand" ""))]
3206 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3207 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3208 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3210 ;; Do not use integer registers when optimizing for size
3211 (define_insn "*movxf_nointeger"
3212 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3213 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3215 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3216 && (reload_in_progress || reload_completed
3217 || (optimize_size && standard_80387_constant_p (operands[1]))
3218 || GET_CODE (operands[1]) != CONST_DOUBLE
3219 || memory_operand (operands[0], XFmode))"
3221 switch (which_alternative)
3225 return output_387_reg_move (insn, operands);
3228 return standard_80387_constant_opcode (operands[1]);
3236 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3237 (set_attr "mode" "XF,XF,XF,SI,SI")])
3239 (define_insn "*movxf_integer"
3240 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3241 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3243 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3244 && (reload_in_progress || reload_completed
3245 || (optimize_size && standard_80387_constant_p (operands[1]))
3246 || GET_CODE (operands[1]) != CONST_DOUBLE
3247 || memory_operand (operands[0], XFmode))"
3249 switch (which_alternative)
3253 return output_387_reg_move (insn, operands);
3256 return standard_80387_constant_opcode (operands[1]);
3265 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3266 (set_attr "mode" "XF,XF,XF,SI,SI")])
3268 (define_expand "movtf"
3269 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3270 (match_operand:TF 1 "nonimmediate_operand" ""))]
3273 ix86_expand_move (TFmode, operands);
3277 (define_insn "*movtf_internal"
3278 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3279 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3281 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3283 switch (which_alternative)
3287 if (get_attr_mode (insn) == MODE_V4SF)
3288 return "movaps\t{%1, %0|%0, %1}";
3290 return "movdqa\t{%1, %0|%0, %1}";
3292 if (get_attr_mode (insn) == MODE_V4SF)
3293 return "xorps\t%0, %0";
3295 return "pxor\t%0, %0";
3303 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3305 (cond [(eq_attr "alternative" "0,2")
3307 (ne (symbol_ref "optimize_size")
3309 (const_string "V4SF")
3310 (const_string "TI"))
3311 (eq_attr "alternative" "1")
3313 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3315 (ne (symbol_ref "optimize_size")
3317 (const_string "V4SF")
3318 (const_string "TI"))]
3319 (const_string "DI")))])
3322 [(set (match_operand 0 "nonimmediate_operand" "")
3323 (match_operand 1 "general_operand" ""))]
3325 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3326 && GET_MODE (operands[0]) == XFmode
3327 && ! (ANY_FP_REG_P (operands[0]) ||
3328 (GET_CODE (operands[0]) == SUBREG
3329 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3330 && ! (ANY_FP_REG_P (operands[1]) ||
3331 (GET_CODE (operands[1]) == SUBREG
3332 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3334 "ix86_split_long_move (operands); DONE;")
3337 [(set (match_operand 0 "register_operand" "")
3338 (match_operand 1 "memory_operand" ""))]
3340 && MEM_P (operands[1])
3341 && (GET_MODE (operands[0]) == TFmode
3342 || GET_MODE (operands[0]) == XFmode
3343 || GET_MODE (operands[0]) == SFmode
3344 || GET_MODE (operands[0]) == DFmode)
3345 && (operands[2] = find_constant_src (insn))"
3346 [(set (match_dup 0) (match_dup 2))]
3348 rtx c = operands[2];
3349 rtx r = operands[0];
3351 if (GET_CODE (r) == SUBREG)
3356 if (!standard_sse_constant_p (c))
3359 else if (FP_REG_P (r))
3361 if (!standard_80387_constant_p (c))
3364 else if (MMX_REG_P (r))
3369 [(set (match_operand 0 "register_operand" "")
3370 (float_extend (match_operand 1 "memory_operand" "")))]
3372 && MEM_P (operands[1])
3373 && (GET_MODE (operands[0]) == TFmode
3374 || GET_MODE (operands[0]) == XFmode
3375 || GET_MODE (operands[0]) == SFmode
3376 || GET_MODE (operands[0]) == DFmode)
3377 && (operands[2] = find_constant_src (insn))"
3378 [(set (match_dup 0) (match_dup 2))]
3380 rtx c = operands[2];
3381 rtx r = operands[0];
3383 if (GET_CODE (r) == SUBREG)
3388 if (!standard_sse_constant_p (c))
3391 else if (FP_REG_P (r))
3393 if (!standard_80387_constant_p (c))
3396 else if (MMX_REG_P (r))
3400 (define_insn "swapxf"
3401 [(set (match_operand:XF 0 "register_operand" "+f")
3402 (match_operand:XF 1 "register_operand" "+f"))
3407 if (STACK_TOP_P (operands[0]))
3412 [(set_attr "type" "fxch")
3413 (set_attr "mode" "XF")])
3415 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3417 [(set (match_operand:X87MODEF 0 "register_operand" "")
3418 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3419 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3420 && (standard_80387_constant_p (operands[1]) == 8
3421 || standard_80387_constant_p (operands[1]) == 9)"
3422 [(set (match_dup 0)(match_dup 1))
3424 (neg:X87MODEF (match_dup 0)))]
3428 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3429 if (real_isnegzero (&r))
3430 operands[1] = CONST0_RTX (<MODE>mode);
3432 operands[1] = CONST1_RTX (<MODE>mode);
3436 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3437 (match_operand:TF 1 "general_operand" ""))]
3439 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3441 "ix86_split_long_move (operands); DONE;")
3443 ;; Zero extension instructions
3445 (define_expand "zero_extendhisi2"
3446 [(set (match_operand:SI 0 "register_operand" "")
3447 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3450 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3452 operands[1] = force_reg (HImode, operands[1]);
3453 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3458 (define_insn "zero_extendhisi2_and"
3459 [(set (match_operand:SI 0 "register_operand" "=r")
3460 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3461 (clobber (reg:CC FLAGS_REG))]
3462 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3464 [(set_attr "type" "alu1")
3465 (set_attr "mode" "SI")])
3468 [(set (match_operand:SI 0 "register_operand" "")
3469 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3470 (clobber (reg:CC FLAGS_REG))]
3471 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3472 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3473 (clobber (reg:CC FLAGS_REG))])]
3476 (define_insn "*zero_extendhisi2_movzwl"
3477 [(set (match_operand:SI 0 "register_operand" "=r")
3478 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3479 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3480 "movz{wl|x}\t{%1, %0|%0, %1}"
3481 [(set_attr "type" "imovx")
3482 (set_attr "mode" "SI")])
3484 (define_expand "zero_extendqihi2"
3486 [(set (match_operand:HI 0 "register_operand" "")
3487 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3488 (clobber (reg:CC FLAGS_REG))])]
3492 (define_insn "*zero_extendqihi2_and"
3493 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3494 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3495 (clobber (reg:CC FLAGS_REG))]
3496 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3498 [(set_attr "type" "alu1")
3499 (set_attr "mode" "HI")])
3501 (define_insn "*zero_extendqihi2_movzbw_and"
3502 [(set (match_operand:HI 0 "register_operand" "=r,r")
3503 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3504 (clobber (reg:CC FLAGS_REG))]
3505 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3507 [(set_attr "type" "imovx,alu1")
3508 (set_attr "mode" "HI")])
3510 ; zero extend to SImode here to avoid partial register stalls
3511 (define_insn "*zero_extendqihi2_movzbl"
3512 [(set (match_operand:HI 0 "register_operand" "=r")
3513 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3514 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3515 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3516 [(set_attr "type" "imovx")
3517 (set_attr "mode" "SI")])
3519 ;; For the movzbw case strip only the clobber
3521 [(set (match_operand:HI 0 "register_operand" "")
3522 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3523 (clobber (reg:CC FLAGS_REG))]
3525 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3526 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3527 [(set (match_operand:HI 0 "register_operand" "")
3528 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3530 ;; When source and destination does not overlap, clear destination
3531 ;; first and then do the movb
3533 [(set (match_operand:HI 0 "register_operand" "")
3534 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3535 (clobber (reg:CC FLAGS_REG))]
3537 && ANY_QI_REG_P (operands[0])
3538 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3539 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3540 [(set (match_dup 0) (const_int 0))
3541 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3542 "operands[2] = gen_lowpart (QImode, operands[0]);")
3544 ;; Rest is handled by single and.
3546 [(set (match_operand:HI 0 "register_operand" "")
3547 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3548 (clobber (reg:CC FLAGS_REG))]
3550 && true_regnum (operands[0]) == true_regnum (operands[1])"
3551 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3552 (clobber (reg:CC FLAGS_REG))])]
3555 (define_expand "zero_extendqisi2"
3557 [(set (match_operand:SI 0 "register_operand" "")
3558 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3559 (clobber (reg:CC FLAGS_REG))])]
3563 (define_insn "*zero_extendqisi2_and"
3564 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3565 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3566 (clobber (reg:CC FLAGS_REG))]
3567 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3569 [(set_attr "type" "alu1")
3570 (set_attr "mode" "SI")])
3572 (define_insn "*zero_extendqisi2_movzbw_and"
3573 [(set (match_operand:SI 0 "register_operand" "=r,r")
3574 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3575 (clobber (reg:CC FLAGS_REG))]
3576 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3578 [(set_attr "type" "imovx,alu1")
3579 (set_attr "mode" "SI")])
3581 (define_insn "*zero_extendqisi2_movzbw"
3582 [(set (match_operand:SI 0 "register_operand" "=r")
3583 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3584 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3585 "movz{bl|x}\t{%1, %0|%0, %1}"
3586 [(set_attr "type" "imovx")
3587 (set_attr "mode" "SI")])
3589 ;; For the movzbl case strip only the clobber
3591 [(set (match_operand:SI 0 "register_operand" "")
3592 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3593 (clobber (reg:CC FLAGS_REG))]
3595 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3596 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3598 (zero_extend:SI (match_dup 1)))])
3600 ;; When source and destination does not overlap, clear destination
3601 ;; first and then do the movb
3603 [(set (match_operand:SI 0 "register_operand" "")
3604 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3605 (clobber (reg:CC FLAGS_REG))]
3607 && ANY_QI_REG_P (operands[0])
3608 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3609 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3610 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3611 [(set (match_dup 0) (const_int 0))
3612 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3613 "operands[2] = gen_lowpart (QImode, operands[0]);")
3615 ;; Rest is handled by single and.
3617 [(set (match_operand:SI 0 "register_operand" "")
3618 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3619 (clobber (reg:CC FLAGS_REG))]
3621 && true_regnum (operands[0]) == true_regnum (operands[1])"
3622 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3623 (clobber (reg:CC FLAGS_REG))])]
3626 ;; %%% Kill me once multi-word ops are sane.
3627 (define_expand "zero_extendsidi2"
3628 [(set (match_operand:DI 0 "register_operand" "")
3629 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3634 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3639 (define_insn "zero_extendsidi2_32"
3640 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3642 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3643 (clobber (reg:CC FLAGS_REG))]
3649 movd\t{%1, %0|%0, %1}
3650 movd\t{%1, %0|%0, %1}
3651 movd\t{%1, %0|%0, %1}
3652 movd\t{%1, %0|%0, %1}"
3653 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3654 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3656 (define_insn "zero_extendsidi2_rex64"
3657 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3659 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3662 mov\t{%k1, %k0|%k0, %k1}
3664 movd\t{%1, %0|%0, %1}
3665 movd\t{%1, %0|%0, %1}
3666 movd\t{%1, %0|%0, %1}
3667 movd\t{%1, %0|%0, %1}"
3668 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3669 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3672 [(set (match_operand:DI 0 "memory_operand" "")
3673 (zero_extend:DI (match_dup 0)))]
3675 [(set (match_dup 4) (const_int 0))]
3676 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3679 [(set (match_operand:DI 0 "register_operand" "")
3680 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3681 (clobber (reg:CC FLAGS_REG))]
3682 "!TARGET_64BIT && reload_completed
3683 && true_regnum (operands[0]) == true_regnum (operands[1])"
3684 [(set (match_dup 4) (const_int 0))]
3685 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3688 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3689 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3690 (clobber (reg:CC FLAGS_REG))]
3691 "!TARGET_64BIT && reload_completed
3692 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3693 [(set (match_dup 3) (match_dup 1))
3694 (set (match_dup 4) (const_int 0))]
3695 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3697 (define_insn "zero_extendhidi2"
3698 [(set (match_operand:DI 0 "register_operand" "=r")
3699 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3701 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3702 [(set_attr "type" "imovx")
3703 (set_attr "mode" "DI")])
3705 (define_insn "zero_extendqidi2"
3706 [(set (match_operand:DI 0 "register_operand" "=r")
3707 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3709 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3710 [(set_attr "type" "imovx")
3711 (set_attr "mode" "DI")])
3713 ;; Sign extension instructions
3715 (define_expand "extendsidi2"
3716 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3717 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3718 (clobber (reg:CC FLAGS_REG))
3719 (clobber (match_scratch:SI 2 ""))])]
3724 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3729 (define_insn "*extendsidi2_1"
3730 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3731 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3732 (clobber (reg:CC FLAGS_REG))
3733 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3737 (define_insn "extendsidi2_rex64"
3738 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3739 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3743 movs{lq|x}\t{%1,%0|%0, %1}"
3744 [(set_attr "type" "imovx")
3745 (set_attr "mode" "DI")
3746 (set_attr "prefix_0f" "0")
3747 (set_attr "modrm" "0,1")])
3749 (define_insn "extendhidi2"
3750 [(set (match_operand:DI 0 "register_operand" "=r")
3751 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3753 "movs{wq|x}\t{%1,%0|%0, %1}"
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "DI")])
3757 (define_insn "extendqidi2"
3758 [(set (match_operand:DI 0 "register_operand" "=r")
3759 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3761 "movs{bq|x}\t{%1,%0|%0, %1}"
3762 [(set_attr "type" "imovx")
3763 (set_attr "mode" "DI")])
3765 ;; Extend to memory case when source register does die.
3767 [(set (match_operand:DI 0 "memory_operand" "")
3768 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3769 (clobber (reg:CC FLAGS_REG))
3770 (clobber (match_operand:SI 2 "register_operand" ""))]
3772 && dead_or_set_p (insn, operands[1])
3773 && !reg_mentioned_p (operands[1], operands[0]))"
3774 [(set (match_dup 3) (match_dup 1))
3775 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3776 (clobber (reg:CC FLAGS_REG))])
3777 (set (match_dup 4) (match_dup 1))]
3778 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3780 ;; Extend to memory case when source register does not die.
3782 [(set (match_operand:DI 0 "memory_operand" "")
3783 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3784 (clobber (reg:CC FLAGS_REG))
3785 (clobber (match_operand:SI 2 "register_operand" ""))]
3789 split_di (&operands[0], 1, &operands[3], &operands[4]);
3791 emit_move_insn (operands[3], operands[1]);
3793 /* Generate a cltd if possible and doing so it profitable. */
3794 if ((optimize_size || TARGET_USE_CLTD)
3795 && true_regnum (operands[1]) == AX_REG
3796 && true_regnum (operands[2]) == DX_REG)
3798 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3802 emit_move_insn (operands[2], operands[1]);
3803 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3805 emit_move_insn (operands[4], operands[2]);
3809 ;; Extend to register case. Optimize case where source and destination
3810 ;; registers match and cases where we can use cltd.
3812 [(set (match_operand:DI 0 "register_operand" "")
3813 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3814 (clobber (reg:CC FLAGS_REG))
3815 (clobber (match_scratch:SI 2 ""))]
3819 split_di (&operands[0], 1, &operands[3], &operands[4]);
3821 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3822 emit_move_insn (operands[3], operands[1]);
3824 /* Generate a cltd if possible and doing so it profitable. */
3825 if ((optimize_size || TARGET_USE_CLTD)
3826 && true_regnum (operands[3]) == AX_REG)
3828 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3832 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3833 emit_move_insn (operands[4], operands[1]);
3835 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3839 (define_insn "extendhisi2"
3840 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3841 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3844 switch (get_attr_prefix_0f (insn))
3847 return "{cwtl|cwde}";
3849 return "movs{wl|x}\t{%1,%0|%0, %1}";
3852 [(set_attr "type" "imovx")
3853 (set_attr "mode" "SI")
3854 (set (attr "prefix_0f")
3855 ;; movsx is short decodable while cwtl is vector decoded.
3856 (if_then_else (and (eq_attr "cpu" "!k6")
3857 (eq_attr "alternative" "0"))
3859 (const_string "1")))
3861 (if_then_else (eq_attr "prefix_0f" "0")
3863 (const_string "1")))])
3865 (define_insn "*extendhisi2_zext"
3866 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3868 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3871 switch (get_attr_prefix_0f (insn))
3874 return "{cwtl|cwde}";
3876 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3879 [(set_attr "type" "imovx")
3880 (set_attr "mode" "SI")
3881 (set (attr "prefix_0f")
3882 ;; movsx is short decodable while cwtl is vector decoded.
3883 (if_then_else (and (eq_attr "cpu" "!k6")
3884 (eq_attr "alternative" "0"))
3886 (const_string "1")))
3888 (if_then_else (eq_attr "prefix_0f" "0")
3890 (const_string "1")))])
3892 (define_insn "extendqihi2"
3893 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3894 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3897 switch (get_attr_prefix_0f (insn))
3900 return "{cbtw|cbw}";
3902 return "movs{bw|x}\t{%1,%0|%0, %1}";
3905 [(set_attr "type" "imovx")
3906 (set_attr "mode" "HI")
3907 (set (attr "prefix_0f")
3908 ;; movsx is short decodable while cwtl is vector decoded.
3909 (if_then_else (and (eq_attr "cpu" "!k6")
3910 (eq_attr "alternative" "0"))
3912 (const_string "1")))
3914 (if_then_else (eq_attr "prefix_0f" "0")
3916 (const_string "1")))])
3918 (define_insn "extendqisi2"
3919 [(set (match_operand:SI 0 "register_operand" "=r")
3920 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3922 "movs{bl|x}\t{%1,%0|%0, %1}"
3923 [(set_attr "type" "imovx")
3924 (set_attr "mode" "SI")])
3926 (define_insn "*extendqisi2_zext"
3927 [(set (match_operand:DI 0 "register_operand" "=r")
3929 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3931 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "SI")])
3935 ;; Conversions between float and double.
3937 ;; These are all no-ops in the model used for the 80387. So just
3940 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3941 (define_insn "*dummy_extendsfdf2"
3942 [(set (match_operand:DF 0 "push_operand" "=<")
3943 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3948 [(set (match_operand:DF 0 "push_operand" "")
3949 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3951 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3952 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3955 [(set (match_operand:DF 0 "push_operand" "")
3956 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3958 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3959 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3961 (define_insn "*dummy_extendsfxf2"
3962 [(set (match_operand:XF 0 "push_operand" "=<")
3963 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3968 [(set (match_operand:XF 0 "push_operand" "")
3969 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3971 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3972 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3973 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3976 [(set (match_operand:XF 0 "push_operand" "")
3977 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3979 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3980 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3981 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3984 [(set (match_operand:XF 0 "push_operand" "")
3985 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3987 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3988 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3989 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3992 [(set (match_operand:XF 0 "push_operand" "")
3993 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3995 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3996 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3997 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3999 (define_expand "extendsfdf2"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4001 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4002 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4004 /* ??? Needed for compress_float_constant since all fp constants
4005 are LEGITIMATE_CONSTANT_P. */
4006 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4008 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4009 && standard_80387_constant_p (operands[1]) > 0)
4011 operands[1] = simplify_const_unary_operation
4012 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4013 emit_move_insn_1 (operands[0], operands[1]);
4016 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4020 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4022 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4024 We do the conversion post reload to avoid producing of 128bit spills
4025 that might lead to ICE on 32bit target. The sequence unlikely combine
4028 [(set (match_operand:DF 0 "register_operand" "")
4030 (match_operand:SF 1 "nonimmediate_operand" "")))]
4031 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4032 && reload_completed && SSE_REG_P (operands[0])"
4037 (parallel [(const_int 0) (const_int 1)]))))]
4039 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4040 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4041 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4042 Try to avoid move when unpacking can be done in source. */
4043 if (REG_P (operands[1]))
4045 /* If it is unsafe to overwrite upper half of source, we need
4046 to move to destination and unpack there. */
4047 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4048 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4049 && true_regnum (operands[0]) != true_regnum (operands[1]))
4051 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4052 emit_move_insn (tmp, operands[1]);
4055 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4056 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4059 emit_insn (gen_vec_setv4sf_0 (operands[3],
4060 CONST0_RTX (V4SFmode), operands[1]));
4063 (define_insn "*extendsfdf2_mixed"
4064 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4066 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4067 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4069 switch (which_alternative)
4073 return output_387_reg_move (insn, operands);
4076 return "cvtss2sd\t{%1, %0|%0, %1}";
4082 [(set_attr "type" "fmov,fmov,ssecvt")
4083 (set_attr "mode" "SF,XF,DF")])
4085 (define_insn "*extendsfdf2_sse"
4086 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4087 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4088 "TARGET_SSE2 && TARGET_SSE_MATH"
4089 "cvtss2sd\t{%1, %0|%0, %1}"
4090 [(set_attr "type" "ssecvt")
4091 (set_attr "mode" "DF")])
4093 (define_insn "*extendsfdf2_i387"
4094 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4095 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4097 "* return output_387_reg_move (insn, operands);"
4098 [(set_attr "type" "fmov")
4099 (set_attr "mode" "SF,XF")])
4101 (define_expand "extend<mode>xf2"
4102 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4103 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4106 /* ??? Needed for compress_float_constant since all fp constants
4107 are LEGITIMATE_CONSTANT_P. */
4108 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4110 if (standard_80387_constant_p (operands[1]) > 0)
4112 operands[1] = simplify_const_unary_operation
4113 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4114 emit_move_insn_1 (operands[0], operands[1]);
4117 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4121 (define_insn "*extend<mode>xf2_i387"
4122 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4124 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4126 "* return output_387_reg_move (insn, operands);"
4127 [(set_attr "type" "fmov")
4128 (set_attr "mode" "<MODE>,XF")])
4130 ;; %%% This seems bad bad news.
4131 ;; This cannot output into an f-reg because there is no way to be sure
4132 ;; of truncating in that case. Otherwise this is just like a simple move
4133 ;; insn. So we pretend we can output to a reg in order to get better
4134 ;; register preferencing, but we really use a stack slot.
4136 ;; Conversion from DFmode to SFmode.
4138 (define_expand "truncdfsf2"
4139 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4141 (match_operand:DF 1 "nonimmediate_operand" "")))]
4142 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4144 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4146 else if (flag_unsafe_math_optimizations)
4150 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4151 rtx temp = assign_386_stack_local (SFmode, slot);
4152 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4157 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4159 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4161 We do the conversion post reload to avoid producing of 128bit spills
4162 that might lead to ICE on 32bit target. The sequence unlikely combine
4165 [(set (match_operand:SF 0 "register_operand" "")
4167 (match_operand:DF 1 "nonimmediate_operand" "")))]
4168 "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4169 && reload_completed && SSE_REG_P (operands[0])"
4172 (float_truncate:V2SF
4176 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4177 operands[3] = CONST0_RTX (V2SFmode);
4178 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4179 /* Use movsd for loading from memory, unpcklpd for registers.
4180 Try to avoid move when unpacking can be done in source, or SSE3
4181 movddup is available. */
4182 if (REG_P (operands[1]))
4185 && true_regnum (operands[0]) != true_regnum (operands[1])
4186 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4187 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4189 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4190 emit_move_insn (tmp, operands[1]);
4193 else if (!TARGET_SSE3)
4194 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4195 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4198 emit_insn (gen_sse2_loadlpd (operands[4],
4199 CONST0_RTX (V2DFmode), operands[1]));
4202 (define_expand "truncdfsf2_with_temp"
4203 [(parallel [(set (match_operand:SF 0 "" "")
4204 (float_truncate:SF (match_operand:DF 1 "" "")))
4205 (clobber (match_operand:SF 2 "" ""))])]
4208 (define_insn "*truncdfsf_fast_mixed"
4209 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4211 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4212 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4214 switch (which_alternative)
4217 return output_387_reg_move (insn, operands);
4219 return "cvtsd2ss\t{%1, %0|%0, %1}";
4224 [(set_attr "type" "fmov,ssecvt")
4225 (set_attr "mode" "SF")])
4227 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4228 ;; because nothing we do here is unsafe.
4229 (define_insn "*truncdfsf_fast_sse"
4230 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4232 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4233 "TARGET_SSE2 && TARGET_SSE_MATH"
4234 "cvtsd2ss\t{%1, %0|%0, %1}"
4235 [(set_attr "type" "ssecvt")
4236 (set_attr "mode" "SF")])
4238 (define_insn "*truncdfsf_fast_i387"
4239 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4241 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4242 "TARGET_80387 && flag_unsafe_math_optimizations"
4243 "* return output_387_reg_move (insn, operands);"
4244 [(set_attr "type" "fmov")
4245 (set_attr "mode" "SF")])
4247 (define_insn "*truncdfsf_mixed"
4248 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4250 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4251 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4252 "TARGET_MIX_SSE_I387"
4254 switch (which_alternative)
4257 return output_387_reg_move (insn, operands);
4262 return "cvtsd2ss\t{%1, %0|%0, %1}";
4267 [(set_attr "type" "fmov,multi,ssecvt")
4268 (set_attr "unit" "*,i387,*")
4269 (set_attr "mode" "SF")])
4271 (define_insn "*truncdfsf_i387"
4272 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4274 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4275 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4278 switch (which_alternative)
4281 return output_387_reg_move (insn, operands);
4289 [(set_attr "type" "fmov,multi")
4290 (set_attr "unit" "*,i387")
4291 (set_attr "mode" "SF")])
4293 (define_insn "*truncdfsf2_i387_1"
4294 [(set (match_operand:SF 0 "memory_operand" "=m")
4296 (match_operand:DF 1 "register_operand" "f")))]
4298 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4299 && !TARGET_MIX_SSE_I387"
4300 "* return output_387_reg_move (insn, operands);"
4301 [(set_attr "type" "fmov")
4302 (set_attr "mode" "SF")])
4305 [(set (match_operand:SF 0 "register_operand" "")
4307 (match_operand:DF 1 "fp_register_operand" "")))
4308 (clobber (match_operand 2 "" ""))]
4310 [(set (match_dup 2) (match_dup 1))
4311 (set (match_dup 0) (match_dup 2))]
4313 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4316 ;; Conversion from XFmode to {SF,DF}mode
4318 (define_expand "truncxf<mode>2"
4319 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4320 (float_truncate:MODEF
4321 (match_operand:XF 1 "register_operand" "")))
4322 (clobber (match_dup 2))])]
4325 if (flag_unsafe_math_optimizations)
4327 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4328 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4329 if (reg != operands[0])
4330 emit_move_insn (operands[0], reg);
4335 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4336 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4340 (define_insn "*truncxfsf2_mixed"
4341 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4343 (match_operand:XF 1 "register_operand" "f,f")))
4344 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4347 gcc_assert (!which_alternative);
4348 return output_387_reg_move (insn, operands);
4350 [(set_attr "type" "fmov,multi")
4351 (set_attr "unit" "*,i387")
4352 (set_attr "mode" "SF")])
4354 (define_insn "*truncxfdf2_mixed"
4355 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4357 (match_operand:XF 1 "register_operand" "f,f")))
4358 (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4361 gcc_assert (!which_alternative);
4362 return output_387_reg_move (insn, operands);
4364 [(set_attr "type" "fmov,multi")
4365 (set_attr "unit" "*,i387")
4366 (set_attr "mode" "DF")])
4368 (define_insn "truncxf<mode>2_i387_noop"
4369 [(set (match_operand:MODEF 0 "register_operand" "=f")
4370 (float_truncate:MODEF
4371 (match_operand:XF 1 "register_operand" "f")))]
4372 "TARGET_80387 && flag_unsafe_math_optimizations"
4373 "* return output_387_reg_move (insn, operands);"
4374 [(set_attr "type" "fmov")
4375 (set_attr "mode" "<MODE>")])
4377 (define_insn "*truncxf<mode>2_i387"
4378 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4379 (float_truncate:MODEF
4380 (match_operand:XF 1 "register_operand" "f")))]
4382 "* return output_387_reg_move (insn, operands);"
4383 [(set_attr "type" "fmov")
4384 (set_attr "mode" "<MODE>")])
4387 [(set (match_operand:MODEF 0 "register_operand" "")
4388 (float_truncate:MODEF
4389 (match_operand:XF 1 "register_operand" "")))
4390 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4391 "TARGET_80387 && reload_completed"
4392 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4393 (set (match_dup 0) (match_dup 2))]
4397 [(set (match_operand:MODEF 0 "memory_operand" "")
4398 (float_truncate:MODEF
4399 (match_operand:XF 1 "register_operand" "")))
4400 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4402 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4405 ;; Signed conversion to DImode.
4407 (define_expand "fix_truncxfdi2"
4408 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4409 (fix:DI (match_operand:XF 1 "register_operand" "")))
4410 (clobber (reg:CC FLAGS_REG))])]
4415 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4420 (define_expand "fix_trunc<mode>di2"
4421 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4422 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4423 (clobber (reg:CC FLAGS_REG))])]
4424 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4427 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4429 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4432 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4434 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4435 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4436 if (out != operands[0])
4437 emit_move_insn (operands[0], out);
4442 ;; Signed conversion to SImode.
4444 (define_expand "fix_truncxfsi2"
4445 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4446 (fix:SI (match_operand:XF 1 "register_operand" "")))
4447 (clobber (reg:CC FLAGS_REG))])]
4452 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4457 (define_expand "fix_trunc<mode>si2"
4458 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4459 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4460 (clobber (reg:CC FLAGS_REG))])]
4461 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4464 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4466 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4469 if (SSE_FLOAT_MODE_P (<MODE>mode))
4471 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4472 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4473 if (out != operands[0])
4474 emit_move_insn (operands[0], out);
4479 ;; Signed conversion to HImode.
4481 (define_expand "fix_trunc<mode>hi2"
4482 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4483 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4484 (clobber (reg:CC FLAGS_REG))])]
4486 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4490 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4495 ;; Unsigned conversion to SImode.
4497 (define_expand "fixuns_trunc<mode>si2"
4499 [(set (match_operand:SI 0 "register_operand" "")
4501 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4503 (clobber (match_scratch:<ssevecmode> 3 ""))
4504 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4505 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4507 enum machine_mode mode = <MODE>mode;
4508 enum machine_mode vecmode = <ssevecmode>mode;
4509 REAL_VALUE_TYPE TWO31r;
4512 real_ldexp (&TWO31r, &dconst1, 31);
4513 two31 = const_double_from_real_value (TWO31r, mode);
4514 two31 = ix86_build_const_vector (mode, true, two31);
4515 operands[2] = force_reg (vecmode, two31);
4518 (define_insn_and_split "*fixuns_trunc<mode>_1"
4519 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4521 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4522 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4523 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4524 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4525 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4527 "&& reload_completed"
4530 ix86_split_convert_uns_si_sse (operands);
4534 ;; Unsigned conversion to HImode.
4535 ;; Without these patterns, we'll try the unsigned SI conversion which
4536 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4538 (define_expand "fixuns_trunc<mode>hi2"
4540 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4541 (set (match_operand:HI 0 "nonimmediate_operand" "")
4542 (subreg:HI (match_dup 2) 0))]
4543 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4544 "operands[2] = gen_reg_rtx (SImode);")
4546 ;; When SSE is available, it is always faster to use it!
4547 (define_insn "fix_trunc<mode>di_sse"
4548 [(set (match_operand:DI 0 "register_operand" "=r,r")
4549 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4550 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4551 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4552 "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4553 [(set_attr "type" "sseicvt")
4554 (set_attr "mode" "<MODE>")
4555 (set_attr "athlon_decode" "double,vector")
4556 (set_attr "amdfam10_decode" "double,double")])
4558 (define_insn "fix_trunc<mode>si_sse"
4559 [(set (match_operand:SI 0 "register_operand" "=r,r")
4560 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4561 "SSE_FLOAT_MODE_P (<MODE>mode)
4562 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4563 "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4564 [(set_attr "type" "sseicvt")
4565 (set_attr "mode" "<MODE>")
4566 (set_attr "athlon_decode" "double,vector")
4567 (set_attr "amdfam10_decode" "double,double")])
4569 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4571 [(set (match_operand:MODEF 0 "register_operand" "")
4572 (match_operand:MODEF 1 "memory_operand" ""))
4573 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4574 (fix:SSEMODEI24 (match_dup 0)))]
4575 "TARGET_SHORTEN_X87_SSE
4576 && peep2_reg_dead_p (2, operands[0])"
4577 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4580 ;; Avoid vector decoded forms of the instruction.
4582 [(match_scratch:DF 2 "Y2")
4583 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4584 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4585 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4586 [(set (match_dup 2) (match_dup 1))
4587 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4591 [(match_scratch:SF 2 "x")
4592 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4593 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4594 "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4595 [(set (match_dup 2) (match_dup 1))
4596 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4599 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4600 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4601 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4602 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4604 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4605 && (TARGET_64BIT || <MODE>mode != DImode))
4607 && !(reload_completed || reload_in_progress)"
4612 if (memory_operand (operands[0], VOIDmode))
4613 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4616 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4617 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4623 [(set_attr "type" "fisttp")
4624 (set_attr "mode" "<MODE>")])
4626 (define_insn "fix_trunc<mode>_i387_fisttp"
4627 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4628 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4629 (clobber (match_scratch:XF 2 "=&1f"))]
4630 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4632 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4633 && (TARGET_64BIT || <MODE>mode != DImode))
4634 && TARGET_SSE_MATH)"
4635 "* return output_fix_trunc (insn, operands, 1);"
4636 [(set_attr "type" "fisttp")
4637 (set_attr "mode" "<MODE>")])
4639 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4640 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4641 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4642 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4643 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4644 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4646 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4647 && (TARGET_64BIT || <MODE>mode != DImode))
4648 && TARGET_SSE_MATH)"
4650 [(set_attr "type" "fisttp")
4651 (set_attr "mode" "<MODE>")])
4654 [(set (match_operand:X87MODEI 0 "register_operand" "")
4655 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4656 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4657 (clobber (match_scratch 3 ""))]
4659 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4660 (clobber (match_dup 3))])
4661 (set (match_dup 0) (match_dup 2))]
4665 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4666 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4667 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4668 (clobber (match_scratch 3 ""))]
4670 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4671 (clobber (match_dup 3))])]
4674 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4675 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4676 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4677 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4678 ;; function in i386.c.
4679 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4680 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4681 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4682 (clobber (reg:CC FLAGS_REG))]
4683 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4685 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4686 && (TARGET_64BIT || <MODE>mode != DImode))
4687 && !(reload_completed || reload_in_progress)"
4692 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4694 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4695 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4696 if (memory_operand (operands[0], VOIDmode))
4697 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4698 operands[2], operands[3]));
4701 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4702 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4703 operands[2], operands[3],
4708 [(set_attr "type" "fistp")
4709 (set_attr "i387_cw" "trunc")
4710 (set_attr "mode" "<MODE>")])
4712 (define_insn "fix_truncdi_i387"
4713 [(set (match_operand:DI 0 "memory_operand" "=m")
4714 (fix:DI (match_operand 1 "register_operand" "f")))
4715 (use (match_operand:HI 2 "memory_operand" "m"))
4716 (use (match_operand:HI 3 "memory_operand" "m"))
4717 (clobber (match_scratch:XF 4 "=&1f"))]
4718 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4720 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4721 "* return output_fix_trunc (insn, operands, 0);"
4722 [(set_attr "type" "fistp")
4723 (set_attr "i387_cw" "trunc")
4724 (set_attr "mode" "DI")])
4726 (define_insn "fix_truncdi_i387_with_temp"
4727 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4728 (fix:DI (match_operand 1 "register_operand" "f,f")))
4729 (use (match_operand:HI 2 "memory_operand" "m,m"))
4730 (use (match_operand:HI 3 "memory_operand" "m,m"))
4731 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4732 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4733 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4735 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4737 [(set_attr "type" "fistp")
4738 (set_attr "i387_cw" "trunc")
4739 (set_attr "mode" "DI")])
4742 [(set (match_operand:DI 0 "register_operand" "")
4743 (fix:DI (match_operand 1 "register_operand" "")))
4744 (use (match_operand:HI 2 "memory_operand" ""))
4745 (use (match_operand:HI 3 "memory_operand" ""))
4746 (clobber (match_operand:DI 4 "memory_operand" ""))
4747 (clobber (match_scratch 5 ""))]
4749 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4752 (clobber (match_dup 5))])
4753 (set (match_dup 0) (match_dup 4))]
4757 [(set (match_operand:DI 0 "memory_operand" "")
4758 (fix:DI (match_operand 1 "register_operand" "")))
4759 (use (match_operand:HI 2 "memory_operand" ""))
4760 (use (match_operand:HI 3 "memory_operand" ""))
4761 (clobber (match_operand:DI 4 "memory_operand" ""))
4762 (clobber (match_scratch 5 ""))]
4764 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4767 (clobber (match_dup 5))])]
4770 (define_insn "fix_trunc<mode>_i387"
4771 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4772 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4773 (use (match_operand:HI 2 "memory_operand" "m"))
4774 (use (match_operand:HI 3 "memory_operand" "m"))]
4775 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4777 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4778 "* return output_fix_trunc (insn, operands, 0);"
4779 [(set_attr "type" "fistp")
4780 (set_attr "i387_cw" "trunc")
4781 (set_attr "mode" "<MODE>")])
4783 (define_insn "fix_trunc<mode>_i387_with_temp"
4784 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4785 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4786 (use (match_operand:HI 2 "memory_operand" "m,m"))
4787 (use (match_operand:HI 3 "memory_operand" "m,m"))
4788 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4789 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4791 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4793 [(set_attr "type" "fistp")
4794 (set_attr "i387_cw" "trunc")
4795 (set_attr "mode" "<MODE>")])
4798 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4799 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4800 (use (match_operand:HI 2 "memory_operand" ""))
4801 (use (match_operand:HI 3 "memory_operand" ""))
4802 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4804 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4806 (use (match_dup 3))])
4807 (set (match_dup 0) (match_dup 4))]
4811 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4812 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4813 (use (match_operand:HI 2 "memory_operand" ""))
4814 (use (match_operand:HI 3 "memory_operand" ""))
4815 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4817 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4819 (use (match_dup 3))])]
4822 (define_insn "x86_fnstcw_1"
4823 [(set (match_operand:HI 0 "memory_operand" "=m")
4824 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4827 [(set_attr "length" "2")
4828 (set_attr "mode" "HI")
4829 (set_attr "unit" "i387")])
4831 (define_insn "x86_fldcw_1"
4832 [(set (reg:HI FPCR_REG)
4833 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4836 [(set_attr "length" "2")
4837 (set_attr "mode" "HI")
4838 (set_attr "unit" "i387")
4839 (set_attr "athlon_decode" "vector")
4840 (set_attr "amdfam10_decode" "vector")])
4842 ;; Conversion between fixed point and floating point.
4844 ;; Even though we only accept memory inputs, the backend _really_
4845 ;; wants to be able to do this between registers.
4847 (define_expand "floathi<mode>2"
4848 [(set (match_operand:X87MODEF 0 "register_operand" "")
4849 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4852 || TARGET_MIX_SSE_I387)"
4855 ;; Pre-reload splitter to add memory clobber to the pattern.
4856 (define_insn_and_split "*floathi<mode>2_1"
4857 [(set (match_operand:X87MODEF 0 "register_operand" "")
4858 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4860 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4861 || TARGET_MIX_SSE_I387)
4862 && !(reload_completed || reload_in_progress)"
4865 [(parallel [(set (match_dup 0)
4866 (float:X87MODEF (match_dup 1)))
4867 (clobber (match_dup 2))])]
4868 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4870 (define_insn "*floathi<mode>2_i387_with_temp"
4871 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4872 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4873 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4875 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4876 || TARGET_MIX_SSE_I387)"
4878 [(set_attr "type" "fmov,multi")
4879 (set_attr "mode" "<MODE>")
4880 (set_attr "unit" "*,i387")
4881 (set_attr "fp_int_src" "true")])
4883 (define_insn "*floathi<mode>2_i387"
4884 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4885 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4887 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4888 || TARGET_MIX_SSE_I387)"
4890 [(set_attr "type" "fmov")
4891 (set_attr "mode" "<MODE>")
4892 (set_attr "fp_int_src" "true")])
4895 [(set (match_operand:X87MODEF 0 "register_operand" "")
4896 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4897 (clobber (match_operand:HI 2 "memory_operand" ""))]
4899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4900 || TARGET_MIX_SSE_I387)
4901 && reload_completed"
4902 [(set (match_dup 2) (match_dup 1))
4903 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4907 [(set (match_operand:X87MODEF 0 "register_operand" "")
4908 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4909 (clobber (match_operand:HI 2 "memory_operand" ""))]
4911 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4912 || TARGET_MIX_SSE_I387)
4913 && reload_completed"
4914 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4917 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4918 [(set (match_operand:X87MODEF 0 "register_operand" "")
4920 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4922 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4923 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4926 ;; Pre-reload splitter to add memory clobber to the pattern.
4927 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4928 [(set (match_operand:X87MODEF 0 "register_operand" "")
4929 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4931 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4932 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4933 || TARGET_MIX_SSE_I387))
4934 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4935 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4936 && ((<SSEMODEI24:MODE>mode == SImode
4937 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4938 && flag_trapping_math)
4939 || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4940 && !(reload_completed || reload_in_progress)"
4943 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4944 (clobber (match_dup 2))])]
4946 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4948 /* Avoid store forwarding (partial memory) stall penalty
4949 by passing DImode value through XMM registers. */
4950 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4951 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4954 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4961 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4962 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4964 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4965 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4966 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4967 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4969 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4970 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4971 (set_attr "unit" "*,i387,*,*,*")
4972 (set_attr "athlon_decode" "*,*,double,direct,double")
4973 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4974 (set_attr "fp_int_src" "true")])
4976 (define_insn "*floatsi<mode>2_vector_mixed"
4977 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4978 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4979 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4980 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4984 [(set_attr "type" "fmov,sseicvt")
4985 (set_attr "mode" "<MODE>,<ssevecmode>")
4986 (set_attr "unit" "i387,*")
4987 (set_attr "athlon_decode" "*,direct")
4988 (set_attr "amdfam10_decode" "*,double")
4989 (set_attr "fp_int_src" "true")])
4991 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4992 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4994 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4995 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4996 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4997 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4999 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5000 (set_attr "mode" "<MODEF:MODE>")
5001 (set_attr "unit" "*,i387,*,*")
5002 (set_attr "athlon_decode" "*,*,double,direct")
5003 (set_attr "amdfam10_decode" "*,*,vector,double")
5004 (set_attr "fp_int_src" "true")])
5007 [(set (match_operand:MODEF 0 "register_operand" "")
5008 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5009 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5010 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5011 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5012 && TARGET_INTER_UNIT_CONVERSIONS
5014 && (SSE_REG_P (operands[0])
5015 || (GET_CODE (operands[0]) == SUBREG
5016 && SSE_REG_P (operands[0])))"
5017 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5021 [(set (match_operand:MODEF 0 "register_operand" "")
5022 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5023 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5024 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5025 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5026 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5028 && (SSE_REG_P (operands[0])
5029 || (GET_CODE (operands[0]) == SUBREG
5030 && SSE_REG_P (operands[0])))"
5031 [(set (match_dup 2) (match_dup 1))
5032 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5035 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5036 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5038 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5039 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5040 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5041 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5044 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5045 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5046 [(set_attr "type" "fmov,sseicvt,sseicvt")
5047 (set_attr "mode" "<MODEF:MODE>")
5048 (set_attr "unit" "i387,*,*")
5049 (set_attr "athlon_decode" "*,double,direct")
5050 (set_attr "amdfam10_decode" "*,vector,double")
5051 (set_attr "fp_int_src" "true")])
5053 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5054 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5056 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5057 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5058 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5059 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5062 cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5063 [(set_attr "type" "fmov,sseicvt")
5064 (set_attr "mode" "<MODEF:MODE>")
5065 (set_attr "athlon_decode" "*,direct")
5066 (set_attr "amdfam10_decode" "*,double")
5067 (set_attr "fp_int_src" "true")])
5069 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5070 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5072 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5073 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5074 "TARGET_SSE2 && TARGET_SSE_MATH
5075 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5077 [(set_attr "type" "sseicvt")
5078 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5079 (set_attr "athlon_decode" "double,direct,double")
5080 (set_attr "amdfam10_decode" "vector,double,double")
5081 (set_attr "fp_int_src" "true")])
5083 (define_insn "*floatsi<mode>2_vector_sse"
5084 [(set (match_operand:MODEF 0 "register_operand" "=x")
5085 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5086 "TARGET_SSE2 && TARGET_SSE_MATH
5087 && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5089 [(set_attr "type" "sseicvt")
5090 (set_attr "mode" "<MODE>")
5091 (set_attr "athlon_decode" "direct")
5092 (set_attr "amdfam10_decode" "double")
5093 (set_attr "fp_int_src" "true")])
5096 [(set (match_operand:MODEF 0 "register_operand" "")
5097 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5098 (clobber (match_operand:SI 2 "memory_operand" ""))]
5099 "TARGET_SSE2 && TARGET_SSE_MATH
5100 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5102 && (SSE_REG_P (operands[0])
5103 || (GET_CODE (operands[0]) == SUBREG
5104 && SSE_REG_P (operands[0])))"
5107 rtx op1 = operands[1];
5109 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5111 if (GET_CODE (op1) == SUBREG)
5112 op1 = SUBREG_REG (op1);
5114 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5116 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5117 emit_insn (gen_sse2_loadld (operands[4],
5118 CONST0_RTX (V4SImode), operands[1]));
5120 /* We can ignore possible trapping value in the
5121 high part of SSE register for non-trapping math. */
5122 else if (SSE_REG_P (op1) && !flag_trapping_math)
5123 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5126 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5127 emit_move_insn (operands[2], operands[1]);
5128 emit_insn (gen_sse2_loadld (operands[4],
5129 CONST0_RTX (V4SImode), operands[2]));
5132 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5137 [(set (match_operand:MODEF 0 "register_operand" "")
5138 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5139 (clobber (match_operand:SI 2 "memory_operand" ""))]
5140 "TARGET_SSE2 && TARGET_SSE_MATH
5141 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5143 && (SSE_REG_P (operands[0])
5144 || (GET_CODE (operands[0]) == SUBREG
5145 && SSE_REG_P (operands[0])))"
5148 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5150 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5152 emit_insn (gen_sse2_loadld (operands[4],
5153 CONST0_RTX (V4SImode), operands[1]));
5155 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5160 [(set (match_operand:MODEF 0 "register_operand" "")
5161 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5162 "TARGET_SSE2 && TARGET_SSE_MATH
5163 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5165 && (SSE_REG_P (operands[0])
5166 || (GET_CODE (operands[0]) == SUBREG
5167 && SSE_REG_P (operands[0])))"
5170 rtx op1 = operands[1];
5172 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5174 if (GET_CODE (op1) == SUBREG)
5175 op1 = SUBREG_REG (op1);
5177 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5179 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5180 emit_insn (gen_sse2_loadld (operands[4],
5181 CONST0_RTX (V4SImode), operands[1]));
5183 /* We can ignore possible trapping value in the
5184 high part of SSE register for non-trapping math. */
5185 else if (SSE_REG_P (op1) && !flag_trapping_math)
5186 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5192 [(set (match_operand:MODEF 0 "register_operand" "")
5193 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5194 "TARGET_SSE2 && TARGET_SSE_MATH
5195 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5197 && (SSE_REG_P (operands[0])
5198 || (GET_CODE (operands[0]) == SUBREG
5199 && SSE_REG_P (operands[0])))"
5202 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5204 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5206 emit_insn (gen_sse2_loadld (operands[4],
5207 CONST0_RTX (V4SImode), operands[1]));
5209 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5213 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5214 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5216 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5217 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5218 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5219 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5221 [(set_attr "type" "sseicvt")
5222 (set_attr "mode" "<MODEF:MODE>")
5223 (set_attr "athlon_decode" "double,direct")
5224 (set_attr "amdfam10_decode" "vector,double")
5225 (set_attr "fp_int_src" "true")])
5227 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5228 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5230 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5231 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5232 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5233 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5234 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5235 [(set_attr "type" "sseicvt")
5236 (set_attr "mode" "<MODEF:MODE>")
5237 (set_attr "athlon_decode" "double,direct")
5238 (set_attr "amdfam10_decode" "vector,double")
5239 (set_attr "fp_int_src" "true")])
5242 [(set (match_operand:MODEF 0 "register_operand" "")
5243 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5244 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5245 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5246 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5247 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5249 && (SSE_REG_P (operands[0])
5250 || (GET_CODE (operands[0]) == SUBREG
5251 && SSE_REG_P (operands[0])))"
5252 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5255 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5256 [(set (match_operand:MODEF 0 "register_operand" "=x")
5258 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5259 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5260 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5261 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5262 "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5263 [(set_attr "type" "sseicvt")
5264 (set_attr "mode" "<MODEF:MODE>")
5265 (set_attr "athlon_decode" "direct")
5266 (set_attr "amdfam10_decode" "double")
5267 (set_attr "fp_int_src" "true")])
5270 [(set (match_operand:MODEF 0 "register_operand" "")
5271 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5272 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5273 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5274 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5275 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5277 && (SSE_REG_P (operands[0])
5278 || (GET_CODE (operands[0]) == SUBREG
5279 && SSE_REG_P (operands[0])))"
5280 [(set (match_dup 2) (match_dup 1))
5281 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5285 [(set (match_operand:MODEF 0 "register_operand" "")
5286 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5287 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5288 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5289 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5291 && (SSE_REG_P (operands[0])
5292 || (GET_CODE (operands[0]) == SUBREG
5293 && SSE_REG_P (operands[0])))"
5294 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5297 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5298 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5300 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5301 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5306 [(set_attr "type" "fmov,multi")
5307 (set_attr "mode" "<X87MODEF:MODE>")
5308 (set_attr "unit" "*,i387")
5309 (set_attr "fp_int_src" "true")])
5311 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5312 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5314 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5317 [(set_attr "type" "fmov")
5318 (set_attr "mode" "<X87MODEF:MODE>")
5319 (set_attr "fp_int_src" "true")])
5322 [(set (match_operand:X87MODEF 0 "register_operand" "")
5323 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5324 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5327 && FP_REG_P (operands[0])"
5328 [(set (match_dup 2) (match_dup 1))
5329 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5333 [(set (match_operand:X87MODEF 0 "register_operand" "")
5334 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5335 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5338 && FP_REG_P (operands[0])"
5339 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5342 ;; Avoid store forwarding (partial memory) stall penalty
5343 ;; by passing DImode value through XMM registers. */
5345 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5346 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5348 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5349 (clobber (match_scratch:V4SI 3 "=X,x"))
5350 (clobber (match_scratch:V4SI 4 "=X,x"))
5351 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5352 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5353 && !TARGET_64BIT && !optimize_size"
5355 [(set_attr "type" "multi")
5356 (set_attr "mode" "<X87MODEF:MODE>")
5357 (set_attr "unit" "i387")
5358 (set_attr "fp_int_src" "true")])
5361 [(set (match_operand:X87MODEF 0 "register_operand" "")
5362 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5363 (clobber (match_scratch:V4SI 3 ""))
5364 (clobber (match_scratch:V4SI 4 ""))
5365 (clobber (match_operand:DI 2 "memory_operand" ""))]
5366 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5367 && !TARGET_64BIT && !optimize_size
5369 && FP_REG_P (operands[0])"
5370 [(set (match_dup 2) (match_dup 3))
5371 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5373 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5374 Assemble the 64-bit DImode value in an xmm register. */
5375 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5376 gen_rtx_SUBREG (SImode, operands[1], 0)));
5377 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5378 gen_rtx_SUBREG (SImode, operands[1], 4)));
5379 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5381 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5385 [(set (match_operand:X87MODEF 0 "register_operand" "")
5386 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5387 (clobber (match_scratch:V4SI 3 ""))
5388 (clobber (match_scratch:V4SI 4 ""))
5389 (clobber (match_operand:DI 2 "memory_operand" ""))]
5390 "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5391 && !TARGET_64BIT && !optimize_size
5393 && FP_REG_P (operands[0])"
5394 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5397 ;; Avoid store forwarding (partial memory) stall penalty by extending
5398 ;; SImode value to DImode through XMM register instead of pushing two
5399 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5400 ;; targets benefit from this optimization. Also note that fild
5401 ;; loads from memory only.
5403 (define_insn "*floatunssi<mode>2_1"
5404 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5405 (unsigned_float:X87MODEF
5406 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5407 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5408 (clobber (match_scratch:SI 3 "=X,x"))]
5410 && TARGET_80387 && TARGET_SSE"
5412 [(set_attr "type" "multi")
5413 (set_attr "mode" "<MODE>")])
5416 [(set (match_operand:X87MODEF 0 "register_operand" "")
5417 (unsigned_float:X87MODEF
5418 (match_operand:SI 1 "register_operand" "")))
5419 (clobber (match_operand:DI 2 "memory_operand" ""))
5420 (clobber (match_scratch:SI 3 ""))]
5422 && TARGET_80387 && TARGET_SSE
5423 && reload_completed"
5424 [(set (match_dup 2) (match_dup 1))
5426 (float:X87MODEF (match_dup 2)))]
5427 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5430 [(set (match_operand:X87MODEF 0 "register_operand" "")
5431 (unsigned_float:X87MODEF
5432 (match_operand:SI 1 "memory_operand" "")))
5433 (clobber (match_operand:DI 2 "memory_operand" ""))
5434 (clobber (match_scratch:SI 3 ""))]
5436 && TARGET_80387 && TARGET_SSE
5437 && reload_completed"
5438 [(set (match_dup 2) (match_dup 3))
5440 (float:X87MODEF (match_dup 2)))]
5442 emit_move_insn (operands[3], operands[1]);
5443 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5446 (define_expand "floatunssi<mode>2"
5448 [(set (match_operand:X87MODEF 0 "register_operand" "")
5449 (unsigned_float:X87MODEF
5450 (match_operand:SI 1 "nonimmediate_operand" "")))
5451 (clobber (match_dup 2))
5452 (clobber (match_scratch:SI 3 ""))])]
5454 && ((TARGET_80387 && TARGET_SSE)
5455 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5457 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5459 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5464 int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5465 operands[2] = assign_386_stack_local (DImode, slot);
5469 (define_expand "floatunsdisf2"
5470 [(use (match_operand:SF 0 "register_operand" ""))
5471 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5472 "TARGET_64BIT && TARGET_SSE_MATH"
5473 "x86_emit_floatuns (operands); DONE;")
5475 (define_expand "floatunsdidf2"
5476 [(use (match_operand:DF 0 "register_operand" ""))
5477 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5478 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5479 && TARGET_SSE2 && TARGET_SSE_MATH"
5482 x86_emit_floatuns (operands);
5484 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5490 ;; %%% splits for addditi3
5492 (define_expand "addti3"
5493 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5494 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5495 (match_operand:TI 2 "x86_64_general_operand" "")))
5496 (clobber (reg:CC FLAGS_REG))]
5498 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5500 (define_insn "*addti3_1"
5501 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5502 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5503 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5504 (clobber (reg:CC FLAGS_REG))]
5505 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5509 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5510 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5511 (match_operand:TI 2 "x86_64_general_operand" "")))
5512 (clobber (reg:CC FLAGS_REG))]
5513 "TARGET_64BIT && reload_completed"
5514 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5516 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5517 (parallel [(set (match_dup 3)
5518 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5521 (clobber (reg:CC FLAGS_REG))])]
5522 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5524 ;; %%% splits for addsidi3
5525 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5526 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5527 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5529 (define_expand "adddi3"
5530 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5531 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5532 (match_operand:DI 2 "x86_64_general_operand" "")))
5533 (clobber (reg:CC FLAGS_REG))]
5535 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5537 (define_insn "*adddi3_1"
5538 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5539 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5540 (match_operand:DI 2 "general_operand" "roiF,riF")))
5541 (clobber (reg:CC FLAGS_REG))]
5542 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5546 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5547 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5548 (match_operand:DI 2 "general_operand" "")))
5549 (clobber (reg:CC FLAGS_REG))]
5550 "!TARGET_64BIT && reload_completed"
5551 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5553 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5554 (parallel [(set (match_dup 3)
5555 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5558 (clobber (reg:CC FLAGS_REG))])]
5559 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
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], 3, &operands[0], &operands[3]);")
7296 ;; %%% splits for subsidi3
7298 (define_expand "subdi3"
7299 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7300 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7301 (match_operand:DI 2 "x86_64_general_operand" "")))
7302 (clobber (reg:CC FLAGS_REG))])]
7304 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7306 (define_insn "*subdi3_1"
7307 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7308 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7309 (match_operand:DI 2 "general_operand" "roiF,riF")))
7310 (clobber (reg:CC FLAGS_REG))]
7311 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7315 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7316 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7317 (match_operand:DI 2 "general_operand" "")))
7318 (clobber (reg:CC FLAGS_REG))]
7319 "!TARGET_64BIT && reload_completed"
7320 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7321 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7322 (parallel [(set (match_dup 3)
7323 (minus:SI (match_dup 4)
7324 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7326 (clobber (reg:CC FLAGS_REG))])]
7327 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7329 (define_insn "subdi3_carry_rex64"
7330 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7331 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7332 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7333 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7334 (clobber (reg:CC FLAGS_REG))]
7335 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7336 "sbb{q}\t{%2, %0|%0, %2}"
7337 [(set_attr "type" "alu")
7338 (set_attr "pent_pair" "pu")
7339 (set_attr "mode" "DI")])
7341 (define_insn "*subdi_1_rex64"
7342 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7343 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7344 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7345 (clobber (reg:CC FLAGS_REG))]
7346 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7347 "sub{q}\t{%2, %0|%0, %2}"
7348 [(set_attr "type" "alu")
7349 (set_attr "mode" "DI")])
7351 (define_insn "*subdi_2_rex64"
7352 [(set (reg FLAGS_REG)
7354 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7355 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7357 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7358 (minus:DI (match_dup 1) (match_dup 2)))]
7359 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7360 && ix86_binary_operator_ok (MINUS, DImode, operands)"
7361 "sub{q}\t{%2, %0|%0, %2}"
7362 [(set_attr "type" "alu")
7363 (set_attr "mode" "DI")])
7365 (define_insn "*subdi_3_rex63"
7366 [(set (reg FLAGS_REG)
7367 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7368 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7369 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7370 (minus:DI (match_dup 1) (match_dup 2)))]
7371 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7372 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7373 "sub{q}\t{%2, %0|%0, %2}"
7374 [(set_attr "type" "alu")
7375 (set_attr "mode" "DI")])
7377 (define_insn "subqi3_carry"
7378 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7379 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7380 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7381 (match_operand:QI 2 "general_operand" "qi,qm"))))
7382 (clobber (reg:CC FLAGS_REG))]
7383 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7384 "sbb{b}\t{%2, %0|%0, %2}"
7385 [(set_attr "type" "alu")
7386 (set_attr "pent_pair" "pu")
7387 (set_attr "mode" "QI")])
7389 (define_insn "subhi3_carry"
7390 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7391 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7392 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7393 (match_operand:HI 2 "general_operand" "ri,rm"))))
7394 (clobber (reg:CC FLAGS_REG))]
7395 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7396 "sbb{w}\t{%2, %0|%0, %2}"
7397 [(set_attr "type" "alu")
7398 (set_attr "pent_pair" "pu")
7399 (set_attr "mode" "HI")])
7401 (define_insn "subsi3_carry"
7402 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7403 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7404 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7405 (match_operand:SI 2 "general_operand" "ri,rm"))))
7406 (clobber (reg:CC FLAGS_REG))]
7407 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7408 "sbb{l}\t{%2, %0|%0, %2}"
7409 [(set_attr "type" "alu")
7410 (set_attr "pent_pair" "pu")
7411 (set_attr "mode" "SI")])
7413 (define_insn "subsi3_carry_zext"
7414 [(set (match_operand:DI 0 "register_operand" "=r")
7416 (minus:SI (match_operand:SI 1 "register_operand" "0")
7417 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7418 (match_operand:SI 2 "general_operand" "g")))))
7419 (clobber (reg:CC FLAGS_REG))]
7420 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7421 "sbb{l}\t{%2, %k0|%k0, %2}"
7422 [(set_attr "type" "alu")
7423 (set_attr "pent_pair" "pu")
7424 (set_attr "mode" "SI")])
7426 (define_expand "subsi3"
7427 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7428 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7429 (match_operand:SI 2 "general_operand" "")))
7430 (clobber (reg:CC FLAGS_REG))])]
7432 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7434 (define_insn "*subsi_1"
7435 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7436 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7437 (match_operand:SI 2 "general_operand" "ri,rm")))
7438 (clobber (reg:CC FLAGS_REG))]
7439 "ix86_binary_operator_ok (MINUS, SImode, operands)"
7440 "sub{l}\t{%2, %0|%0, %2}"
7441 [(set_attr "type" "alu")
7442 (set_attr "mode" "SI")])
7444 (define_insn "*subsi_1_zext"
7445 [(set (match_operand:DI 0 "register_operand" "=r")
7447 (minus:SI (match_operand:SI 1 "register_operand" "0")
7448 (match_operand:SI 2 "general_operand" "g"))))
7449 (clobber (reg:CC FLAGS_REG))]
7450 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7451 "sub{l}\t{%2, %k0|%k0, %2}"
7452 [(set_attr "type" "alu")
7453 (set_attr "mode" "SI")])
7455 (define_insn "*subsi_2"
7456 [(set (reg FLAGS_REG)
7458 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7459 (match_operand:SI 2 "general_operand" "ri,rm"))
7461 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7462 (minus:SI (match_dup 1) (match_dup 2)))]
7463 "ix86_match_ccmode (insn, CCGOCmode)
7464 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7465 "sub{l}\t{%2, %0|%0, %2}"
7466 [(set_attr "type" "alu")
7467 (set_attr "mode" "SI")])
7469 (define_insn "*subsi_2_zext"
7470 [(set (reg FLAGS_REG)
7472 (minus:SI (match_operand:SI 1 "register_operand" "0")
7473 (match_operand:SI 2 "general_operand" "g"))
7475 (set (match_operand:DI 0 "register_operand" "=r")
7477 (minus:SI (match_dup 1)
7479 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7480 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7481 "sub{l}\t{%2, %k0|%k0, %2}"
7482 [(set_attr "type" "alu")
7483 (set_attr "mode" "SI")])
7485 (define_insn "*subsi_3"
7486 [(set (reg FLAGS_REG)
7487 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7488 (match_operand:SI 2 "general_operand" "ri,rm")))
7489 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7490 (minus:SI (match_dup 1) (match_dup 2)))]
7491 "ix86_match_ccmode (insn, CCmode)
7492 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7493 "sub{l}\t{%2, %0|%0, %2}"
7494 [(set_attr "type" "alu")
7495 (set_attr "mode" "SI")])
7497 (define_insn "*subsi_3_zext"
7498 [(set (reg FLAGS_REG)
7499 (compare (match_operand:SI 1 "register_operand" "0")
7500 (match_operand:SI 2 "general_operand" "g")))
7501 (set (match_operand:DI 0 "register_operand" "=r")
7503 (minus:SI (match_dup 1)
7505 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7506 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7507 "sub{l}\t{%2, %1|%1, %2}"
7508 [(set_attr "type" "alu")
7509 (set_attr "mode" "DI")])
7511 (define_expand "subhi3"
7512 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7513 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7514 (match_operand:HI 2 "general_operand" "")))
7515 (clobber (reg:CC FLAGS_REG))])]
7516 "TARGET_HIMODE_MATH"
7517 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7519 (define_insn "*subhi_1"
7520 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7521 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7522 (match_operand:HI 2 "general_operand" "ri,rm")))
7523 (clobber (reg:CC FLAGS_REG))]
7524 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7525 "sub{w}\t{%2, %0|%0, %2}"
7526 [(set_attr "type" "alu")
7527 (set_attr "mode" "HI")])
7529 (define_insn "*subhi_2"
7530 [(set (reg FLAGS_REG)
7532 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7533 (match_operand:HI 2 "general_operand" "ri,rm"))
7535 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7536 (minus:HI (match_dup 1) (match_dup 2)))]
7537 "ix86_match_ccmode (insn, CCGOCmode)
7538 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7539 "sub{w}\t{%2, %0|%0, %2}"
7540 [(set_attr "type" "alu")
7541 (set_attr "mode" "HI")])
7543 (define_insn "*subhi_3"
7544 [(set (reg FLAGS_REG)
7545 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7546 (match_operand:HI 2 "general_operand" "ri,rm")))
7547 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7548 (minus:HI (match_dup 1) (match_dup 2)))]
7549 "ix86_match_ccmode (insn, CCmode)
7550 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7551 "sub{w}\t{%2, %0|%0, %2}"
7552 [(set_attr "type" "alu")
7553 (set_attr "mode" "HI")])
7555 (define_expand "subqi3"
7556 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7557 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7558 (match_operand:QI 2 "general_operand" "")))
7559 (clobber (reg:CC FLAGS_REG))])]
7560 "TARGET_QIMODE_MATH"
7561 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7563 (define_insn "*subqi_1"
7564 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7565 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7566 (match_operand:QI 2 "general_operand" "qn,qmn")))
7567 (clobber (reg:CC FLAGS_REG))]
7568 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7569 "sub{b}\t{%2, %0|%0, %2}"
7570 [(set_attr "type" "alu")
7571 (set_attr "mode" "QI")])
7573 (define_insn "*subqi_1_slp"
7574 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7575 (minus:QI (match_dup 0)
7576 (match_operand:QI 1 "general_operand" "qn,qmn")))
7577 (clobber (reg:CC FLAGS_REG))]
7578 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7579 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7580 "sub{b}\t{%1, %0|%0, %1}"
7581 [(set_attr "type" "alu1")
7582 (set_attr "mode" "QI")])
7584 (define_insn "*subqi_2"
7585 [(set (reg FLAGS_REG)
7587 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7588 (match_operand:QI 2 "general_operand" "qi,qm"))
7590 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7591 (minus:HI (match_dup 1) (match_dup 2)))]
7592 "ix86_match_ccmode (insn, CCGOCmode)
7593 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7594 "sub{b}\t{%2, %0|%0, %2}"
7595 [(set_attr "type" "alu")
7596 (set_attr "mode" "QI")])
7598 (define_insn "*subqi_3"
7599 [(set (reg FLAGS_REG)
7600 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7601 (match_operand:QI 2 "general_operand" "qi,qm")))
7602 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7603 (minus:HI (match_dup 1) (match_dup 2)))]
7604 "ix86_match_ccmode (insn, CCmode)
7605 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7606 "sub{b}\t{%2, %0|%0, %2}"
7607 [(set_attr "type" "alu")
7608 (set_attr "mode" "QI")])
7610 ;; The patterns that match these are at the end of this file.
7612 (define_expand "subxf3"
7613 [(set (match_operand:XF 0 "register_operand" "")
7614 (minus:XF (match_operand:XF 1 "register_operand" "")
7615 (match_operand:XF 2 "register_operand" "")))]
7619 (define_expand "sub<mode>3"
7620 [(set (match_operand:MODEF 0 "register_operand" "")
7621 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7622 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7623 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7626 ;; Multiply instructions
7628 (define_expand "muldi3"
7629 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7630 (mult:DI (match_operand:DI 1 "register_operand" "")
7631 (match_operand:DI 2 "x86_64_general_operand" "")))
7632 (clobber (reg:CC FLAGS_REG))])]
7637 ;; IMUL reg64, reg64, imm8 Direct
7638 ;; IMUL reg64, mem64, imm8 VectorPath
7639 ;; IMUL reg64, reg64, imm32 Direct
7640 ;; IMUL reg64, mem64, imm32 VectorPath
7641 ;; IMUL reg64, reg64 Direct
7642 ;; IMUL reg64, mem64 Direct
7644 (define_insn "*muldi3_1_rex64"
7645 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7646 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7647 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7648 (clobber (reg:CC FLAGS_REG))]
7650 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7652 imul{q}\t{%2, %1, %0|%0, %1, %2}
7653 imul{q}\t{%2, %1, %0|%0, %1, %2}
7654 imul{q}\t{%2, %0|%0, %2}"
7655 [(set_attr "type" "imul")
7656 (set_attr "prefix_0f" "0,0,1")
7657 (set (attr "athlon_decode")
7658 (cond [(eq_attr "cpu" "athlon")
7659 (const_string "vector")
7660 (eq_attr "alternative" "1")
7661 (const_string "vector")
7662 (and (eq_attr "alternative" "2")
7663 (match_operand 1 "memory_operand" ""))
7664 (const_string "vector")]
7665 (const_string "direct")))
7666 (set (attr "amdfam10_decode")
7667 (cond [(and (eq_attr "alternative" "0,1")
7668 (match_operand 1 "memory_operand" ""))
7669 (const_string "vector")]
7670 (const_string "direct")))
7671 (set_attr "mode" "DI")])
7673 (define_expand "mulsi3"
7674 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7675 (mult:SI (match_operand:SI 1 "register_operand" "")
7676 (match_operand:SI 2 "general_operand" "")))
7677 (clobber (reg:CC FLAGS_REG))])]
7682 ;; IMUL reg32, reg32, imm8 Direct
7683 ;; IMUL reg32, mem32, imm8 VectorPath
7684 ;; IMUL reg32, reg32, imm32 Direct
7685 ;; IMUL reg32, mem32, imm32 VectorPath
7686 ;; IMUL reg32, reg32 Direct
7687 ;; IMUL reg32, mem32 Direct
7689 (define_insn "*mulsi3_1"
7690 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7691 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7692 (match_operand:SI 2 "general_operand" "K,i,mr")))
7693 (clobber (reg:CC FLAGS_REG))]
7694 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7696 imul{l}\t{%2, %1, %0|%0, %1, %2}
7697 imul{l}\t{%2, %1, %0|%0, %1, %2}
7698 imul{l}\t{%2, %0|%0, %2}"
7699 [(set_attr "type" "imul")
7700 (set_attr "prefix_0f" "0,0,1")
7701 (set (attr "athlon_decode")
7702 (cond [(eq_attr "cpu" "athlon")
7703 (const_string "vector")
7704 (eq_attr "alternative" "1")
7705 (const_string "vector")
7706 (and (eq_attr "alternative" "2")
7707 (match_operand 1 "memory_operand" ""))
7708 (const_string "vector")]
7709 (const_string "direct")))
7710 (set (attr "amdfam10_decode")
7711 (cond [(and (eq_attr "alternative" "0,1")
7712 (match_operand 1 "memory_operand" ""))
7713 (const_string "vector")]
7714 (const_string "direct")))
7715 (set_attr "mode" "SI")])
7717 (define_insn "*mulsi3_1_zext"
7718 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7720 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7721 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7722 (clobber (reg:CC FLAGS_REG))]
7724 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7726 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7727 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7728 imul{l}\t{%2, %k0|%k0, %2}"
7729 [(set_attr "type" "imul")
7730 (set_attr "prefix_0f" "0,0,1")
7731 (set (attr "athlon_decode")
7732 (cond [(eq_attr "cpu" "athlon")
7733 (const_string "vector")
7734 (eq_attr "alternative" "1")
7735 (const_string "vector")
7736 (and (eq_attr "alternative" "2")
7737 (match_operand 1 "memory_operand" ""))
7738 (const_string "vector")]
7739 (const_string "direct")))
7740 (set (attr "amdfam10_decode")
7741 (cond [(and (eq_attr "alternative" "0,1")
7742 (match_operand 1 "memory_operand" ""))
7743 (const_string "vector")]
7744 (const_string "direct")))
7745 (set_attr "mode" "SI")])
7747 (define_expand "mulhi3"
7748 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7749 (mult:HI (match_operand:HI 1 "register_operand" "")
7750 (match_operand:HI 2 "general_operand" "")))
7751 (clobber (reg:CC FLAGS_REG))])]
7752 "TARGET_HIMODE_MATH"
7756 ;; IMUL reg16, reg16, imm8 VectorPath
7757 ;; IMUL reg16, mem16, imm8 VectorPath
7758 ;; IMUL reg16, reg16, imm16 VectorPath
7759 ;; IMUL reg16, mem16, imm16 VectorPath
7760 ;; IMUL reg16, reg16 Direct
7761 ;; IMUL reg16, mem16 Direct
7762 (define_insn "*mulhi3_1"
7763 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7764 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7765 (match_operand:HI 2 "general_operand" "K,i,mr")))
7766 (clobber (reg:CC FLAGS_REG))]
7767 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7769 imul{w}\t{%2, %1, %0|%0, %1, %2}
7770 imul{w}\t{%2, %1, %0|%0, %1, %2}
7771 imul{w}\t{%2, %0|%0, %2}"
7772 [(set_attr "type" "imul")
7773 (set_attr "prefix_0f" "0,0,1")
7774 (set (attr "athlon_decode")
7775 (cond [(eq_attr "cpu" "athlon")
7776 (const_string "vector")
7777 (eq_attr "alternative" "1,2")
7778 (const_string "vector")]
7779 (const_string "direct")))
7780 (set (attr "amdfam10_decode")
7781 (cond [(eq_attr "alternative" "0,1")
7782 (const_string "vector")]
7783 (const_string "direct")))
7784 (set_attr "mode" "HI")])
7786 (define_expand "mulqi3"
7787 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7788 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7789 (match_operand:QI 2 "register_operand" "")))
7790 (clobber (reg:CC FLAGS_REG))])]
7791 "TARGET_QIMODE_MATH"
7798 (define_insn "*mulqi3_1"
7799 [(set (match_operand:QI 0 "register_operand" "=a")
7800 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7801 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7802 (clobber (reg:CC FLAGS_REG))]
7804 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7806 [(set_attr "type" "imul")
7807 (set_attr "length_immediate" "0")
7808 (set (attr "athlon_decode")
7809 (if_then_else (eq_attr "cpu" "athlon")
7810 (const_string "vector")
7811 (const_string "direct")))
7812 (set_attr "amdfam10_decode" "direct")
7813 (set_attr "mode" "QI")])
7815 (define_expand "umulqihi3"
7816 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7817 (mult:HI (zero_extend:HI
7818 (match_operand:QI 1 "nonimmediate_operand" ""))
7820 (match_operand:QI 2 "register_operand" ""))))
7821 (clobber (reg:CC FLAGS_REG))])]
7822 "TARGET_QIMODE_MATH"
7825 (define_insn "*umulqihi3_1"
7826 [(set (match_operand:HI 0 "register_operand" "=a")
7827 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7828 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7829 (clobber (reg:CC FLAGS_REG))]
7831 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7833 [(set_attr "type" "imul")
7834 (set_attr "length_immediate" "0")
7835 (set (attr "athlon_decode")
7836 (if_then_else (eq_attr "cpu" "athlon")
7837 (const_string "vector")
7838 (const_string "direct")))
7839 (set_attr "amdfam10_decode" "direct")
7840 (set_attr "mode" "QI")])
7842 (define_expand "mulqihi3"
7843 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7844 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7845 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7846 (clobber (reg:CC FLAGS_REG))])]
7847 "TARGET_QIMODE_MATH"
7850 (define_insn "*mulqihi3_insn"
7851 [(set (match_operand:HI 0 "register_operand" "=a")
7852 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7853 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7854 (clobber (reg:CC FLAGS_REG))]
7856 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7858 [(set_attr "type" "imul")
7859 (set_attr "length_immediate" "0")
7860 (set (attr "athlon_decode")
7861 (if_then_else (eq_attr "cpu" "athlon")
7862 (const_string "vector")
7863 (const_string "direct")))
7864 (set_attr "amdfam10_decode" "direct")
7865 (set_attr "mode" "QI")])
7867 (define_expand "umulditi3"
7868 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7869 (mult:TI (zero_extend:TI
7870 (match_operand:DI 1 "nonimmediate_operand" ""))
7872 (match_operand:DI 2 "register_operand" ""))))
7873 (clobber (reg:CC FLAGS_REG))])]
7877 (define_insn "*umulditi3_insn"
7878 [(set (match_operand:TI 0 "register_operand" "=A")
7879 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7880 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7881 (clobber (reg:CC FLAGS_REG))]
7883 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7885 [(set_attr "type" "imul")
7886 (set_attr "length_immediate" "0")
7887 (set (attr "athlon_decode")
7888 (if_then_else (eq_attr "cpu" "athlon")
7889 (const_string "vector")
7890 (const_string "double")))
7891 (set_attr "amdfam10_decode" "double")
7892 (set_attr "mode" "DI")])
7894 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7895 (define_expand "umulsidi3"
7896 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7897 (mult:DI (zero_extend:DI
7898 (match_operand:SI 1 "nonimmediate_operand" ""))
7900 (match_operand:SI 2 "register_operand" ""))))
7901 (clobber (reg:CC FLAGS_REG))])]
7905 (define_insn "*umulsidi3_insn"
7906 [(set (match_operand:DI 0 "register_operand" "=A")
7907 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7908 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7909 (clobber (reg:CC FLAGS_REG))]
7911 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7913 [(set_attr "type" "imul")
7914 (set_attr "length_immediate" "0")
7915 (set (attr "athlon_decode")
7916 (if_then_else (eq_attr "cpu" "athlon")
7917 (const_string "vector")
7918 (const_string "double")))
7919 (set_attr "amdfam10_decode" "double")
7920 (set_attr "mode" "SI")])
7922 (define_expand "mulditi3"
7923 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7924 (mult:TI (sign_extend:TI
7925 (match_operand:DI 1 "nonimmediate_operand" ""))
7927 (match_operand:DI 2 "register_operand" ""))))
7928 (clobber (reg:CC FLAGS_REG))])]
7932 (define_insn "*mulditi3_insn"
7933 [(set (match_operand:TI 0 "register_operand" "=A")
7934 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7935 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7936 (clobber (reg:CC FLAGS_REG))]
7938 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7940 [(set_attr "type" "imul")
7941 (set_attr "length_immediate" "0")
7942 (set (attr "athlon_decode")
7943 (if_then_else (eq_attr "cpu" "athlon")
7944 (const_string "vector")
7945 (const_string "double")))
7946 (set_attr "amdfam10_decode" "double")
7947 (set_attr "mode" "DI")])
7949 (define_expand "mulsidi3"
7950 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7951 (mult:DI (sign_extend:DI
7952 (match_operand:SI 1 "nonimmediate_operand" ""))
7954 (match_operand:SI 2 "register_operand" ""))))
7955 (clobber (reg:CC FLAGS_REG))])]
7959 (define_insn "*mulsidi3_insn"
7960 [(set (match_operand:DI 0 "register_operand" "=A")
7961 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7962 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7963 (clobber (reg:CC FLAGS_REG))]
7965 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7967 [(set_attr "type" "imul")
7968 (set_attr "length_immediate" "0")
7969 (set (attr "athlon_decode")
7970 (if_then_else (eq_attr "cpu" "athlon")
7971 (const_string "vector")
7972 (const_string "double")))
7973 (set_attr "amdfam10_decode" "double")
7974 (set_attr "mode" "SI")])
7976 (define_expand "umuldi3_highpart"
7977 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7980 (mult:TI (zero_extend:TI
7981 (match_operand:DI 1 "nonimmediate_operand" ""))
7983 (match_operand:DI 2 "register_operand" "")))
7985 (clobber (match_scratch:DI 3 ""))
7986 (clobber (reg:CC FLAGS_REG))])]
7990 (define_insn "*umuldi3_highpart_rex64"
7991 [(set (match_operand:DI 0 "register_operand" "=d")
7994 (mult:TI (zero_extend:TI
7995 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7997 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7999 (clobber (match_scratch:DI 3 "=1"))
8000 (clobber (reg:CC FLAGS_REG))]
8002 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8004 [(set_attr "type" "imul")
8005 (set_attr "length_immediate" "0")
8006 (set (attr "athlon_decode")
8007 (if_then_else (eq_attr "cpu" "athlon")
8008 (const_string "vector")
8009 (const_string "double")))
8010 (set_attr "amdfam10_decode" "double")
8011 (set_attr "mode" "DI")])
8013 (define_expand "umulsi3_highpart"
8014 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8017 (mult:DI (zero_extend:DI
8018 (match_operand:SI 1 "nonimmediate_operand" ""))
8020 (match_operand:SI 2 "register_operand" "")))
8022 (clobber (match_scratch:SI 3 ""))
8023 (clobber (reg:CC FLAGS_REG))])]
8027 (define_insn "*umulsi3_highpart_insn"
8028 [(set (match_operand:SI 0 "register_operand" "=d")
8031 (mult:DI (zero_extend:DI
8032 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8034 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8036 (clobber (match_scratch:SI 3 "=1"))
8037 (clobber (reg:CC FLAGS_REG))]
8038 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8040 [(set_attr "type" "imul")
8041 (set_attr "length_immediate" "0")
8042 (set (attr "athlon_decode")
8043 (if_then_else (eq_attr "cpu" "athlon")
8044 (const_string "vector")
8045 (const_string "double")))
8046 (set_attr "amdfam10_decode" "double")
8047 (set_attr "mode" "SI")])
8049 (define_insn "*umulsi3_highpart_zext"
8050 [(set (match_operand:DI 0 "register_operand" "=d")
8051 (zero_extend:DI (truncate:SI
8053 (mult:DI (zero_extend:DI
8054 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8056 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8058 (clobber (match_scratch:SI 3 "=1"))
8059 (clobber (reg:CC FLAGS_REG))]
8061 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8063 [(set_attr "type" "imul")
8064 (set_attr "length_immediate" "0")
8065 (set (attr "athlon_decode")
8066 (if_then_else (eq_attr "cpu" "athlon")
8067 (const_string "vector")
8068 (const_string "double")))
8069 (set_attr "amdfam10_decode" "double")
8070 (set_attr "mode" "SI")])
8072 (define_expand "smuldi3_highpart"
8073 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8076 (mult:TI (sign_extend:TI
8077 (match_operand:DI 1 "nonimmediate_operand" ""))
8079 (match_operand:DI 2 "register_operand" "")))
8081 (clobber (match_scratch:DI 3 ""))
8082 (clobber (reg:CC FLAGS_REG))])]
8086 (define_insn "*smuldi3_highpart_rex64"
8087 [(set (match_operand:DI 0 "register_operand" "=d")
8090 (mult:TI (sign_extend:TI
8091 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8093 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8095 (clobber (match_scratch:DI 3 "=1"))
8096 (clobber (reg:CC FLAGS_REG))]
8098 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8100 [(set_attr "type" "imul")
8101 (set (attr "athlon_decode")
8102 (if_then_else (eq_attr "cpu" "athlon")
8103 (const_string "vector")
8104 (const_string "double")))
8105 (set_attr "amdfam10_decode" "double")
8106 (set_attr "mode" "DI")])
8108 (define_expand "smulsi3_highpart"
8109 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8112 (mult:DI (sign_extend:DI
8113 (match_operand:SI 1 "nonimmediate_operand" ""))
8115 (match_operand:SI 2 "register_operand" "")))
8117 (clobber (match_scratch:SI 3 ""))
8118 (clobber (reg:CC FLAGS_REG))])]
8122 (define_insn "*smulsi3_highpart_insn"
8123 [(set (match_operand:SI 0 "register_operand" "=d")
8126 (mult:DI (sign_extend:DI
8127 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8129 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8131 (clobber (match_scratch:SI 3 "=1"))
8132 (clobber (reg:CC FLAGS_REG))]
8133 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8135 [(set_attr "type" "imul")
8136 (set (attr "athlon_decode")
8137 (if_then_else (eq_attr "cpu" "athlon")
8138 (const_string "vector")
8139 (const_string "double")))
8140 (set_attr "amdfam10_decode" "double")
8141 (set_attr "mode" "SI")])
8143 (define_insn "*smulsi3_highpart_zext"
8144 [(set (match_operand:DI 0 "register_operand" "=d")
8145 (zero_extend:DI (truncate:SI
8147 (mult:DI (sign_extend:DI
8148 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8150 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8152 (clobber (match_scratch:SI 3 "=1"))
8153 (clobber (reg:CC FLAGS_REG))]
8155 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8157 [(set_attr "type" "imul")
8158 (set (attr "athlon_decode")
8159 (if_then_else (eq_attr "cpu" "athlon")
8160 (const_string "vector")
8161 (const_string "double")))
8162 (set_attr "amdfam10_decode" "double")
8163 (set_attr "mode" "SI")])
8165 ;; The patterns that match these are at the end of this file.
8167 (define_expand "mulxf3"
8168 [(set (match_operand:XF 0 "register_operand" "")
8169 (mult:XF (match_operand:XF 1 "register_operand" "")
8170 (match_operand:XF 2 "register_operand" "")))]
8174 (define_expand "mul<mode>3"
8175 [(set (match_operand:MODEF 0 "register_operand" "")
8176 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8177 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8178 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8181 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8184 ;; Divide instructions
8186 (define_insn "divqi3"
8187 [(set (match_operand:QI 0 "register_operand" "=a")
8188 (div:QI (match_operand:HI 1 "register_operand" "0")
8189 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8190 (clobber (reg:CC FLAGS_REG))]
8191 "TARGET_QIMODE_MATH"
8193 [(set_attr "type" "idiv")
8194 (set_attr "mode" "QI")])
8196 (define_insn "udivqi3"
8197 [(set (match_operand:QI 0 "register_operand" "=a")
8198 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8199 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "TARGET_QIMODE_MATH"
8203 [(set_attr "type" "idiv")
8204 (set_attr "mode" "QI")])
8206 ;; The patterns that match these are at the end of this file.
8208 (define_expand "divxf3"
8209 [(set (match_operand:XF 0 "register_operand" "")
8210 (div:XF (match_operand:XF 1 "register_operand" "")
8211 (match_operand:XF 2 "register_operand" "")))]
8215 (define_expand "divdf3"
8216 [(set (match_operand:DF 0 "register_operand" "")
8217 (div:DF (match_operand:DF 1 "register_operand" "")
8218 (match_operand:DF 2 "nonimmediate_operand" "")))]
8219 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8222 (define_expand "divsf3"
8223 [(set (match_operand:SF 0 "register_operand" "")
8224 (div:SF (match_operand:SF 1 "register_operand" "")
8225 (match_operand:SF 2 "nonimmediate_operand" "")))]
8226 "TARGET_80387 || TARGET_SSE_MATH"
8228 if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8229 && flag_finite_math_only && !flag_trapping_math
8230 && flag_unsafe_math_optimizations)
8232 ix86_emit_swdivsf (operands[0], operands[1],
8233 operands[2], SFmode);
8238 ;; Remainder instructions.
8240 (define_expand "divmoddi4"
8241 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8242 (div:DI (match_operand:DI 1 "register_operand" "")
8243 (match_operand:DI 2 "nonimmediate_operand" "")))
8244 (set (match_operand:DI 3 "register_operand" "")
8245 (mod:DI (match_dup 1) (match_dup 2)))
8246 (clobber (reg:CC FLAGS_REG))])]
8250 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8251 ;; Penalize eax case slightly because it results in worse scheduling
8253 (define_insn "*divmoddi4_nocltd_rex64"
8254 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8255 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8256 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8257 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8258 (mod:DI (match_dup 2) (match_dup 3)))
8259 (clobber (reg:CC FLAGS_REG))]
8260 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8262 [(set_attr "type" "multi")])
8264 (define_insn "*divmoddi4_cltd_rex64"
8265 [(set (match_operand:DI 0 "register_operand" "=a")
8266 (div:DI (match_operand:DI 2 "register_operand" "a")
8267 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8268 (set (match_operand:DI 1 "register_operand" "=&d")
8269 (mod:DI (match_dup 2) (match_dup 3)))
8270 (clobber (reg:CC FLAGS_REG))]
8271 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8273 [(set_attr "type" "multi")])
8275 (define_insn "*divmoddi_noext_rex64"
8276 [(set (match_operand:DI 0 "register_operand" "=a")
8277 (div:DI (match_operand:DI 1 "register_operand" "0")
8278 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8279 (set (match_operand:DI 3 "register_operand" "=d")
8280 (mod:DI (match_dup 1) (match_dup 2)))
8281 (use (match_operand:DI 4 "register_operand" "3"))
8282 (clobber (reg:CC FLAGS_REG))]
8285 [(set_attr "type" "idiv")
8286 (set_attr "mode" "DI")])
8289 [(set (match_operand:DI 0 "register_operand" "")
8290 (div:DI (match_operand:DI 1 "register_operand" "")
8291 (match_operand:DI 2 "nonimmediate_operand" "")))
8292 (set (match_operand:DI 3 "register_operand" "")
8293 (mod:DI (match_dup 1) (match_dup 2)))
8294 (clobber (reg:CC FLAGS_REG))]
8295 "TARGET_64BIT && reload_completed"
8296 [(parallel [(set (match_dup 3)
8297 (ashiftrt:DI (match_dup 4) (const_int 63)))
8298 (clobber (reg:CC FLAGS_REG))])
8299 (parallel [(set (match_dup 0)
8300 (div:DI (reg:DI 0) (match_dup 2)))
8302 (mod:DI (reg:DI 0) (match_dup 2)))
8304 (clobber (reg:CC FLAGS_REG))])]
8306 /* Avoid use of cltd in favor of a mov+shift. */
8307 if (!TARGET_USE_CLTD && !optimize_size)
8309 if (true_regnum (operands[1]))
8310 emit_move_insn (operands[0], operands[1]);
8312 emit_move_insn (operands[3], operands[1]);
8313 operands[4] = operands[3];
8317 gcc_assert (!true_regnum (operands[1]));
8318 operands[4] = operands[1];
8323 (define_expand "divmodsi4"
8324 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8325 (div:SI (match_operand:SI 1 "register_operand" "")
8326 (match_operand:SI 2 "nonimmediate_operand" "")))
8327 (set (match_operand:SI 3 "register_operand" "")
8328 (mod:SI (match_dup 1) (match_dup 2)))
8329 (clobber (reg:CC FLAGS_REG))])]
8333 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8334 ;; Penalize eax case slightly because it results in worse scheduling
8336 (define_insn "*divmodsi4_nocltd"
8337 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8338 (div:SI (match_operand:SI 2 "register_operand" "1,0")
8339 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8340 (set (match_operand:SI 1 "register_operand" "=&d,&d")
8341 (mod:SI (match_dup 2) (match_dup 3)))
8342 (clobber (reg:CC FLAGS_REG))]
8343 "!optimize_size && !TARGET_USE_CLTD"
8345 [(set_attr "type" "multi")])
8347 (define_insn "*divmodsi4_cltd"
8348 [(set (match_operand:SI 0 "register_operand" "=a")
8349 (div:SI (match_operand:SI 2 "register_operand" "a")
8350 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8351 (set (match_operand:SI 1 "register_operand" "=&d")
8352 (mod:SI (match_dup 2) (match_dup 3)))
8353 (clobber (reg:CC FLAGS_REG))]
8354 "optimize_size || TARGET_USE_CLTD"
8356 [(set_attr "type" "multi")])
8358 (define_insn "*divmodsi_noext"
8359 [(set (match_operand:SI 0 "register_operand" "=a")
8360 (div:SI (match_operand:SI 1 "register_operand" "0")
8361 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8362 (set (match_operand:SI 3 "register_operand" "=d")
8363 (mod:SI (match_dup 1) (match_dup 2)))
8364 (use (match_operand:SI 4 "register_operand" "3"))
8365 (clobber (reg:CC FLAGS_REG))]
8368 [(set_attr "type" "idiv")
8369 (set_attr "mode" "SI")])
8372 [(set (match_operand:SI 0 "register_operand" "")
8373 (div:SI (match_operand:SI 1 "register_operand" "")
8374 (match_operand:SI 2 "nonimmediate_operand" "")))
8375 (set (match_operand:SI 3 "register_operand" "")
8376 (mod:SI (match_dup 1) (match_dup 2)))
8377 (clobber (reg:CC FLAGS_REG))]
8379 [(parallel [(set (match_dup 3)
8380 (ashiftrt:SI (match_dup 4) (const_int 31)))
8381 (clobber (reg:CC FLAGS_REG))])
8382 (parallel [(set (match_dup 0)
8383 (div:SI (reg:SI 0) (match_dup 2)))
8385 (mod:SI (reg:SI 0) (match_dup 2)))
8387 (clobber (reg:CC FLAGS_REG))])]
8389 /* Avoid use of cltd in favor of a mov+shift. */
8390 if (!TARGET_USE_CLTD && !optimize_size)
8392 if (true_regnum (operands[1]))
8393 emit_move_insn (operands[0], operands[1]);
8395 emit_move_insn (operands[3], operands[1]);
8396 operands[4] = operands[3];
8400 gcc_assert (!true_regnum (operands[1]));
8401 operands[4] = operands[1];
8405 (define_insn "divmodhi4"
8406 [(set (match_operand:HI 0 "register_operand" "=a")
8407 (div:HI (match_operand:HI 1 "register_operand" "0")
8408 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8409 (set (match_operand:HI 3 "register_operand" "=&d")
8410 (mod:HI (match_dup 1) (match_dup 2)))
8411 (clobber (reg:CC FLAGS_REG))]
8412 "TARGET_HIMODE_MATH"
8414 [(set_attr "type" "multi")
8415 (set_attr "length_immediate" "0")
8416 (set_attr "mode" "SI")])
8418 (define_insn "udivmoddi4"
8419 [(set (match_operand:DI 0 "register_operand" "=a")
8420 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8421 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8422 (set (match_operand:DI 3 "register_operand" "=&d")
8423 (umod:DI (match_dup 1) (match_dup 2)))
8424 (clobber (reg:CC FLAGS_REG))]
8426 "xor{q}\t%3, %3\;div{q}\t%2"
8427 [(set_attr "type" "multi")
8428 (set_attr "length_immediate" "0")
8429 (set_attr "mode" "DI")])
8431 (define_insn "*udivmoddi4_noext"
8432 [(set (match_operand:DI 0 "register_operand" "=a")
8433 (udiv:DI (match_operand:DI 1 "register_operand" "0")
8434 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8435 (set (match_operand:DI 3 "register_operand" "=d")
8436 (umod:DI (match_dup 1) (match_dup 2)))
8438 (clobber (reg:CC FLAGS_REG))]
8441 [(set_attr "type" "idiv")
8442 (set_attr "mode" "DI")])
8445 [(set (match_operand:DI 0 "register_operand" "")
8446 (udiv:DI (match_operand:DI 1 "register_operand" "")
8447 (match_operand:DI 2 "nonimmediate_operand" "")))
8448 (set (match_operand:DI 3 "register_operand" "")
8449 (umod:DI (match_dup 1) (match_dup 2)))
8450 (clobber (reg:CC FLAGS_REG))]
8451 "TARGET_64BIT && reload_completed"
8452 [(set (match_dup 3) (const_int 0))
8453 (parallel [(set (match_dup 0)
8454 (udiv:DI (match_dup 1) (match_dup 2)))
8456 (umod:DI (match_dup 1) (match_dup 2)))
8458 (clobber (reg:CC FLAGS_REG))])]
8461 (define_insn "udivmodsi4"
8462 [(set (match_operand:SI 0 "register_operand" "=a")
8463 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8464 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8465 (set (match_operand:SI 3 "register_operand" "=&d")
8466 (umod:SI (match_dup 1) (match_dup 2)))
8467 (clobber (reg:CC FLAGS_REG))]
8469 "xor{l}\t%3, %3\;div{l}\t%2"
8470 [(set_attr "type" "multi")
8471 (set_attr "length_immediate" "0")
8472 (set_attr "mode" "SI")])
8474 (define_insn "*udivmodsi4_noext"
8475 [(set (match_operand:SI 0 "register_operand" "=a")
8476 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8477 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8478 (set (match_operand:SI 3 "register_operand" "=d")
8479 (umod:SI (match_dup 1) (match_dup 2)))
8481 (clobber (reg:CC FLAGS_REG))]
8484 [(set_attr "type" "idiv")
8485 (set_attr "mode" "SI")])
8488 [(set (match_operand:SI 0 "register_operand" "")
8489 (udiv:SI (match_operand:SI 1 "register_operand" "")
8490 (match_operand:SI 2 "nonimmediate_operand" "")))
8491 (set (match_operand:SI 3 "register_operand" "")
8492 (umod:SI (match_dup 1) (match_dup 2)))
8493 (clobber (reg:CC FLAGS_REG))]
8495 [(set (match_dup 3) (const_int 0))
8496 (parallel [(set (match_dup 0)
8497 (udiv:SI (match_dup 1) (match_dup 2)))
8499 (umod:SI (match_dup 1) (match_dup 2)))
8501 (clobber (reg:CC FLAGS_REG))])]
8504 (define_expand "udivmodhi4"
8505 [(set (match_dup 4) (const_int 0))
8506 (parallel [(set (match_operand:HI 0 "register_operand" "")
8507 (udiv:HI (match_operand:HI 1 "register_operand" "")
8508 (match_operand:HI 2 "nonimmediate_operand" "")))
8509 (set (match_operand:HI 3 "register_operand" "")
8510 (umod:HI (match_dup 1) (match_dup 2)))
8512 (clobber (reg:CC FLAGS_REG))])]
8513 "TARGET_HIMODE_MATH"
8514 "operands[4] = gen_reg_rtx (HImode);")
8516 (define_insn "*udivmodhi_noext"
8517 [(set (match_operand:HI 0 "register_operand" "=a")
8518 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8519 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8520 (set (match_operand:HI 3 "register_operand" "=d")
8521 (umod:HI (match_dup 1) (match_dup 2)))
8522 (use (match_operand:HI 4 "register_operand" "3"))
8523 (clobber (reg:CC FLAGS_REG))]
8526 [(set_attr "type" "idiv")
8527 (set_attr "mode" "HI")])
8529 ;; We cannot use div/idiv for double division, because it causes
8530 ;; "division by zero" on the overflow and that's not what we expect
8531 ;; from truncate. Because true (non truncating) double division is
8532 ;; never generated, we can't create this insn anyway.
8535 ; [(set (match_operand:SI 0 "register_operand" "=a")
8537 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8539 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8540 ; (set (match_operand:SI 3 "register_operand" "=d")
8542 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8543 ; (clobber (reg:CC FLAGS_REG))]
8545 ; "div{l}\t{%2, %0|%0, %2}"
8546 ; [(set_attr "type" "idiv")])
8548 ;;- Logical AND instructions
8550 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8551 ;; Note that this excludes ah.
8553 (define_insn "*testdi_1_rex64"
8554 [(set (reg FLAGS_REG)
8556 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8557 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8559 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8560 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8562 test{l}\t{%k1, %k0|%k0, %k1}
8563 test{l}\t{%k1, %k0|%k0, %k1}
8564 test{q}\t{%1, %0|%0, %1}
8565 test{q}\t{%1, %0|%0, %1}
8566 test{q}\t{%1, %0|%0, %1}"
8567 [(set_attr "type" "test")
8568 (set_attr "modrm" "0,1,0,1,1")
8569 (set_attr "mode" "SI,SI,DI,DI,DI")
8570 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8572 (define_insn "testsi_1"
8573 [(set (reg FLAGS_REG)
8575 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8576 (match_operand:SI 1 "general_operand" "in,in,rin"))
8578 "ix86_match_ccmode (insn, CCNOmode)
8579 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8580 "test{l}\t{%1, %0|%0, %1}"
8581 [(set_attr "type" "test")
8582 (set_attr "modrm" "0,1,1")
8583 (set_attr "mode" "SI")
8584 (set_attr "pent_pair" "uv,np,uv")])
8586 (define_expand "testsi_ccno_1"
8587 [(set (reg:CCNO FLAGS_REG)
8589 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8590 (match_operand:SI 1 "nonmemory_operand" ""))
8595 (define_insn "*testhi_1"
8596 [(set (reg FLAGS_REG)
8597 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8598 (match_operand:HI 1 "general_operand" "n,n,rn"))
8600 "ix86_match_ccmode (insn, CCNOmode)
8601 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8602 "test{w}\t{%1, %0|%0, %1}"
8603 [(set_attr "type" "test")
8604 (set_attr "modrm" "0,1,1")
8605 (set_attr "mode" "HI")
8606 (set_attr "pent_pair" "uv,np,uv")])
8608 (define_expand "testqi_ccz_1"
8609 [(set (reg:CCZ FLAGS_REG)
8610 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8611 (match_operand:QI 1 "nonmemory_operand" ""))
8616 (define_insn "*testqi_1_maybe_si"
8617 [(set (reg FLAGS_REG)
8620 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8621 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8623 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8624 && ix86_match_ccmode (insn,
8625 CONST_INT_P (operands[1])
8626 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8628 if (which_alternative == 3)
8630 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8631 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8632 return "test{l}\t{%1, %k0|%k0, %1}";
8634 return "test{b}\t{%1, %0|%0, %1}";
8636 [(set_attr "type" "test")
8637 (set_attr "modrm" "0,1,1,1")
8638 (set_attr "mode" "QI,QI,QI,SI")
8639 (set_attr "pent_pair" "uv,np,uv,np")])
8641 (define_insn "*testqi_1"
8642 [(set (reg FLAGS_REG)
8645 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8646 (match_operand:QI 1 "general_operand" "n,n,qn"))
8648 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8649 && ix86_match_ccmode (insn, CCNOmode)"
8650 "test{b}\t{%1, %0|%0, %1}"
8651 [(set_attr "type" "test")
8652 (set_attr "modrm" "0,1,1")
8653 (set_attr "mode" "QI")
8654 (set_attr "pent_pair" "uv,np,uv")])
8656 (define_expand "testqi_ext_ccno_0"
8657 [(set (reg:CCNO FLAGS_REG)
8661 (match_operand 0 "ext_register_operand" "")
8664 (match_operand 1 "const_int_operand" ""))
8669 (define_insn "*testqi_ext_0"
8670 [(set (reg FLAGS_REG)
8674 (match_operand 0 "ext_register_operand" "Q")
8677 (match_operand 1 "const_int_operand" "n"))
8679 "ix86_match_ccmode (insn, CCNOmode)"
8680 "test{b}\t{%1, %h0|%h0, %1}"
8681 [(set_attr "type" "test")
8682 (set_attr "mode" "QI")
8683 (set_attr "length_immediate" "1")
8684 (set_attr "pent_pair" "np")])
8686 (define_insn "*testqi_ext_1"
8687 [(set (reg FLAGS_REG)
8691 (match_operand 0 "ext_register_operand" "Q")
8695 (match_operand:QI 1 "general_operand" "Qm")))
8697 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8698 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8699 "test{b}\t{%1, %h0|%h0, %1}"
8700 [(set_attr "type" "test")
8701 (set_attr "mode" "QI")])
8703 (define_insn "*testqi_ext_1_rex64"
8704 [(set (reg FLAGS_REG)
8708 (match_operand 0 "ext_register_operand" "Q")
8712 (match_operand:QI 1 "register_operand" "Q")))
8714 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8715 "test{b}\t{%1, %h0|%h0, %1}"
8716 [(set_attr "type" "test")
8717 (set_attr "mode" "QI")])
8719 (define_insn "*testqi_ext_2"
8720 [(set (reg FLAGS_REG)
8724 (match_operand 0 "ext_register_operand" "Q")
8728 (match_operand 1 "ext_register_operand" "Q")
8732 "ix86_match_ccmode (insn, CCNOmode)"
8733 "test{b}\t{%h1, %h0|%h0, %h1}"
8734 [(set_attr "type" "test")
8735 (set_attr "mode" "QI")])
8737 ;; Combine likes to form bit extractions for some tests. Humor it.
8738 (define_insn "*testqi_ext_3"
8739 [(set (reg FLAGS_REG)
8740 (compare (zero_extract:SI
8741 (match_operand 0 "nonimmediate_operand" "rm")
8742 (match_operand:SI 1 "const_int_operand" "")
8743 (match_operand:SI 2 "const_int_operand" ""))
8745 "ix86_match_ccmode (insn, CCNOmode)
8746 && INTVAL (operands[1]) > 0
8747 && INTVAL (operands[2]) >= 0
8748 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8749 && (GET_MODE (operands[0]) == SImode
8750 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8751 || GET_MODE (operands[0]) == HImode
8752 || GET_MODE (operands[0]) == QImode)"
8755 (define_insn "*testqi_ext_3_rex64"
8756 [(set (reg FLAGS_REG)
8757 (compare (zero_extract:DI
8758 (match_operand 0 "nonimmediate_operand" "rm")
8759 (match_operand:DI 1 "const_int_operand" "")
8760 (match_operand:DI 2 "const_int_operand" ""))
8763 && ix86_match_ccmode (insn, CCNOmode)
8764 && INTVAL (operands[1]) > 0
8765 && INTVAL (operands[2]) >= 0
8766 /* Ensure that resulting mask is zero or sign extended operand. */
8767 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8768 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8769 && INTVAL (operands[1]) > 32))
8770 && (GET_MODE (operands[0]) == SImode
8771 || GET_MODE (operands[0]) == DImode
8772 || GET_MODE (operands[0]) == HImode
8773 || GET_MODE (operands[0]) == QImode)"
8777 [(set (match_operand 0 "flags_reg_operand" "")
8778 (match_operator 1 "compare_operator"
8780 (match_operand 2 "nonimmediate_operand" "")
8781 (match_operand 3 "const_int_operand" "")
8782 (match_operand 4 "const_int_operand" ""))
8784 "ix86_match_ccmode (insn, CCNOmode)"
8785 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8787 rtx val = operands[2];
8788 HOST_WIDE_INT len = INTVAL (operands[3]);
8789 HOST_WIDE_INT pos = INTVAL (operands[4]);
8791 enum machine_mode mode, submode;
8793 mode = GET_MODE (val);
8796 /* ??? Combine likes to put non-volatile mem extractions in QImode
8797 no matter the size of the test. So find a mode that works. */
8798 if (! MEM_VOLATILE_P (val))
8800 mode = smallest_mode_for_size (pos + len, MODE_INT);
8801 val = adjust_address (val, mode, 0);
8804 else if (GET_CODE (val) == SUBREG
8805 && (submode = GET_MODE (SUBREG_REG (val)),
8806 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8807 && pos + len <= GET_MODE_BITSIZE (submode))
8809 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8811 val = SUBREG_REG (val);
8813 else if (mode == HImode && pos + len <= 8)
8815 /* Small HImode tests can be converted to QImode. */
8817 val = gen_lowpart (QImode, val);
8820 if (len == HOST_BITS_PER_WIDE_INT)
8823 mask = ((HOST_WIDE_INT)1 << len) - 1;
8826 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8829 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8830 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8831 ;; this is relatively important trick.
8832 ;; Do the conversion only post-reload to avoid limiting of the register class
8835 [(set (match_operand 0 "flags_reg_operand" "")
8836 (match_operator 1 "compare_operator"
8837 [(and (match_operand 2 "register_operand" "")
8838 (match_operand 3 "const_int_operand" ""))
8841 && QI_REG_P (operands[2])
8842 && GET_MODE (operands[2]) != QImode
8843 && ((ix86_match_ccmode (insn, CCZmode)
8844 && !(INTVAL (operands[3]) & ~(255 << 8)))
8845 || (ix86_match_ccmode (insn, CCNOmode)
8846 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8849 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8852 "operands[2] = gen_lowpart (SImode, operands[2]);
8853 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8856 [(set (match_operand 0 "flags_reg_operand" "")
8857 (match_operator 1 "compare_operator"
8858 [(and (match_operand 2 "nonimmediate_operand" "")
8859 (match_operand 3 "const_int_operand" ""))
8862 && GET_MODE (operands[2]) != QImode
8863 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8864 && ((ix86_match_ccmode (insn, CCZmode)
8865 && !(INTVAL (operands[3]) & ~255))
8866 || (ix86_match_ccmode (insn, CCNOmode)
8867 && !(INTVAL (operands[3]) & ~127)))"
8869 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8871 "operands[2] = gen_lowpart (QImode, operands[2]);
8872 operands[3] = gen_lowpart (QImode, operands[3]);")
8875 ;; %%% This used to optimize known byte-wide and operations to memory,
8876 ;; and sometimes to QImode registers. If this is considered useful,
8877 ;; it should be done with splitters.
8879 (define_expand "anddi3"
8880 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8881 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8882 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8883 (clobber (reg:CC FLAGS_REG))]
8885 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8887 (define_insn "*anddi_1_rex64"
8888 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8889 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8890 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8891 (clobber (reg:CC FLAGS_REG))]
8892 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8894 switch (get_attr_type (insn))
8898 enum machine_mode mode;
8900 gcc_assert (CONST_INT_P (operands[2]));
8901 if (INTVAL (operands[2]) == 0xff)
8905 gcc_assert (INTVAL (operands[2]) == 0xffff);
8909 operands[1] = gen_lowpart (mode, operands[1]);
8911 return "movz{bq|x}\t{%1,%0|%0, %1}";
8913 return "movz{wq|x}\t{%1,%0|%0, %1}";
8917 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8918 if (get_attr_mode (insn) == MODE_SI)
8919 return "and{l}\t{%k2, %k0|%k0, %k2}";
8921 return "and{q}\t{%2, %0|%0, %2}";
8924 [(set_attr "type" "alu,alu,alu,imovx")
8925 (set_attr "length_immediate" "*,*,*,0")
8926 (set_attr "mode" "SI,DI,DI,DI")])
8928 (define_insn "*anddi_2"
8929 [(set (reg FLAGS_REG)
8930 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8931 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8933 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8934 (and:DI (match_dup 1) (match_dup 2)))]
8935 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8936 && ix86_binary_operator_ok (AND, DImode, operands)"
8938 and{l}\t{%k2, %k0|%k0, %k2}
8939 and{q}\t{%2, %0|%0, %2}
8940 and{q}\t{%2, %0|%0, %2}"
8941 [(set_attr "type" "alu")
8942 (set_attr "mode" "SI,DI,DI")])
8944 (define_expand "andsi3"
8945 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8946 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8947 (match_operand:SI 2 "general_operand" "")))
8948 (clobber (reg:CC FLAGS_REG))]
8950 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8952 (define_insn "*andsi_1"
8953 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8954 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8955 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8956 (clobber (reg:CC FLAGS_REG))]
8957 "ix86_binary_operator_ok (AND, SImode, operands)"
8959 switch (get_attr_type (insn))
8963 enum machine_mode mode;
8965 gcc_assert (CONST_INT_P (operands[2]));
8966 if (INTVAL (operands[2]) == 0xff)
8970 gcc_assert (INTVAL (operands[2]) == 0xffff);
8974 operands[1] = gen_lowpart (mode, operands[1]);
8976 return "movz{bl|x}\t{%1,%0|%0, %1}";
8978 return "movz{wl|x}\t{%1,%0|%0, %1}";
8982 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8983 return "and{l}\t{%2, %0|%0, %2}";
8986 [(set_attr "type" "alu,alu,imovx")
8987 (set_attr "length_immediate" "*,*,0")
8988 (set_attr "mode" "SI")])
8991 [(set (match_operand 0 "register_operand" "")
8993 (const_int -65536)))
8994 (clobber (reg:CC FLAGS_REG))]
8995 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8996 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8997 "operands[1] = gen_lowpart (HImode, operands[0]);")
9000 [(set (match_operand 0 "ext_register_operand" "")
9003 (clobber (reg:CC FLAGS_REG))]
9004 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9005 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9006 "operands[1] = gen_lowpart (QImode, operands[0]);")
9009 [(set (match_operand 0 "ext_register_operand" "")
9011 (const_int -65281)))
9012 (clobber (reg:CC FLAGS_REG))]
9013 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9014 [(parallel [(set (zero_extract:SI (match_dup 0)
9018 (zero_extract:SI (match_dup 0)
9021 (zero_extract:SI (match_dup 0)
9024 (clobber (reg:CC FLAGS_REG))])]
9025 "operands[0] = gen_lowpart (SImode, operands[0]);")
9027 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9028 (define_insn "*andsi_1_zext"
9029 [(set (match_operand:DI 0 "register_operand" "=r")
9031 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9032 (match_operand:SI 2 "general_operand" "g"))))
9033 (clobber (reg:CC FLAGS_REG))]
9034 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9035 "and{l}\t{%2, %k0|%k0, %2}"
9036 [(set_attr "type" "alu")
9037 (set_attr "mode" "SI")])
9039 (define_insn "*andsi_2"
9040 [(set (reg FLAGS_REG)
9041 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9042 (match_operand:SI 2 "general_operand" "g,ri"))
9044 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9045 (and:SI (match_dup 1) (match_dup 2)))]
9046 "ix86_match_ccmode (insn, CCNOmode)
9047 && ix86_binary_operator_ok (AND, SImode, operands)"
9048 "and{l}\t{%2, %0|%0, %2}"
9049 [(set_attr "type" "alu")
9050 (set_attr "mode" "SI")])
9052 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9053 (define_insn "*andsi_2_zext"
9054 [(set (reg FLAGS_REG)
9055 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9056 (match_operand:SI 2 "general_operand" "g"))
9058 (set (match_operand:DI 0 "register_operand" "=r")
9059 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9060 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9061 && ix86_binary_operator_ok (AND, SImode, operands)"
9062 "and{l}\t{%2, %k0|%k0, %2}"
9063 [(set_attr "type" "alu")
9064 (set_attr "mode" "SI")])
9066 (define_expand "andhi3"
9067 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9068 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9069 (match_operand:HI 2 "general_operand" "")))
9070 (clobber (reg:CC FLAGS_REG))]
9071 "TARGET_HIMODE_MATH"
9072 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9074 (define_insn "*andhi_1"
9075 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9076 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9077 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9078 (clobber (reg:CC FLAGS_REG))]
9079 "ix86_binary_operator_ok (AND, HImode, operands)"
9081 switch (get_attr_type (insn))
9084 gcc_assert (CONST_INT_P (operands[2]));
9085 gcc_assert (INTVAL (operands[2]) == 0xff);
9086 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9089 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9091 return "and{w}\t{%2, %0|%0, %2}";
9094 [(set_attr "type" "alu,alu,imovx")
9095 (set_attr "length_immediate" "*,*,0")
9096 (set_attr "mode" "HI,HI,SI")])
9098 (define_insn "*andhi_2"
9099 [(set (reg FLAGS_REG)
9100 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9101 (match_operand:HI 2 "general_operand" "g,ri"))
9103 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9104 (and:HI (match_dup 1) (match_dup 2)))]
9105 "ix86_match_ccmode (insn, CCNOmode)
9106 && ix86_binary_operator_ok (AND, HImode, operands)"
9107 "and{w}\t{%2, %0|%0, %2}"
9108 [(set_attr "type" "alu")
9109 (set_attr "mode" "HI")])
9111 (define_expand "andqi3"
9112 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9113 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9114 (match_operand:QI 2 "general_operand" "")))
9115 (clobber (reg:CC FLAGS_REG))]
9116 "TARGET_QIMODE_MATH"
9117 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9119 ;; %%% Potential partial reg stall on alternative 2. What to do?
9120 (define_insn "*andqi_1"
9121 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9122 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9123 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9124 (clobber (reg:CC FLAGS_REG))]
9125 "ix86_binary_operator_ok (AND, QImode, operands)"
9127 and{b}\t{%2, %0|%0, %2}
9128 and{b}\t{%2, %0|%0, %2}
9129 and{l}\t{%k2, %k0|%k0, %k2}"
9130 [(set_attr "type" "alu")
9131 (set_attr "mode" "QI,QI,SI")])
9133 (define_insn "*andqi_1_slp"
9134 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9135 (and:QI (match_dup 0)
9136 (match_operand:QI 1 "general_operand" "qi,qmi")))
9137 (clobber (reg:CC FLAGS_REG))]
9138 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9139 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9140 "and{b}\t{%1, %0|%0, %1}"
9141 [(set_attr "type" "alu1")
9142 (set_attr "mode" "QI")])
9144 (define_insn "*andqi_2_maybe_si"
9145 [(set (reg FLAGS_REG)
9147 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9148 (match_operand:QI 2 "general_operand" "qim,qi,i"))
9150 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9151 (and:QI (match_dup 1) (match_dup 2)))]
9152 "ix86_binary_operator_ok (AND, QImode, operands)
9153 && ix86_match_ccmode (insn,
9154 CONST_INT_P (operands[2])
9155 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9157 if (which_alternative == 2)
9159 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9160 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9161 return "and{l}\t{%2, %k0|%k0, %2}";
9163 return "and{b}\t{%2, %0|%0, %2}";
9165 [(set_attr "type" "alu")
9166 (set_attr "mode" "QI,QI,SI")])
9168 (define_insn "*andqi_2"
9169 [(set (reg FLAGS_REG)
9171 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9172 (match_operand:QI 2 "general_operand" "qim,qi"))
9174 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9175 (and:QI (match_dup 1) (match_dup 2)))]
9176 "ix86_match_ccmode (insn, CCNOmode)
9177 && ix86_binary_operator_ok (AND, QImode, operands)"
9178 "and{b}\t{%2, %0|%0, %2}"
9179 [(set_attr "type" "alu")
9180 (set_attr "mode" "QI")])
9182 (define_insn "*andqi_2_slp"
9183 [(set (reg FLAGS_REG)
9185 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9186 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9188 (set (strict_low_part (match_dup 0))
9189 (and:QI (match_dup 0) (match_dup 1)))]
9190 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9191 && ix86_match_ccmode (insn, CCNOmode)
9192 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9193 "and{b}\t{%1, %0|%0, %1}"
9194 [(set_attr "type" "alu1")
9195 (set_attr "mode" "QI")])
9197 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9198 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9199 ;; for a QImode operand, which of course failed.
9201 (define_insn "andqi_ext_0"
9202 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9207 (match_operand 1 "ext_register_operand" "0")
9210 (match_operand 2 "const_int_operand" "n")))
9211 (clobber (reg:CC FLAGS_REG))]
9213 "and{b}\t{%2, %h0|%h0, %2}"
9214 [(set_attr "type" "alu")
9215 (set_attr "length_immediate" "1")
9216 (set_attr "mode" "QI")])
9218 ;; Generated by peephole translating test to and. This shows up
9219 ;; often in fp comparisons.
9221 (define_insn "*andqi_ext_0_cc"
9222 [(set (reg FLAGS_REG)
9226 (match_operand 1 "ext_register_operand" "0")
9229 (match_operand 2 "const_int_operand" "n"))
9231 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9240 "ix86_match_ccmode (insn, CCNOmode)"
9241 "and{b}\t{%2, %h0|%h0, %2}"
9242 [(set_attr "type" "alu")
9243 (set_attr "length_immediate" "1")
9244 (set_attr "mode" "QI")])
9246 (define_insn "*andqi_ext_1"
9247 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9252 (match_operand 1 "ext_register_operand" "0")
9256 (match_operand:QI 2 "general_operand" "Qm"))))
9257 (clobber (reg:CC FLAGS_REG))]
9259 "and{b}\t{%2, %h0|%h0, %2}"
9260 [(set_attr "type" "alu")
9261 (set_attr "length_immediate" "0")
9262 (set_attr "mode" "QI")])
9264 (define_insn "*andqi_ext_1_rex64"
9265 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9270 (match_operand 1 "ext_register_operand" "0")
9274 (match_operand 2 "ext_register_operand" "Q"))))
9275 (clobber (reg:CC FLAGS_REG))]
9277 "and{b}\t{%2, %h0|%h0, %2}"
9278 [(set_attr "type" "alu")
9279 (set_attr "length_immediate" "0")
9280 (set_attr "mode" "QI")])
9282 (define_insn "*andqi_ext_2"
9283 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9288 (match_operand 1 "ext_register_operand" "%0")
9292 (match_operand 2 "ext_register_operand" "Q")
9295 (clobber (reg:CC FLAGS_REG))]
9297 "and{b}\t{%h2, %h0|%h0, %h2}"
9298 [(set_attr "type" "alu")
9299 (set_attr "length_immediate" "0")
9300 (set_attr "mode" "QI")])
9302 ;; Convert wide AND instructions with immediate operand to shorter QImode
9303 ;; equivalents when possible.
9304 ;; Don't do the splitting with memory operands, since it introduces risk
9305 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9306 ;; for size, but that can (should?) be handled by generic code instead.
9308 [(set (match_operand 0 "register_operand" "")
9309 (and (match_operand 1 "register_operand" "")
9310 (match_operand 2 "const_int_operand" "")))
9311 (clobber (reg:CC FLAGS_REG))]
9313 && QI_REG_P (operands[0])
9314 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9315 && !(~INTVAL (operands[2]) & ~(255 << 8))
9316 && GET_MODE (operands[0]) != QImode"
9317 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9318 (and:SI (zero_extract:SI (match_dup 1)
9319 (const_int 8) (const_int 8))
9321 (clobber (reg:CC FLAGS_REG))])]
9322 "operands[0] = gen_lowpart (SImode, operands[0]);
9323 operands[1] = gen_lowpart (SImode, operands[1]);
9324 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9326 ;; Since AND can be encoded with sign extended immediate, this is only
9327 ;; profitable when 7th bit is not set.
9329 [(set (match_operand 0 "register_operand" "")
9330 (and (match_operand 1 "general_operand" "")
9331 (match_operand 2 "const_int_operand" "")))
9332 (clobber (reg:CC FLAGS_REG))]
9334 && ANY_QI_REG_P (operands[0])
9335 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9336 && !(~INTVAL (operands[2]) & ~255)
9337 && !(INTVAL (operands[2]) & 128)
9338 && GET_MODE (operands[0]) != QImode"
9339 [(parallel [(set (strict_low_part (match_dup 0))
9340 (and:QI (match_dup 1)
9342 (clobber (reg:CC FLAGS_REG))])]
9343 "operands[0] = gen_lowpart (QImode, operands[0]);
9344 operands[1] = gen_lowpart (QImode, operands[1]);
9345 operands[2] = gen_lowpart (QImode, operands[2]);")
9347 ;; Logical inclusive OR instructions
9349 ;; %%% This used to optimize known byte-wide and operations to memory.
9350 ;; If this is considered useful, it should be done with splitters.
9352 (define_expand "iordi3"
9353 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9354 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9355 (match_operand:DI 2 "x86_64_general_operand" "")))
9356 (clobber (reg:CC FLAGS_REG))]
9358 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9360 (define_insn "*iordi_1_rex64"
9361 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9362 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9363 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9364 (clobber (reg:CC FLAGS_REG))]
9366 && ix86_binary_operator_ok (IOR, DImode, operands)"
9367 "or{q}\t{%2, %0|%0, %2}"
9368 [(set_attr "type" "alu")
9369 (set_attr "mode" "DI")])
9371 (define_insn "*iordi_2_rex64"
9372 [(set (reg FLAGS_REG)
9373 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9374 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9376 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9377 (ior:DI (match_dup 1) (match_dup 2)))]
9379 && ix86_match_ccmode (insn, CCNOmode)
9380 && ix86_binary_operator_ok (IOR, DImode, operands)"
9381 "or{q}\t{%2, %0|%0, %2}"
9382 [(set_attr "type" "alu")
9383 (set_attr "mode" "DI")])
9385 (define_insn "*iordi_3_rex64"
9386 [(set (reg FLAGS_REG)
9387 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9388 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9390 (clobber (match_scratch:DI 0 "=r"))]
9392 && ix86_match_ccmode (insn, CCNOmode)
9393 && ix86_binary_operator_ok (IOR, DImode, operands)"
9394 "or{q}\t{%2, %0|%0, %2}"
9395 [(set_attr "type" "alu")
9396 (set_attr "mode" "DI")])
9399 (define_expand "iorsi3"
9400 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9401 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9402 (match_operand:SI 2 "general_operand" "")))
9403 (clobber (reg:CC FLAGS_REG))]
9405 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9407 (define_insn "*iorsi_1"
9408 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9409 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9410 (match_operand:SI 2 "general_operand" "ri,g")))
9411 (clobber (reg:CC FLAGS_REG))]
9412 "ix86_binary_operator_ok (IOR, SImode, operands)"
9413 "or{l}\t{%2, %0|%0, %2}"
9414 [(set_attr "type" "alu")
9415 (set_attr "mode" "SI")])
9417 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9418 (define_insn "*iorsi_1_zext"
9419 [(set (match_operand:DI 0 "register_operand" "=r")
9421 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9422 (match_operand:SI 2 "general_operand" "g"))))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9425 "or{l}\t{%2, %k0|%k0, %2}"
9426 [(set_attr "type" "alu")
9427 (set_attr "mode" "SI")])
9429 (define_insn "*iorsi_1_zext_imm"
9430 [(set (match_operand:DI 0 "register_operand" "=r")
9431 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9432 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9433 (clobber (reg:CC FLAGS_REG))]
9435 "or{l}\t{%2, %k0|%k0, %2}"
9436 [(set_attr "type" "alu")
9437 (set_attr "mode" "SI")])
9439 (define_insn "*iorsi_2"
9440 [(set (reg FLAGS_REG)
9441 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9442 (match_operand:SI 2 "general_operand" "g,ri"))
9444 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9445 (ior:SI (match_dup 1) (match_dup 2)))]
9446 "ix86_match_ccmode (insn, CCNOmode)
9447 && ix86_binary_operator_ok (IOR, SImode, operands)"
9448 "or{l}\t{%2, %0|%0, %2}"
9449 [(set_attr "type" "alu")
9450 (set_attr "mode" "SI")])
9452 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9453 ;; ??? Special case for immediate operand is missing - it is tricky.
9454 (define_insn "*iorsi_2_zext"
9455 [(set (reg FLAGS_REG)
9456 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9457 (match_operand:SI 2 "general_operand" "g"))
9459 (set (match_operand:DI 0 "register_operand" "=r")
9460 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9461 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9462 && ix86_binary_operator_ok (IOR, SImode, operands)"
9463 "or{l}\t{%2, %k0|%k0, %2}"
9464 [(set_attr "type" "alu")
9465 (set_attr "mode" "SI")])
9467 (define_insn "*iorsi_2_zext_imm"
9468 [(set (reg FLAGS_REG)
9469 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9470 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9472 (set (match_operand:DI 0 "register_operand" "=r")
9473 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9474 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9475 && ix86_binary_operator_ok (IOR, SImode, operands)"
9476 "or{l}\t{%2, %k0|%k0, %2}"
9477 [(set_attr "type" "alu")
9478 (set_attr "mode" "SI")])
9480 (define_insn "*iorsi_3"
9481 [(set (reg FLAGS_REG)
9482 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9483 (match_operand:SI 2 "general_operand" "g"))
9485 (clobber (match_scratch:SI 0 "=r"))]
9486 "ix86_match_ccmode (insn, CCNOmode)
9487 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9488 "or{l}\t{%2, %0|%0, %2}"
9489 [(set_attr "type" "alu")
9490 (set_attr "mode" "SI")])
9492 (define_expand "iorhi3"
9493 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9494 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9495 (match_operand:HI 2 "general_operand" "")))
9496 (clobber (reg:CC FLAGS_REG))]
9497 "TARGET_HIMODE_MATH"
9498 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9500 (define_insn "*iorhi_1"
9501 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9502 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9503 (match_operand:HI 2 "general_operand" "g,ri")))
9504 (clobber (reg:CC FLAGS_REG))]
9505 "ix86_binary_operator_ok (IOR, HImode, operands)"
9506 "or{w}\t{%2, %0|%0, %2}"
9507 [(set_attr "type" "alu")
9508 (set_attr "mode" "HI")])
9510 (define_insn "*iorhi_2"
9511 [(set (reg FLAGS_REG)
9512 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9513 (match_operand:HI 2 "general_operand" "g,ri"))
9515 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9516 (ior:HI (match_dup 1) (match_dup 2)))]
9517 "ix86_match_ccmode (insn, CCNOmode)
9518 && ix86_binary_operator_ok (IOR, HImode, operands)"
9519 "or{w}\t{%2, %0|%0, %2}"
9520 [(set_attr "type" "alu")
9521 (set_attr "mode" "HI")])
9523 (define_insn "*iorhi_3"
9524 [(set (reg FLAGS_REG)
9525 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9526 (match_operand:HI 2 "general_operand" "g"))
9528 (clobber (match_scratch:HI 0 "=r"))]
9529 "ix86_match_ccmode (insn, CCNOmode)
9530 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9531 "or{w}\t{%2, %0|%0, %2}"
9532 [(set_attr "type" "alu")
9533 (set_attr "mode" "HI")])
9535 (define_expand "iorqi3"
9536 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9537 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9538 (match_operand:QI 2 "general_operand" "")))
9539 (clobber (reg:CC FLAGS_REG))]
9540 "TARGET_QIMODE_MATH"
9541 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9543 ;; %%% Potential partial reg stall on alternative 2. What to do?
9544 (define_insn "*iorqi_1"
9545 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9546 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9547 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9548 (clobber (reg:CC FLAGS_REG))]
9549 "ix86_binary_operator_ok (IOR, QImode, operands)"
9551 or{b}\t{%2, %0|%0, %2}
9552 or{b}\t{%2, %0|%0, %2}
9553 or{l}\t{%k2, %k0|%k0, %k2}"
9554 [(set_attr "type" "alu")
9555 (set_attr "mode" "QI,QI,SI")])
9557 (define_insn "*iorqi_1_slp"
9558 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9559 (ior:QI (match_dup 0)
9560 (match_operand:QI 1 "general_operand" "qmi,qi")))
9561 (clobber (reg:CC FLAGS_REG))]
9562 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9563 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9564 "or{b}\t{%1, %0|%0, %1}"
9565 [(set_attr "type" "alu1")
9566 (set_attr "mode" "QI")])
9568 (define_insn "*iorqi_2"
9569 [(set (reg FLAGS_REG)
9570 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9571 (match_operand:QI 2 "general_operand" "qim,qi"))
9573 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9574 (ior:QI (match_dup 1) (match_dup 2)))]
9575 "ix86_match_ccmode (insn, CCNOmode)
9576 && ix86_binary_operator_ok (IOR, QImode, operands)"
9577 "or{b}\t{%2, %0|%0, %2}"
9578 [(set_attr "type" "alu")
9579 (set_attr "mode" "QI")])
9581 (define_insn "*iorqi_2_slp"
9582 [(set (reg FLAGS_REG)
9583 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9584 (match_operand:QI 1 "general_operand" "qim,qi"))
9586 (set (strict_low_part (match_dup 0))
9587 (ior:QI (match_dup 0) (match_dup 1)))]
9588 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9589 && ix86_match_ccmode (insn, CCNOmode)
9590 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9591 "or{b}\t{%1, %0|%0, %1}"
9592 [(set_attr "type" "alu1")
9593 (set_attr "mode" "QI")])
9595 (define_insn "*iorqi_3"
9596 [(set (reg FLAGS_REG)
9597 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9598 (match_operand:QI 2 "general_operand" "qim"))
9600 (clobber (match_scratch:QI 0 "=q"))]
9601 "ix86_match_ccmode (insn, CCNOmode)
9602 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9603 "or{b}\t{%2, %0|%0, %2}"
9604 [(set_attr "type" "alu")
9605 (set_attr "mode" "QI")])
9607 (define_insn "iorqi_ext_0"
9608 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9613 (match_operand 1 "ext_register_operand" "0")
9616 (match_operand 2 "const_int_operand" "n")))
9617 (clobber (reg:CC FLAGS_REG))]
9618 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9619 "or{b}\t{%2, %h0|%h0, %2}"
9620 [(set_attr "type" "alu")
9621 (set_attr "length_immediate" "1")
9622 (set_attr "mode" "QI")])
9624 (define_insn "*iorqi_ext_1"
9625 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9630 (match_operand 1 "ext_register_operand" "0")
9634 (match_operand:QI 2 "general_operand" "Qm"))))
9635 (clobber (reg:CC FLAGS_REG))]
9637 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9638 "or{b}\t{%2, %h0|%h0, %2}"
9639 [(set_attr "type" "alu")
9640 (set_attr "length_immediate" "0")
9641 (set_attr "mode" "QI")])
9643 (define_insn "*iorqi_ext_1_rex64"
9644 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9649 (match_operand 1 "ext_register_operand" "0")
9653 (match_operand 2 "ext_register_operand" "Q"))))
9654 (clobber (reg:CC FLAGS_REG))]
9656 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9657 "or{b}\t{%2, %h0|%h0, %2}"
9658 [(set_attr "type" "alu")
9659 (set_attr "length_immediate" "0")
9660 (set_attr "mode" "QI")])
9662 (define_insn "*iorqi_ext_2"
9663 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9667 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9670 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9673 (clobber (reg:CC FLAGS_REG))]
9674 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9675 "ior{b}\t{%h2, %h0|%h0, %h2}"
9676 [(set_attr "type" "alu")
9677 (set_attr "length_immediate" "0")
9678 (set_attr "mode" "QI")])
9681 [(set (match_operand 0 "register_operand" "")
9682 (ior (match_operand 1 "register_operand" "")
9683 (match_operand 2 "const_int_operand" "")))
9684 (clobber (reg:CC FLAGS_REG))]
9686 && QI_REG_P (operands[0])
9687 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9688 && !(INTVAL (operands[2]) & ~(255 << 8))
9689 && GET_MODE (operands[0]) != QImode"
9690 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9691 (ior:SI (zero_extract:SI (match_dup 1)
9692 (const_int 8) (const_int 8))
9694 (clobber (reg:CC FLAGS_REG))])]
9695 "operands[0] = gen_lowpart (SImode, operands[0]);
9696 operands[1] = gen_lowpart (SImode, operands[1]);
9697 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9699 ;; Since OR can be encoded with sign extended immediate, this is only
9700 ;; profitable when 7th bit is set.
9702 [(set (match_operand 0 "register_operand" "")
9703 (ior (match_operand 1 "general_operand" "")
9704 (match_operand 2 "const_int_operand" "")))
9705 (clobber (reg:CC FLAGS_REG))]
9707 && ANY_QI_REG_P (operands[0])
9708 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9709 && !(INTVAL (operands[2]) & ~255)
9710 && (INTVAL (operands[2]) & 128)
9711 && GET_MODE (operands[0]) != QImode"
9712 [(parallel [(set (strict_low_part (match_dup 0))
9713 (ior:QI (match_dup 1)
9715 (clobber (reg:CC FLAGS_REG))])]
9716 "operands[0] = gen_lowpart (QImode, operands[0]);
9717 operands[1] = gen_lowpart (QImode, operands[1]);
9718 operands[2] = gen_lowpart (QImode, operands[2]);")
9720 ;; Logical XOR instructions
9722 ;; %%% This used to optimize known byte-wide and operations to memory.
9723 ;; If this is considered useful, it should be done with splitters.
9725 (define_expand "xordi3"
9726 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9727 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9728 (match_operand:DI 2 "x86_64_general_operand" "")))
9729 (clobber (reg:CC FLAGS_REG))]
9731 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9733 (define_insn "*xordi_1_rex64"
9734 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9735 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9736 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9737 (clobber (reg:CC FLAGS_REG))]
9739 && ix86_binary_operator_ok (XOR, DImode, operands)"
9740 "xor{q}\t{%2, %0|%0, %2}"
9741 [(set_attr "type" "alu")
9742 (set_attr "mode" "DI")])
9744 (define_insn "*xordi_2_rex64"
9745 [(set (reg FLAGS_REG)
9746 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9747 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9749 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9750 (xor:DI (match_dup 1) (match_dup 2)))]
9752 && ix86_match_ccmode (insn, CCNOmode)
9753 && ix86_binary_operator_ok (XOR, DImode, operands)"
9754 "xor{q}\t{%2, %0|%0, %2}"
9755 [(set_attr "type" "alu")
9756 (set_attr "mode" "DI")])
9758 (define_insn "*xordi_3_rex64"
9759 [(set (reg FLAGS_REG)
9760 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9761 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9763 (clobber (match_scratch:DI 0 "=r"))]
9765 && ix86_match_ccmode (insn, CCNOmode)
9766 && ix86_binary_operator_ok (XOR, DImode, operands)"
9767 "xor{q}\t{%2, %0|%0, %2}"
9768 [(set_attr "type" "alu")
9769 (set_attr "mode" "DI")])
9771 (define_expand "xorsi3"
9772 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9773 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9774 (match_operand:SI 2 "general_operand" "")))
9775 (clobber (reg:CC FLAGS_REG))]
9777 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9779 (define_insn "*xorsi_1"
9780 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9781 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9782 (match_operand:SI 2 "general_operand" "ri,rm")))
9783 (clobber (reg:CC FLAGS_REG))]
9784 "ix86_binary_operator_ok (XOR, SImode, operands)"
9785 "xor{l}\t{%2, %0|%0, %2}"
9786 [(set_attr "type" "alu")
9787 (set_attr "mode" "SI")])
9789 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9790 ;; Add speccase for immediates
9791 (define_insn "*xorsi_1_zext"
9792 [(set (match_operand:DI 0 "register_operand" "=r")
9794 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9795 (match_operand:SI 2 "general_operand" "g"))))
9796 (clobber (reg:CC FLAGS_REG))]
9797 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9798 "xor{l}\t{%2, %k0|%k0, %2}"
9799 [(set_attr "type" "alu")
9800 (set_attr "mode" "SI")])
9802 (define_insn "*xorsi_1_zext_imm"
9803 [(set (match_operand:DI 0 "register_operand" "=r")
9804 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9805 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9806 (clobber (reg:CC FLAGS_REG))]
9807 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9808 "xor{l}\t{%2, %k0|%k0, %2}"
9809 [(set_attr "type" "alu")
9810 (set_attr "mode" "SI")])
9812 (define_insn "*xorsi_2"
9813 [(set (reg FLAGS_REG)
9814 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9815 (match_operand:SI 2 "general_operand" "g,ri"))
9817 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9818 (xor:SI (match_dup 1) (match_dup 2)))]
9819 "ix86_match_ccmode (insn, CCNOmode)
9820 && ix86_binary_operator_ok (XOR, SImode, operands)"
9821 "xor{l}\t{%2, %0|%0, %2}"
9822 [(set_attr "type" "alu")
9823 (set_attr "mode" "SI")])
9825 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9826 ;; ??? Special case for immediate operand is missing - it is tricky.
9827 (define_insn "*xorsi_2_zext"
9828 [(set (reg FLAGS_REG)
9829 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9830 (match_operand:SI 2 "general_operand" "g"))
9832 (set (match_operand:DI 0 "register_operand" "=r")
9833 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9834 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9835 && ix86_binary_operator_ok (XOR, SImode, operands)"
9836 "xor{l}\t{%2, %k0|%k0, %2}"
9837 [(set_attr "type" "alu")
9838 (set_attr "mode" "SI")])
9840 (define_insn "*xorsi_2_zext_imm"
9841 [(set (reg FLAGS_REG)
9842 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9843 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9845 (set (match_operand:DI 0 "register_operand" "=r")
9846 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9847 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9848 && ix86_binary_operator_ok (XOR, SImode, operands)"
9849 "xor{l}\t{%2, %k0|%k0, %2}"
9850 [(set_attr "type" "alu")
9851 (set_attr "mode" "SI")])
9853 (define_insn "*xorsi_3"
9854 [(set (reg FLAGS_REG)
9855 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9856 (match_operand:SI 2 "general_operand" "g"))
9858 (clobber (match_scratch:SI 0 "=r"))]
9859 "ix86_match_ccmode (insn, CCNOmode)
9860 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9861 "xor{l}\t{%2, %0|%0, %2}"
9862 [(set_attr "type" "alu")
9863 (set_attr "mode" "SI")])
9865 (define_expand "xorhi3"
9866 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9867 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9868 (match_operand:HI 2 "general_operand" "")))
9869 (clobber (reg:CC FLAGS_REG))]
9870 "TARGET_HIMODE_MATH"
9871 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9873 (define_insn "*xorhi_1"
9874 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9875 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9876 (match_operand:HI 2 "general_operand" "g,ri")))
9877 (clobber (reg:CC FLAGS_REG))]
9878 "ix86_binary_operator_ok (XOR, HImode, operands)"
9879 "xor{w}\t{%2, %0|%0, %2}"
9880 [(set_attr "type" "alu")
9881 (set_attr "mode" "HI")])
9883 (define_insn "*xorhi_2"
9884 [(set (reg FLAGS_REG)
9885 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9886 (match_operand:HI 2 "general_operand" "g,ri"))
9888 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9889 (xor:HI (match_dup 1) (match_dup 2)))]
9890 "ix86_match_ccmode (insn, CCNOmode)
9891 && ix86_binary_operator_ok (XOR, HImode, operands)"
9892 "xor{w}\t{%2, %0|%0, %2}"
9893 [(set_attr "type" "alu")
9894 (set_attr "mode" "HI")])
9896 (define_insn "*xorhi_3"
9897 [(set (reg FLAGS_REG)
9898 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9899 (match_operand:HI 2 "general_operand" "g"))
9901 (clobber (match_scratch:HI 0 "=r"))]
9902 "ix86_match_ccmode (insn, CCNOmode)
9903 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9904 "xor{w}\t{%2, %0|%0, %2}"
9905 [(set_attr "type" "alu")
9906 (set_attr "mode" "HI")])
9908 (define_expand "xorqi3"
9909 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9910 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9911 (match_operand:QI 2 "general_operand" "")))
9912 (clobber (reg:CC FLAGS_REG))]
9913 "TARGET_QIMODE_MATH"
9914 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9916 ;; %%% Potential partial reg stall on alternative 2. What to do?
9917 (define_insn "*xorqi_1"
9918 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9919 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9920 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9921 (clobber (reg:CC FLAGS_REG))]
9922 "ix86_binary_operator_ok (XOR, QImode, operands)"
9924 xor{b}\t{%2, %0|%0, %2}
9925 xor{b}\t{%2, %0|%0, %2}
9926 xor{l}\t{%k2, %k0|%k0, %k2}"
9927 [(set_attr "type" "alu")
9928 (set_attr "mode" "QI,QI,SI")])
9930 (define_insn "*xorqi_1_slp"
9931 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9932 (xor:QI (match_dup 0)
9933 (match_operand:QI 1 "general_operand" "qi,qmi")))
9934 (clobber (reg:CC FLAGS_REG))]
9935 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9936 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9937 "xor{b}\t{%1, %0|%0, %1}"
9938 [(set_attr "type" "alu1")
9939 (set_attr "mode" "QI")])
9941 (define_insn "xorqi_ext_0"
9942 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9947 (match_operand 1 "ext_register_operand" "0")
9950 (match_operand 2 "const_int_operand" "n")))
9951 (clobber (reg:CC FLAGS_REG))]
9952 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9953 "xor{b}\t{%2, %h0|%h0, %2}"
9954 [(set_attr "type" "alu")
9955 (set_attr "length_immediate" "1")
9956 (set_attr "mode" "QI")])
9958 (define_insn "*xorqi_ext_1"
9959 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9964 (match_operand 1 "ext_register_operand" "0")
9968 (match_operand:QI 2 "general_operand" "Qm"))))
9969 (clobber (reg:CC FLAGS_REG))]
9971 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9972 "xor{b}\t{%2, %h0|%h0, %2}"
9973 [(set_attr "type" "alu")
9974 (set_attr "length_immediate" "0")
9975 (set_attr "mode" "QI")])
9977 (define_insn "*xorqi_ext_1_rex64"
9978 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9983 (match_operand 1 "ext_register_operand" "0")
9987 (match_operand 2 "ext_register_operand" "Q"))))
9988 (clobber (reg:CC FLAGS_REG))]
9990 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9991 "xor{b}\t{%2, %h0|%h0, %2}"
9992 [(set_attr "type" "alu")
9993 (set_attr "length_immediate" "0")
9994 (set_attr "mode" "QI")])
9996 (define_insn "*xorqi_ext_2"
9997 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10001 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10004 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10007 (clobber (reg:CC FLAGS_REG))]
10008 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
10009 "xor{b}\t{%h2, %h0|%h0, %h2}"
10010 [(set_attr "type" "alu")
10011 (set_attr "length_immediate" "0")
10012 (set_attr "mode" "QI")])
10014 (define_insn "*xorqi_cc_1"
10015 [(set (reg FLAGS_REG)
10017 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10018 (match_operand:QI 2 "general_operand" "qim,qi"))
10020 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10021 (xor:QI (match_dup 1) (match_dup 2)))]
10022 "ix86_match_ccmode (insn, CCNOmode)
10023 && ix86_binary_operator_ok (XOR, QImode, operands)"
10024 "xor{b}\t{%2, %0|%0, %2}"
10025 [(set_attr "type" "alu")
10026 (set_attr "mode" "QI")])
10028 (define_insn "*xorqi_2_slp"
10029 [(set (reg FLAGS_REG)
10030 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10031 (match_operand:QI 1 "general_operand" "qim,qi"))
10033 (set (strict_low_part (match_dup 0))
10034 (xor:QI (match_dup 0) (match_dup 1)))]
10035 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10036 && ix86_match_ccmode (insn, CCNOmode)
10037 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10038 "xor{b}\t{%1, %0|%0, %1}"
10039 [(set_attr "type" "alu1")
10040 (set_attr "mode" "QI")])
10042 (define_insn "*xorqi_cc_2"
10043 [(set (reg FLAGS_REG)
10045 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10046 (match_operand:QI 2 "general_operand" "qim"))
10048 (clobber (match_scratch:QI 0 "=q"))]
10049 "ix86_match_ccmode (insn, CCNOmode)
10050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10051 "xor{b}\t{%2, %0|%0, %2}"
10052 [(set_attr "type" "alu")
10053 (set_attr "mode" "QI")])
10055 (define_insn "*xorqi_cc_ext_1"
10056 [(set (reg FLAGS_REG)
10060 (match_operand 1 "ext_register_operand" "0")
10063 (match_operand:QI 2 "general_operand" "qmn"))
10065 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10069 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10071 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10072 "xor{b}\t{%2, %h0|%h0, %2}"
10073 [(set_attr "type" "alu")
10074 (set_attr "mode" "QI")])
10076 (define_insn "*xorqi_cc_ext_1_rex64"
10077 [(set (reg FLAGS_REG)
10081 (match_operand 1 "ext_register_operand" "0")
10084 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10086 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10090 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10092 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10093 "xor{b}\t{%2, %h0|%h0, %2}"
10094 [(set_attr "type" "alu")
10095 (set_attr "mode" "QI")])
10097 (define_expand "xorqi_cc_ext_1"
10099 (set (reg:CCNO FLAGS_REG)
10103 (match_operand 1 "ext_register_operand" "")
10106 (match_operand:QI 2 "general_operand" ""))
10108 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10112 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10118 [(set (match_operand 0 "register_operand" "")
10119 (xor (match_operand 1 "register_operand" "")
10120 (match_operand 2 "const_int_operand" "")))
10121 (clobber (reg:CC FLAGS_REG))]
10123 && QI_REG_P (operands[0])
10124 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10125 && !(INTVAL (operands[2]) & ~(255 << 8))
10126 && GET_MODE (operands[0]) != QImode"
10127 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10128 (xor:SI (zero_extract:SI (match_dup 1)
10129 (const_int 8) (const_int 8))
10131 (clobber (reg:CC FLAGS_REG))])]
10132 "operands[0] = gen_lowpart (SImode, operands[0]);
10133 operands[1] = gen_lowpart (SImode, operands[1]);
10134 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10136 ;; Since XOR can be encoded with sign extended immediate, this is only
10137 ;; profitable when 7th bit is set.
10139 [(set (match_operand 0 "register_operand" "")
10140 (xor (match_operand 1 "general_operand" "")
10141 (match_operand 2 "const_int_operand" "")))
10142 (clobber (reg:CC FLAGS_REG))]
10144 && ANY_QI_REG_P (operands[0])
10145 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10146 && !(INTVAL (operands[2]) & ~255)
10147 && (INTVAL (operands[2]) & 128)
10148 && GET_MODE (operands[0]) != QImode"
10149 [(parallel [(set (strict_low_part (match_dup 0))
10150 (xor:QI (match_dup 1)
10152 (clobber (reg:CC FLAGS_REG))])]
10153 "operands[0] = gen_lowpart (QImode, operands[0]);
10154 operands[1] = gen_lowpart (QImode, operands[1]);
10155 operands[2] = gen_lowpart (QImode, operands[2]);")
10157 ;; Negation instructions
10159 (define_expand "negti2"
10160 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10161 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10162 (clobber (reg:CC FLAGS_REG))])]
10164 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10166 (define_insn "*negti2_1"
10167 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10168 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10169 (clobber (reg:CC FLAGS_REG))]
10171 && ix86_unary_operator_ok (NEG, TImode, operands)"
10175 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10176 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10177 (clobber (reg:CC FLAGS_REG))]
10178 "TARGET_64BIT && reload_completed"
10180 [(set (reg:CCZ FLAGS_REG)
10181 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10182 (set (match_dup 0) (neg:DI (match_dup 1)))])
10184 [(set (match_dup 2)
10185 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10188 (clobber (reg:CC FLAGS_REG))])
10190 [(set (match_dup 2)
10191 (neg:DI (match_dup 2)))
10192 (clobber (reg:CC FLAGS_REG))])]
10193 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10195 (define_expand "negdi2"
10196 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10197 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10198 (clobber (reg:CC FLAGS_REG))])]
10200 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10202 (define_insn "*negdi2_1"
10203 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10204 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10205 (clobber (reg:CC FLAGS_REG))]
10207 && ix86_unary_operator_ok (NEG, DImode, operands)"
10211 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10212 (neg:DI (match_operand:DI 1 "general_operand" "")))
10213 (clobber (reg:CC FLAGS_REG))]
10214 "!TARGET_64BIT && reload_completed"
10216 [(set (reg:CCZ FLAGS_REG)
10217 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10218 (set (match_dup 0) (neg:SI (match_dup 1)))])
10220 [(set (match_dup 2)
10221 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10224 (clobber (reg:CC FLAGS_REG))])
10226 [(set (match_dup 2)
10227 (neg:SI (match_dup 2)))
10228 (clobber (reg:CC FLAGS_REG))])]
10229 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10231 (define_insn "*negdi2_1_rex64"
10232 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10233 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10234 (clobber (reg:CC FLAGS_REG))]
10235 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10237 [(set_attr "type" "negnot")
10238 (set_attr "mode" "DI")])
10240 ;; The problem with neg is that it does not perform (compare x 0),
10241 ;; it really performs (compare 0 x), which leaves us with the zero
10242 ;; flag being the only useful item.
10244 (define_insn "*negdi2_cmpz_rex64"
10245 [(set (reg:CCZ FLAGS_REG)
10246 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10248 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10249 (neg:DI (match_dup 1)))]
10250 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10252 [(set_attr "type" "negnot")
10253 (set_attr "mode" "DI")])
10256 (define_expand "negsi2"
10257 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10258 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10259 (clobber (reg:CC FLAGS_REG))])]
10261 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10263 (define_insn "*negsi2_1"
10264 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10265 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10266 (clobber (reg:CC FLAGS_REG))]
10267 "ix86_unary_operator_ok (NEG, SImode, operands)"
10269 [(set_attr "type" "negnot")
10270 (set_attr "mode" "SI")])
10272 ;; Combine is quite creative about this pattern.
10273 (define_insn "*negsi2_1_zext"
10274 [(set (match_operand:DI 0 "register_operand" "=r")
10275 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10278 (clobber (reg:CC FLAGS_REG))]
10279 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10281 [(set_attr "type" "negnot")
10282 (set_attr "mode" "SI")])
10284 ;; The problem with neg is that it does not perform (compare x 0),
10285 ;; it really performs (compare 0 x), which leaves us with the zero
10286 ;; flag being the only useful item.
10288 (define_insn "*negsi2_cmpz"
10289 [(set (reg:CCZ FLAGS_REG)
10290 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10292 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10293 (neg:SI (match_dup 1)))]
10294 "ix86_unary_operator_ok (NEG, SImode, operands)"
10296 [(set_attr "type" "negnot")
10297 (set_attr "mode" "SI")])
10299 (define_insn "*negsi2_cmpz_zext"
10300 [(set (reg:CCZ FLAGS_REG)
10301 (compare:CCZ (lshiftrt:DI
10303 (match_operand:DI 1 "register_operand" "0")
10307 (set (match_operand:DI 0 "register_operand" "=r")
10308 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10311 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10313 [(set_attr "type" "negnot")
10314 (set_attr "mode" "SI")])
10316 (define_expand "neghi2"
10317 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10318 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10319 (clobber (reg:CC FLAGS_REG))])]
10320 "TARGET_HIMODE_MATH"
10321 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10323 (define_insn "*neghi2_1"
10324 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10325 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10326 (clobber (reg:CC FLAGS_REG))]
10327 "ix86_unary_operator_ok (NEG, HImode, operands)"
10329 [(set_attr "type" "negnot")
10330 (set_attr "mode" "HI")])
10332 (define_insn "*neghi2_cmpz"
10333 [(set (reg:CCZ FLAGS_REG)
10334 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10336 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10337 (neg:HI (match_dup 1)))]
10338 "ix86_unary_operator_ok (NEG, HImode, operands)"
10340 [(set_attr "type" "negnot")
10341 (set_attr "mode" "HI")])
10343 (define_expand "negqi2"
10344 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10345 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10346 (clobber (reg:CC FLAGS_REG))])]
10347 "TARGET_QIMODE_MATH"
10348 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10350 (define_insn "*negqi2_1"
10351 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10352 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10353 (clobber (reg:CC FLAGS_REG))]
10354 "ix86_unary_operator_ok (NEG, QImode, operands)"
10356 [(set_attr "type" "negnot")
10357 (set_attr "mode" "QI")])
10359 (define_insn "*negqi2_cmpz"
10360 [(set (reg:CCZ FLAGS_REG)
10361 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10363 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10364 (neg:QI (match_dup 1)))]
10365 "ix86_unary_operator_ok (NEG, QImode, operands)"
10367 [(set_attr "type" "negnot")
10368 (set_attr "mode" "QI")])
10370 ;; Changing of sign for FP values is doable using integer unit too.
10372 (define_expand "<code><mode>2"
10373 [(set (match_operand:X87MODEF 0 "register_operand" "")
10374 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10375 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10376 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10378 (define_insn "*absneg<mode>2_mixed"
10379 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10380 (match_operator:MODEF 3 "absneg_operator"
10381 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10382 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10383 (clobber (reg:CC FLAGS_REG))]
10384 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10387 (define_insn "*absneg<mode>2_sse"
10388 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10389 (match_operator:MODEF 3 "absneg_operator"
10390 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10391 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10392 (clobber (reg:CC FLAGS_REG))]
10393 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10396 (define_insn "*absneg<mode>2_i387"
10397 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10398 (match_operator:X87MODEF 3 "absneg_operator"
10399 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10400 (use (match_operand 2 "" ""))
10401 (clobber (reg:CC FLAGS_REG))]
10402 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10405 (define_expand "<code>tf2"
10406 [(set (match_operand:TF 0 "register_operand" "")
10407 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10409 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10411 (define_insn "*absnegtf2_sse"
10412 [(set (match_operand:TF 0 "register_operand" "=x,x")
10413 (match_operator:TF 3 "absneg_operator"
10414 [(match_operand:TF 1 "register_operand" "0,x")]))
10415 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10416 (clobber (reg:CC FLAGS_REG))]
10420 ;; Splitters for fp abs and neg.
10423 [(set (match_operand 0 "fp_register_operand" "")
10424 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10425 (use (match_operand 2 "" ""))
10426 (clobber (reg:CC FLAGS_REG))]
10428 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10431 [(set (match_operand 0 "register_operand" "")
10432 (match_operator 3 "absneg_operator"
10433 [(match_operand 1 "register_operand" "")]))
10434 (use (match_operand 2 "nonimmediate_operand" ""))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "reload_completed && SSE_REG_P (operands[0])"
10437 [(set (match_dup 0) (match_dup 3))]
10439 enum machine_mode mode = GET_MODE (operands[0]);
10440 enum machine_mode vmode = GET_MODE (operands[2]);
10443 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10444 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10445 if (operands_match_p (operands[0], operands[2]))
10448 operands[1] = operands[2];
10451 if (GET_CODE (operands[3]) == ABS)
10452 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10454 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10459 [(set (match_operand:SF 0 "register_operand" "")
10460 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10461 (use (match_operand:V4SF 2 "" ""))
10462 (clobber (reg:CC FLAGS_REG))]
10464 [(parallel [(set (match_dup 0) (match_dup 1))
10465 (clobber (reg:CC FLAGS_REG))])]
10468 operands[0] = gen_lowpart (SImode, operands[0]);
10469 if (GET_CODE (operands[1]) == ABS)
10471 tmp = gen_int_mode (0x7fffffff, SImode);
10472 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10476 tmp = gen_int_mode (0x80000000, SImode);
10477 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10483 [(set (match_operand:DF 0 "register_operand" "")
10484 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10485 (use (match_operand 2 "" ""))
10486 (clobber (reg:CC FLAGS_REG))]
10488 [(parallel [(set (match_dup 0) (match_dup 1))
10489 (clobber (reg:CC FLAGS_REG))])]
10494 tmp = gen_lowpart (DImode, operands[0]);
10495 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10498 if (GET_CODE (operands[1]) == ABS)
10501 tmp = gen_rtx_NOT (DImode, tmp);
10505 operands[0] = gen_highpart (SImode, operands[0]);
10506 if (GET_CODE (operands[1]) == ABS)
10508 tmp = gen_int_mode (0x7fffffff, SImode);
10509 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10513 tmp = gen_int_mode (0x80000000, SImode);
10514 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10521 [(set (match_operand:XF 0 "register_operand" "")
10522 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10523 (use (match_operand 2 "" ""))
10524 (clobber (reg:CC FLAGS_REG))]
10526 [(parallel [(set (match_dup 0) (match_dup 1))
10527 (clobber (reg:CC FLAGS_REG))])]
10530 operands[0] = gen_rtx_REG (SImode,
10531 true_regnum (operands[0])
10532 + (TARGET_64BIT ? 1 : 2));
10533 if (GET_CODE (operands[1]) == ABS)
10535 tmp = GEN_INT (0x7fff);
10536 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10540 tmp = GEN_INT (0x8000);
10541 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10546 ;; Conditionalize these after reload. If they match before reload, we
10547 ;; lose the clobber and ability to use integer instructions.
10549 (define_insn "*<code><mode>2_1"
10550 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10551 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10553 && (reload_completed
10554 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10556 [(set_attr "type" "fsgn")
10557 (set_attr "mode" "<MODE>")])
10559 (define_insn "*<code>extendsfdf2"
10560 [(set (match_operand:DF 0 "register_operand" "=f")
10561 (absneg:DF (float_extend:DF
10562 (match_operand:SF 1 "register_operand" "0"))))]
10563 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10565 [(set_attr "type" "fsgn")
10566 (set_attr "mode" "DF")])
10568 (define_insn "*<code>extendsfxf2"
10569 [(set (match_operand:XF 0 "register_operand" "=f")
10570 (absneg:XF (float_extend:XF
10571 (match_operand:SF 1 "register_operand" "0"))))]
10574 [(set_attr "type" "fsgn")
10575 (set_attr "mode" "XF")])
10577 (define_insn "*<code>extenddfxf2"
10578 [(set (match_operand:XF 0 "register_operand" "=f")
10579 (absneg:XF (float_extend:XF
10580 (match_operand:DF 1 "register_operand" "0"))))]
10583 [(set_attr "type" "fsgn")
10584 (set_attr "mode" "XF")])
10586 ;; Copysign instructions
10588 (define_mode_iterator CSGNMODE [SF DF TF])
10589 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10591 (define_expand "copysign<mode>3"
10592 [(match_operand:CSGNMODE 0 "register_operand" "")
10593 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10594 (match_operand:CSGNMODE 2 "register_operand" "")]
10595 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10596 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10598 ix86_expand_copysign (operands);
10602 (define_insn_and_split "copysign<mode>3_const"
10603 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10605 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10606 (match_operand:CSGNMODE 2 "register_operand" "0")
10607 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10609 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10610 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10612 "&& reload_completed"
10615 ix86_split_copysign_const (operands);
10619 (define_insn "copysign<mode>3_var"
10620 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10622 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10623 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10624 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10625 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10627 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10628 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10629 || (TARGET_64BIT && (<MODE>mode == TFmode))"
10633 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10635 [(match_operand:CSGNMODE 2 "register_operand" "")
10636 (match_operand:CSGNMODE 3 "register_operand" "")
10637 (match_operand:<CSGNVMODE> 4 "" "")
10638 (match_operand:<CSGNVMODE> 5 "" "")]
10640 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10641 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10642 || (TARGET_64BIT && (<MODE>mode == TFmode)))
10643 && reload_completed"
10646 ix86_split_copysign_var (operands);
10650 ;; One complement instructions
10652 (define_expand "one_cmpldi2"
10653 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10654 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10656 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10658 (define_insn "*one_cmpldi2_1_rex64"
10659 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10660 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10661 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10663 [(set_attr "type" "negnot")
10664 (set_attr "mode" "DI")])
10666 (define_insn "*one_cmpldi2_2_rex64"
10667 [(set (reg FLAGS_REG)
10668 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10670 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10671 (not:DI (match_dup 1)))]
10672 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10673 && ix86_unary_operator_ok (NOT, DImode, operands)"
10675 [(set_attr "type" "alu1")
10676 (set_attr "mode" "DI")])
10679 [(set (match_operand 0 "flags_reg_operand" "")
10680 (match_operator 2 "compare_operator"
10681 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10683 (set (match_operand:DI 1 "nonimmediate_operand" "")
10684 (not:DI (match_dup 3)))]
10685 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10686 [(parallel [(set (match_dup 0)
10688 [(xor:DI (match_dup 3) (const_int -1))
10691 (xor:DI (match_dup 3) (const_int -1)))])]
10694 (define_expand "one_cmplsi2"
10695 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10696 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10698 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10700 (define_insn "*one_cmplsi2_1"
10701 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10702 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10703 "ix86_unary_operator_ok (NOT, SImode, operands)"
10705 [(set_attr "type" "negnot")
10706 (set_attr "mode" "SI")])
10708 ;; ??? Currently never generated - xor is used instead.
10709 (define_insn "*one_cmplsi2_1_zext"
10710 [(set (match_operand:DI 0 "register_operand" "=r")
10711 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10712 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10714 [(set_attr "type" "negnot")
10715 (set_attr "mode" "SI")])
10717 (define_insn "*one_cmplsi2_2"
10718 [(set (reg FLAGS_REG)
10719 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10721 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10722 (not:SI (match_dup 1)))]
10723 "ix86_match_ccmode (insn, CCNOmode)
10724 && ix86_unary_operator_ok (NOT, SImode, operands)"
10726 [(set_attr "type" "alu1")
10727 (set_attr "mode" "SI")])
10730 [(set (match_operand 0 "flags_reg_operand" "")
10731 (match_operator 2 "compare_operator"
10732 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10734 (set (match_operand:SI 1 "nonimmediate_operand" "")
10735 (not:SI (match_dup 3)))]
10736 "ix86_match_ccmode (insn, CCNOmode)"
10737 [(parallel [(set (match_dup 0)
10738 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10741 (xor:SI (match_dup 3) (const_int -1)))])]
10744 ;; ??? Currently never generated - xor is used instead.
10745 (define_insn "*one_cmplsi2_2_zext"
10746 [(set (reg FLAGS_REG)
10747 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10749 (set (match_operand:DI 0 "register_operand" "=r")
10750 (zero_extend:DI (not:SI (match_dup 1))))]
10751 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10752 && ix86_unary_operator_ok (NOT, SImode, operands)"
10754 [(set_attr "type" "alu1")
10755 (set_attr "mode" "SI")])
10758 [(set (match_operand 0 "flags_reg_operand" "")
10759 (match_operator 2 "compare_operator"
10760 [(not:SI (match_operand:SI 3 "register_operand" ""))
10762 (set (match_operand:DI 1 "register_operand" "")
10763 (zero_extend:DI (not:SI (match_dup 3))))]
10764 "ix86_match_ccmode (insn, CCNOmode)"
10765 [(parallel [(set (match_dup 0)
10766 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10769 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10772 (define_expand "one_cmplhi2"
10773 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10774 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10775 "TARGET_HIMODE_MATH"
10776 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10778 (define_insn "*one_cmplhi2_1"
10779 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10780 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10781 "ix86_unary_operator_ok (NOT, HImode, operands)"
10783 [(set_attr "type" "negnot")
10784 (set_attr "mode" "HI")])
10786 (define_insn "*one_cmplhi2_2"
10787 [(set (reg FLAGS_REG)
10788 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10790 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10791 (not:HI (match_dup 1)))]
10792 "ix86_match_ccmode (insn, CCNOmode)
10793 && ix86_unary_operator_ok (NEG, HImode, operands)"
10795 [(set_attr "type" "alu1")
10796 (set_attr "mode" "HI")])
10799 [(set (match_operand 0 "flags_reg_operand" "")
10800 (match_operator 2 "compare_operator"
10801 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10803 (set (match_operand:HI 1 "nonimmediate_operand" "")
10804 (not:HI (match_dup 3)))]
10805 "ix86_match_ccmode (insn, CCNOmode)"
10806 [(parallel [(set (match_dup 0)
10807 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10810 (xor:HI (match_dup 3) (const_int -1)))])]
10813 ;; %%% Potential partial reg stall on alternative 1. What to do?
10814 (define_expand "one_cmplqi2"
10815 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10816 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10817 "TARGET_QIMODE_MATH"
10818 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10820 (define_insn "*one_cmplqi2_1"
10821 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10822 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10823 "ix86_unary_operator_ok (NOT, QImode, operands)"
10827 [(set_attr "type" "negnot")
10828 (set_attr "mode" "QI,SI")])
10830 (define_insn "*one_cmplqi2_2"
10831 [(set (reg FLAGS_REG)
10832 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10834 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10835 (not:QI (match_dup 1)))]
10836 "ix86_match_ccmode (insn, CCNOmode)
10837 && ix86_unary_operator_ok (NOT, QImode, operands)"
10839 [(set_attr "type" "alu1")
10840 (set_attr "mode" "QI")])
10843 [(set (match_operand 0 "flags_reg_operand" "")
10844 (match_operator 2 "compare_operator"
10845 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10847 (set (match_operand:QI 1 "nonimmediate_operand" "")
10848 (not:QI (match_dup 3)))]
10849 "ix86_match_ccmode (insn, CCNOmode)"
10850 [(parallel [(set (match_dup 0)
10851 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10854 (xor:QI (match_dup 3) (const_int -1)))])]
10857 ;; Arithmetic shift instructions
10859 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10860 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10861 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10862 ;; from the assembler input.
10864 ;; This instruction shifts the target reg/mem as usual, but instead of
10865 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10866 ;; is a left shift double, bits are taken from the high order bits of
10867 ;; reg, else if the insn is a shift right double, bits are taken from the
10868 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10869 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10871 ;; Since sh[lr]d does not change the `reg' operand, that is done
10872 ;; separately, making all shifts emit pairs of shift double and normal
10873 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10874 ;; support a 63 bit shift, each shift where the count is in a reg expands
10875 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10877 ;; If the shift count is a constant, we need never emit more than one
10878 ;; shift pair, instead using moves and sign extension for counts greater
10881 (define_expand "ashlti3"
10882 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10883 (ashift:TI (match_operand:TI 1 "register_operand" "")
10884 (match_operand:QI 2 "nonmemory_operand" "")))
10885 (clobber (reg:CC FLAGS_REG))])]
10888 if (! immediate_operand (operands[2], QImode))
10890 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10893 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10897 (define_insn "ashlti3_1"
10898 [(set (match_operand:TI 0 "register_operand" "=r")
10899 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10900 (match_operand:QI 2 "register_operand" "c")))
10901 (clobber (match_scratch:DI 3 "=&r"))
10902 (clobber (reg:CC FLAGS_REG))]
10905 [(set_attr "type" "multi")])
10907 ;; This pattern must be defined before *ashlti3_2 to prevent
10908 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10910 (define_insn "sse2_ashlti3"
10911 [(set (match_operand:TI 0 "register_operand" "=x")
10912 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10913 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10916 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10917 return "pslldq\t{%2, %0|%0, %2}";
10919 [(set_attr "type" "sseishft")
10920 (set_attr "prefix_data16" "1")
10921 (set_attr "mode" "TI")])
10923 (define_insn "*ashlti3_2"
10924 [(set (match_operand:TI 0 "register_operand" "=r")
10925 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10926 (match_operand:QI 2 "immediate_operand" "O")))
10927 (clobber (reg:CC FLAGS_REG))]
10930 [(set_attr "type" "multi")])
10933 [(set (match_operand:TI 0 "register_operand" "")
10934 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10935 (match_operand:QI 2 "register_operand" "")))
10936 (clobber (match_scratch:DI 3 ""))
10937 (clobber (reg:CC FLAGS_REG))]
10938 "TARGET_64BIT && reload_completed"
10940 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10943 [(set (match_operand:TI 0 "register_operand" "")
10944 (ashift:TI (match_operand:TI 1 "register_operand" "")
10945 (match_operand:QI 2 "immediate_operand" "")))
10946 (clobber (reg:CC FLAGS_REG))]
10947 "TARGET_64BIT && reload_completed"
10949 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10951 (define_insn "x86_64_shld"
10952 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10953 (ior:DI (ashift:DI (match_dup 0)
10954 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10955 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10956 (minus:QI (const_int 64) (match_dup 2)))))
10957 (clobber (reg:CC FLAGS_REG))]
10960 shld{q}\t{%2, %1, %0|%0, %1, %2}
10961 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10962 [(set_attr "type" "ishift")
10963 (set_attr "prefix_0f" "1")
10964 (set_attr "mode" "DI")
10965 (set_attr "athlon_decode" "vector")
10966 (set_attr "amdfam10_decode" "vector")])
10968 (define_expand "x86_64_shift_adj"
10969 [(set (reg:CCZ FLAGS_REG)
10970 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10973 (set (match_operand:DI 0 "register_operand" "")
10974 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10975 (match_operand:DI 1 "register_operand" "")
10978 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10979 (match_operand:DI 3 "register_operand" "r")
10984 (define_expand "ashldi3"
10985 [(set (match_operand:DI 0 "shiftdi_operand" "")
10986 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10987 (match_operand:QI 2 "nonmemory_operand" "")))]
10989 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10991 (define_insn "*ashldi3_1_rex64"
10992 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10993 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10994 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10995 (clobber (reg:CC FLAGS_REG))]
10996 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10998 switch (get_attr_type (insn))
11001 gcc_assert (operands[2] == const1_rtx);
11002 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11003 return "add{q}\t%0, %0";
11006 gcc_assert (CONST_INT_P (operands[2]));
11007 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11008 operands[1] = gen_rtx_MULT (DImode, operands[1],
11009 GEN_INT (1 << INTVAL (operands[2])));
11010 return "lea{q}\t{%a1, %0|%0, %a1}";
11013 if (REG_P (operands[2]))
11014 return "sal{q}\t{%b2, %0|%0, %b2}";
11015 else if (operands[2] == const1_rtx
11016 && (TARGET_SHIFT1 || optimize_size))
11017 return "sal{q}\t%0";
11019 return "sal{q}\t{%2, %0|%0, %2}";
11022 [(set (attr "type")
11023 (cond [(eq_attr "alternative" "1")
11024 (const_string "lea")
11025 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11027 (match_operand 0 "register_operand" ""))
11028 (match_operand 2 "const1_operand" ""))
11029 (const_string "alu")
11031 (const_string "ishift")))
11032 (set_attr "mode" "DI")])
11034 ;; Convert lea to the lea pattern to avoid flags dependency.
11036 [(set (match_operand:DI 0 "register_operand" "")
11037 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11038 (match_operand:QI 2 "immediate_operand" "")))
11039 (clobber (reg:CC FLAGS_REG))]
11040 "TARGET_64BIT && reload_completed
11041 && true_regnum (operands[0]) != true_regnum (operands[1])"
11042 [(set (match_dup 0)
11043 (mult:DI (match_dup 1)
11045 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11047 ;; This pattern can't accept a variable shift count, since shifts by
11048 ;; zero don't affect the flags. We assume that shifts by constant
11049 ;; zero are optimized away.
11050 (define_insn "*ashldi3_cmp_rex64"
11051 [(set (reg FLAGS_REG)
11053 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11054 (match_operand:QI 2 "immediate_operand" "e"))
11056 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11057 (ashift:DI (match_dup 1) (match_dup 2)))]
11060 || !TARGET_PARTIAL_FLAG_REG_STALL
11061 || (operands[2] == const1_rtx
11063 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11064 && ix86_match_ccmode (insn, CCGOCmode)
11065 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11067 switch (get_attr_type (insn))
11070 gcc_assert (operands[2] == const1_rtx);
11071 return "add{q}\t%0, %0";
11074 if (REG_P (operands[2]))
11075 return "sal{q}\t{%b2, %0|%0, %b2}";
11076 else if (operands[2] == const1_rtx
11077 && (TARGET_SHIFT1 || optimize_size))
11078 return "sal{q}\t%0";
11080 return "sal{q}\t{%2, %0|%0, %2}";
11083 [(set (attr "type")
11084 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11086 (match_operand 0 "register_operand" ""))
11087 (match_operand 2 "const1_operand" ""))
11088 (const_string "alu")
11090 (const_string "ishift")))
11091 (set_attr "mode" "DI")])
11093 (define_insn "*ashldi3_cconly_rex64"
11094 [(set (reg FLAGS_REG)
11096 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11097 (match_operand:QI 2 "immediate_operand" "e"))
11099 (clobber (match_scratch:DI 0 "=r"))]
11102 || !TARGET_PARTIAL_FLAG_REG_STALL
11103 || (operands[2] == const1_rtx
11105 || TARGET_DOUBLE_WITH_ADD)))
11106 && ix86_match_ccmode (insn, CCGOCmode)
11107 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11109 switch (get_attr_type (insn))
11112 gcc_assert (operands[2] == const1_rtx);
11113 return "add{q}\t%0, %0";
11116 if (REG_P (operands[2]))
11117 return "sal{q}\t{%b2, %0|%0, %b2}";
11118 else if (operands[2] == const1_rtx
11119 && (TARGET_SHIFT1 || optimize_size))
11120 return "sal{q}\t%0";
11122 return "sal{q}\t{%2, %0|%0, %2}";
11125 [(set (attr "type")
11126 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11128 (match_operand 0 "register_operand" ""))
11129 (match_operand 2 "const1_operand" ""))
11130 (const_string "alu")
11132 (const_string "ishift")))
11133 (set_attr "mode" "DI")])
11135 (define_insn "*ashldi3_1"
11136 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11137 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11138 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11139 (clobber (reg:CC FLAGS_REG))]
11142 [(set_attr "type" "multi")])
11144 ;; By default we don't ask for a scratch register, because when DImode
11145 ;; values are manipulated, registers are already at a premium. But if
11146 ;; we have one handy, we won't turn it away.
11148 [(match_scratch:SI 3 "r")
11149 (parallel [(set (match_operand:DI 0 "register_operand" "")
11150 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11151 (match_operand:QI 2 "nonmemory_operand" "")))
11152 (clobber (reg:CC FLAGS_REG))])
11154 "!TARGET_64BIT && TARGET_CMOVE"
11156 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11159 [(set (match_operand:DI 0 "register_operand" "")
11160 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11161 (match_operand:QI 2 "nonmemory_operand" "")))
11162 (clobber (reg:CC FLAGS_REG))]
11163 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11164 ? epilogue_completed : reload_completed)"
11166 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11168 (define_insn "x86_shld_1"
11169 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11170 (ior:SI (ashift:SI (match_dup 0)
11171 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11172 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11173 (minus:QI (const_int 32) (match_dup 2)))))
11174 (clobber (reg:CC FLAGS_REG))]
11177 shld{l}\t{%2, %1, %0|%0, %1, %2}
11178 shld{l}\t{%s2%1, %0|%0, %1, %2}"
11179 [(set_attr "type" "ishift")
11180 (set_attr "prefix_0f" "1")
11181 (set_attr "mode" "SI")
11182 (set_attr "pent_pair" "np")
11183 (set_attr "athlon_decode" "vector")
11184 (set_attr "amdfam10_decode" "vector")])
11186 (define_expand "x86_shift_adj_1"
11187 [(set (reg:CCZ FLAGS_REG)
11188 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11191 (set (match_operand:SI 0 "register_operand" "")
11192 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11193 (match_operand:SI 1 "register_operand" "")
11196 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11197 (match_operand:SI 3 "register_operand" "r")
11202 (define_expand "x86_shift_adj_2"
11203 [(use (match_operand:SI 0 "register_operand" ""))
11204 (use (match_operand:SI 1 "register_operand" ""))
11205 (use (match_operand:QI 2 "register_operand" ""))]
11208 rtx label = gen_label_rtx ();
11211 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11213 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11214 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11215 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11216 gen_rtx_LABEL_REF (VOIDmode, label),
11218 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11219 JUMP_LABEL (tmp) = label;
11221 emit_move_insn (operands[0], operands[1]);
11222 ix86_expand_clear (operands[1]);
11224 emit_label (label);
11225 LABEL_NUSES (label) = 1;
11230 (define_expand "ashlsi3"
11231 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11232 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11233 (match_operand:QI 2 "nonmemory_operand" "")))
11234 (clobber (reg:CC FLAGS_REG))]
11236 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11238 (define_insn "*ashlsi3_1"
11239 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11240 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11241 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11242 (clobber (reg:CC FLAGS_REG))]
11243 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11245 switch (get_attr_type (insn))
11248 gcc_assert (operands[2] == const1_rtx);
11249 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11250 return "add{l}\t%0, %0";
11256 if (REG_P (operands[2]))
11257 return "sal{l}\t{%b2, %0|%0, %b2}";
11258 else if (operands[2] == const1_rtx
11259 && (TARGET_SHIFT1 || optimize_size))
11260 return "sal{l}\t%0";
11262 return "sal{l}\t{%2, %0|%0, %2}";
11265 [(set (attr "type")
11266 (cond [(eq_attr "alternative" "1")
11267 (const_string "lea")
11268 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11270 (match_operand 0 "register_operand" ""))
11271 (match_operand 2 "const1_operand" ""))
11272 (const_string "alu")
11274 (const_string "ishift")))
11275 (set_attr "mode" "SI")])
11277 ;; Convert lea to the lea pattern to avoid flags dependency.
11279 [(set (match_operand 0 "register_operand" "")
11280 (ashift (match_operand 1 "index_register_operand" "")
11281 (match_operand:QI 2 "const_int_operand" "")))
11282 (clobber (reg:CC FLAGS_REG))]
11284 && true_regnum (operands[0]) != true_regnum (operands[1])
11285 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11289 enum machine_mode mode = GET_MODE (operands[0]);
11291 if (GET_MODE_SIZE (mode) < 4)
11292 operands[0] = gen_lowpart (SImode, operands[0]);
11294 operands[1] = gen_lowpart (Pmode, operands[1]);
11295 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11297 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11298 if (Pmode != SImode)
11299 pat = gen_rtx_SUBREG (SImode, pat, 0);
11300 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11304 ;; Rare case of shifting RSP is handled by generating move and shift
11306 [(set (match_operand 0 "register_operand" "")
11307 (ashift (match_operand 1 "register_operand" "")
11308 (match_operand:QI 2 "const_int_operand" "")))
11309 (clobber (reg:CC FLAGS_REG))]
11311 && true_regnum (operands[0]) != true_regnum (operands[1])"
11315 emit_move_insn (operands[0], operands[1]);
11316 pat = gen_rtx_SET (VOIDmode, operands[0],
11317 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11318 operands[0], operands[2]));
11319 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11320 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11324 (define_insn "*ashlsi3_1_zext"
11325 [(set (match_operand:DI 0 "register_operand" "=r,r")
11326 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11327 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11328 (clobber (reg:CC FLAGS_REG))]
11329 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11331 switch (get_attr_type (insn))
11334 gcc_assert (operands[2] == const1_rtx);
11335 return "add{l}\t%k0, %k0";
11341 if (REG_P (operands[2]))
11342 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11343 else if (operands[2] == const1_rtx
11344 && (TARGET_SHIFT1 || optimize_size))
11345 return "sal{l}\t%k0";
11347 return "sal{l}\t{%2, %k0|%k0, %2}";
11350 [(set (attr "type")
11351 (cond [(eq_attr "alternative" "1")
11352 (const_string "lea")
11353 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11355 (match_operand 2 "const1_operand" ""))
11356 (const_string "alu")
11358 (const_string "ishift")))
11359 (set_attr "mode" "SI")])
11361 ;; Convert lea to the lea pattern to avoid flags dependency.
11363 [(set (match_operand:DI 0 "register_operand" "")
11364 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11365 (match_operand:QI 2 "const_int_operand" ""))))
11366 (clobber (reg:CC FLAGS_REG))]
11367 "TARGET_64BIT && reload_completed
11368 && true_regnum (operands[0]) != true_regnum (operands[1])"
11369 [(set (match_dup 0) (zero_extend:DI
11370 (subreg:SI (mult:SI (match_dup 1)
11371 (match_dup 2)) 0)))]
11373 operands[1] = gen_lowpart (Pmode, operands[1]);
11374 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11377 ;; This pattern can't accept a variable shift count, since shifts by
11378 ;; zero don't affect the flags. We assume that shifts by constant
11379 ;; zero are optimized away.
11380 (define_insn "*ashlsi3_cmp"
11381 [(set (reg FLAGS_REG)
11383 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11384 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11386 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11387 (ashift:SI (match_dup 1) (match_dup 2)))]
11389 || !TARGET_PARTIAL_FLAG_REG_STALL
11390 || (operands[2] == const1_rtx
11392 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11393 && ix86_match_ccmode (insn, CCGOCmode)
11394 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11396 switch (get_attr_type (insn))
11399 gcc_assert (operands[2] == const1_rtx);
11400 return "add{l}\t%0, %0";
11403 if (REG_P (operands[2]))
11404 return "sal{l}\t{%b2, %0|%0, %b2}";
11405 else if (operands[2] == const1_rtx
11406 && (TARGET_SHIFT1 || optimize_size))
11407 return "sal{l}\t%0";
11409 return "sal{l}\t{%2, %0|%0, %2}";
11412 [(set (attr "type")
11413 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11415 (match_operand 0 "register_operand" ""))
11416 (match_operand 2 "const1_operand" ""))
11417 (const_string "alu")
11419 (const_string "ishift")))
11420 (set_attr "mode" "SI")])
11422 (define_insn "*ashlsi3_cconly"
11423 [(set (reg FLAGS_REG)
11425 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11426 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11428 (clobber (match_scratch:SI 0 "=r"))]
11430 || !TARGET_PARTIAL_FLAG_REG_STALL
11431 || (operands[2] == const1_rtx
11433 || TARGET_DOUBLE_WITH_ADD)))
11434 && ix86_match_ccmode (insn, CCGOCmode)
11435 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11437 switch (get_attr_type (insn))
11440 gcc_assert (operands[2] == const1_rtx);
11441 return "add{l}\t%0, %0";
11444 if (REG_P (operands[2]))
11445 return "sal{l}\t{%b2, %0|%0, %b2}";
11446 else if (operands[2] == const1_rtx
11447 && (TARGET_SHIFT1 || optimize_size))
11448 return "sal{l}\t%0";
11450 return "sal{l}\t{%2, %0|%0, %2}";
11453 [(set (attr "type")
11454 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11456 (match_operand 0 "register_operand" ""))
11457 (match_operand 2 "const1_operand" ""))
11458 (const_string "alu")
11460 (const_string "ishift")))
11461 (set_attr "mode" "SI")])
11463 (define_insn "*ashlsi3_cmp_zext"
11464 [(set (reg FLAGS_REG)
11466 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11467 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11469 (set (match_operand:DI 0 "register_operand" "=r")
11470 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11473 || !TARGET_PARTIAL_FLAG_REG_STALL
11474 || (operands[2] == const1_rtx
11476 || TARGET_DOUBLE_WITH_ADD)))
11477 && ix86_match_ccmode (insn, CCGOCmode)
11478 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11480 switch (get_attr_type (insn))
11483 gcc_assert (operands[2] == const1_rtx);
11484 return "add{l}\t%k0, %k0";
11487 if (REG_P (operands[2]))
11488 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11489 else if (operands[2] == const1_rtx
11490 && (TARGET_SHIFT1 || optimize_size))
11491 return "sal{l}\t%k0";
11493 return "sal{l}\t{%2, %k0|%k0, %2}";
11496 [(set (attr "type")
11497 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11499 (match_operand 2 "const1_operand" ""))
11500 (const_string "alu")
11502 (const_string "ishift")))
11503 (set_attr "mode" "SI")])
11505 (define_expand "ashlhi3"
11506 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11507 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11508 (match_operand:QI 2 "nonmemory_operand" "")))
11509 (clobber (reg:CC FLAGS_REG))]
11510 "TARGET_HIMODE_MATH"
11511 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11513 (define_insn "*ashlhi3_1_lea"
11514 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11515 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11516 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11517 (clobber (reg:CC FLAGS_REG))]
11518 "!TARGET_PARTIAL_REG_STALL
11519 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11521 switch (get_attr_type (insn))
11526 gcc_assert (operands[2] == const1_rtx);
11527 return "add{w}\t%0, %0";
11530 if (REG_P (operands[2]))
11531 return "sal{w}\t{%b2, %0|%0, %b2}";
11532 else if (operands[2] == const1_rtx
11533 && (TARGET_SHIFT1 || optimize_size))
11534 return "sal{w}\t%0";
11536 return "sal{w}\t{%2, %0|%0, %2}";
11539 [(set (attr "type")
11540 (cond [(eq_attr "alternative" "1")
11541 (const_string "lea")
11542 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11544 (match_operand 0 "register_operand" ""))
11545 (match_operand 2 "const1_operand" ""))
11546 (const_string "alu")
11548 (const_string "ishift")))
11549 (set_attr "mode" "HI,SI")])
11551 (define_insn "*ashlhi3_1"
11552 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11553 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11554 (match_operand:QI 2 "nonmemory_operand" "cI")))
11555 (clobber (reg:CC FLAGS_REG))]
11556 "TARGET_PARTIAL_REG_STALL
11557 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11559 switch (get_attr_type (insn))
11562 gcc_assert (operands[2] == const1_rtx);
11563 return "add{w}\t%0, %0";
11566 if (REG_P (operands[2]))
11567 return "sal{w}\t{%b2, %0|%0, %b2}";
11568 else if (operands[2] == const1_rtx
11569 && (TARGET_SHIFT1 || optimize_size))
11570 return "sal{w}\t%0";
11572 return "sal{w}\t{%2, %0|%0, %2}";
11575 [(set (attr "type")
11576 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11578 (match_operand 0 "register_operand" ""))
11579 (match_operand 2 "const1_operand" ""))
11580 (const_string "alu")
11582 (const_string "ishift")))
11583 (set_attr "mode" "HI")])
11585 ;; This pattern can't accept a variable shift count, since shifts by
11586 ;; zero don't affect the flags. We assume that shifts by constant
11587 ;; zero are optimized away.
11588 (define_insn "*ashlhi3_cmp"
11589 [(set (reg FLAGS_REG)
11591 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11592 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11594 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11595 (ashift:HI (match_dup 1) (match_dup 2)))]
11597 || !TARGET_PARTIAL_FLAG_REG_STALL
11598 || (operands[2] == const1_rtx
11600 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11601 && ix86_match_ccmode (insn, CCGOCmode)
11602 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11604 switch (get_attr_type (insn))
11607 gcc_assert (operands[2] == const1_rtx);
11608 return "add{w}\t%0, %0";
11611 if (REG_P (operands[2]))
11612 return "sal{w}\t{%b2, %0|%0, %b2}";
11613 else if (operands[2] == const1_rtx
11614 && (TARGET_SHIFT1 || optimize_size))
11615 return "sal{w}\t%0";
11617 return "sal{w}\t{%2, %0|%0, %2}";
11620 [(set (attr "type")
11621 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11623 (match_operand 0 "register_operand" ""))
11624 (match_operand 2 "const1_operand" ""))
11625 (const_string "alu")
11627 (const_string "ishift")))
11628 (set_attr "mode" "HI")])
11630 (define_insn "*ashlhi3_cconly"
11631 [(set (reg FLAGS_REG)
11633 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11634 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11636 (clobber (match_scratch:HI 0 "=r"))]
11638 || !TARGET_PARTIAL_FLAG_REG_STALL
11639 || (operands[2] == const1_rtx
11641 || TARGET_DOUBLE_WITH_ADD)))
11642 && ix86_match_ccmode (insn, CCGOCmode)
11643 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11645 switch (get_attr_type (insn))
11648 gcc_assert (operands[2] == const1_rtx);
11649 return "add{w}\t%0, %0";
11652 if (REG_P (operands[2]))
11653 return "sal{w}\t{%b2, %0|%0, %b2}";
11654 else if (operands[2] == const1_rtx
11655 && (TARGET_SHIFT1 || optimize_size))
11656 return "sal{w}\t%0";
11658 return "sal{w}\t{%2, %0|%0, %2}";
11661 [(set (attr "type")
11662 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11664 (match_operand 0 "register_operand" ""))
11665 (match_operand 2 "const1_operand" ""))
11666 (const_string "alu")
11668 (const_string "ishift")))
11669 (set_attr "mode" "HI")])
11671 (define_expand "ashlqi3"
11672 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11673 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11674 (match_operand:QI 2 "nonmemory_operand" "")))
11675 (clobber (reg:CC FLAGS_REG))]
11676 "TARGET_QIMODE_MATH"
11677 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11679 ;; %%% Potential partial reg stall on alternative 2. What to do?
11681 (define_insn "*ashlqi3_1_lea"
11682 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11683 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11684 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11685 (clobber (reg:CC FLAGS_REG))]
11686 "!TARGET_PARTIAL_REG_STALL
11687 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11689 switch (get_attr_type (insn))
11694 gcc_assert (operands[2] == const1_rtx);
11695 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11696 return "add{l}\t%k0, %k0";
11698 return "add{b}\t%0, %0";
11701 if (REG_P (operands[2]))
11703 if (get_attr_mode (insn) == MODE_SI)
11704 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11706 return "sal{b}\t{%b2, %0|%0, %b2}";
11708 else if (operands[2] == const1_rtx
11709 && (TARGET_SHIFT1 || optimize_size))
11711 if (get_attr_mode (insn) == MODE_SI)
11712 return "sal{l}\t%0";
11714 return "sal{b}\t%0";
11718 if (get_attr_mode (insn) == MODE_SI)
11719 return "sal{l}\t{%2, %k0|%k0, %2}";
11721 return "sal{b}\t{%2, %0|%0, %2}";
11725 [(set (attr "type")
11726 (cond [(eq_attr "alternative" "2")
11727 (const_string "lea")
11728 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11730 (match_operand 0 "register_operand" ""))
11731 (match_operand 2 "const1_operand" ""))
11732 (const_string "alu")
11734 (const_string "ishift")))
11735 (set_attr "mode" "QI,SI,SI")])
11737 (define_insn "*ashlqi3_1"
11738 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11739 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11740 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11741 (clobber (reg:CC FLAGS_REG))]
11742 "TARGET_PARTIAL_REG_STALL
11743 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11745 switch (get_attr_type (insn))
11748 gcc_assert (operands[2] == const1_rtx);
11749 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11750 return "add{l}\t%k0, %k0";
11752 return "add{b}\t%0, %0";
11755 if (REG_P (operands[2]))
11757 if (get_attr_mode (insn) == MODE_SI)
11758 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11760 return "sal{b}\t{%b2, %0|%0, %b2}";
11762 else if (operands[2] == const1_rtx
11763 && (TARGET_SHIFT1 || optimize_size))
11765 if (get_attr_mode (insn) == MODE_SI)
11766 return "sal{l}\t%0";
11768 return "sal{b}\t%0";
11772 if (get_attr_mode (insn) == MODE_SI)
11773 return "sal{l}\t{%2, %k0|%k0, %2}";
11775 return "sal{b}\t{%2, %0|%0, %2}";
11779 [(set (attr "type")
11780 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11782 (match_operand 0 "register_operand" ""))
11783 (match_operand 2 "const1_operand" ""))
11784 (const_string "alu")
11786 (const_string "ishift")))
11787 (set_attr "mode" "QI,SI")])
11789 ;; This pattern can't accept a variable shift count, since shifts by
11790 ;; zero don't affect the flags. We assume that shifts by constant
11791 ;; zero are optimized away.
11792 (define_insn "*ashlqi3_cmp"
11793 [(set (reg FLAGS_REG)
11795 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11796 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11798 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11799 (ashift:QI (match_dup 1) (match_dup 2)))]
11801 || !TARGET_PARTIAL_FLAG_REG_STALL
11802 || (operands[2] == const1_rtx
11804 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11805 && ix86_match_ccmode (insn, CCGOCmode)
11806 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11808 switch (get_attr_type (insn))
11811 gcc_assert (operands[2] == const1_rtx);
11812 return "add{b}\t%0, %0";
11815 if (REG_P (operands[2]))
11816 return "sal{b}\t{%b2, %0|%0, %b2}";
11817 else if (operands[2] == const1_rtx
11818 && (TARGET_SHIFT1 || optimize_size))
11819 return "sal{b}\t%0";
11821 return "sal{b}\t{%2, %0|%0, %2}";
11824 [(set (attr "type")
11825 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11827 (match_operand 0 "register_operand" ""))
11828 (match_operand 2 "const1_operand" ""))
11829 (const_string "alu")
11831 (const_string "ishift")))
11832 (set_attr "mode" "QI")])
11834 (define_insn "*ashlqi3_cconly"
11835 [(set (reg FLAGS_REG)
11837 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11838 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11840 (clobber (match_scratch:QI 0 "=q"))]
11842 || !TARGET_PARTIAL_FLAG_REG_STALL
11843 || (operands[2] == const1_rtx
11845 || TARGET_DOUBLE_WITH_ADD)))
11846 && ix86_match_ccmode (insn, CCGOCmode)
11847 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11849 switch (get_attr_type (insn))
11852 gcc_assert (operands[2] == const1_rtx);
11853 return "add{b}\t%0, %0";
11856 if (REG_P (operands[2]))
11857 return "sal{b}\t{%b2, %0|%0, %b2}";
11858 else if (operands[2] == const1_rtx
11859 && (TARGET_SHIFT1 || optimize_size))
11860 return "sal{b}\t%0";
11862 return "sal{b}\t{%2, %0|%0, %2}";
11865 [(set (attr "type")
11866 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11868 (match_operand 0 "register_operand" ""))
11869 (match_operand 2 "const1_operand" ""))
11870 (const_string "alu")
11872 (const_string "ishift")))
11873 (set_attr "mode" "QI")])
11875 ;; See comment above `ashldi3' about how this works.
11877 (define_expand "ashrti3"
11878 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11879 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11880 (match_operand:QI 2 "nonmemory_operand" "")))
11881 (clobber (reg:CC FLAGS_REG))])]
11884 if (! immediate_operand (operands[2], QImode))
11886 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11889 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11893 (define_insn "ashrti3_1"
11894 [(set (match_operand:TI 0 "register_operand" "=r")
11895 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11896 (match_operand:QI 2 "register_operand" "c")))
11897 (clobber (match_scratch:DI 3 "=&r"))
11898 (clobber (reg:CC FLAGS_REG))]
11901 [(set_attr "type" "multi")])
11903 (define_insn "*ashrti3_2"
11904 [(set (match_operand:TI 0 "register_operand" "=r")
11905 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11906 (match_operand:QI 2 "immediate_operand" "O")))
11907 (clobber (reg:CC FLAGS_REG))]
11910 [(set_attr "type" "multi")])
11913 [(set (match_operand:TI 0 "register_operand" "")
11914 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11915 (match_operand:QI 2 "register_operand" "")))
11916 (clobber (match_scratch:DI 3 ""))
11917 (clobber (reg:CC FLAGS_REG))]
11918 "TARGET_64BIT && reload_completed"
11920 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11923 [(set (match_operand:TI 0 "register_operand" "")
11924 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11925 (match_operand:QI 2 "immediate_operand" "")))
11926 (clobber (reg:CC FLAGS_REG))]
11927 "TARGET_64BIT && reload_completed"
11929 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11931 (define_insn "x86_64_shrd"
11932 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11933 (ior:DI (ashiftrt:DI (match_dup 0)
11934 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11935 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11936 (minus:QI (const_int 64) (match_dup 2)))))
11937 (clobber (reg:CC FLAGS_REG))]
11940 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11941 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11942 [(set_attr "type" "ishift")
11943 (set_attr "prefix_0f" "1")
11944 (set_attr "mode" "DI")
11945 (set_attr "athlon_decode" "vector")
11946 (set_attr "amdfam10_decode" "vector")])
11948 (define_expand "ashrdi3"
11949 [(set (match_operand:DI 0 "shiftdi_operand" "")
11950 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11951 (match_operand:QI 2 "nonmemory_operand" "")))]
11953 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11955 (define_insn "*ashrdi3_63_rex64"
11956 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11957 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11958 (match_operand:DI 2 "const_int_operand" "i,i")))
11959 (clobber (reg:CC FLAGS_REG))]
11960 "TARGET_64BIT && INTVAL (operands[2]) == 63
11961 && (TARGET_USE_CLTD || optimize_size)
11962 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11965 sar{q}\t{%2, %0|%0, %2}"
11966 [(set_attr "type" "imovx,ishift")
11967 (set_attr "prefix_0f" "0,*")
11968 (set_attr "length_immediate" "0,*")
11969 (set_attr "modrm" "0,1")
11970 (set_attr "mode" "DI")])
11972 (define_insn "*ashrdi3_1_one_bit_rex64"
11973 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11974 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11975 (match_operand:QI 2 "const1_operand" "")))
11976 (clobber (reg:CC FLAGS_REG))]
11978 && (TARGET_SHIFT1 || optimize_size)
11979 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11981 [(set_attr "type" "ishift")
11982 (set (attr "length")
11983 (if_then_else (match_operand:DI 0 "register_operand" "")
11985 (const_string "*")))])
11987 (define_insn "*ashrdi3_1_rex64"
11988 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11989 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11990 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11991 (clobber (reg:CC FLAGS_REG))]
11992 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11994 sar{q}\t{%2, %0|%0, %2}
11995 sar{q}\t{%b2, %0|%0, %b2}"
11996 [(set_attr "type" "ishift")
11997 (set_attr "mode" "DI")])
11999 ;; This pattern can't accept a variable shift count, since shifts by
12000 ;; zero don't affect the flags. We assume that shifts by constant
12001 ;; zero are optimized away.
12002 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12003 [(set (reg FLAGS_REG)
12005 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12006 (match_operand:QI 2 "const1_operand" ""))
12008 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12009 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12011 && (TARGET_SHIFT1 || optimize_size)
12012 && ix86_match_ccmode (insn, CCGOCmode)
12013 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12015 [(set_attr "type" "ishift")
12016 (set (attr "length")
12017 (if_then_else (match_operand:DI 0 "register_operand" "")
12019 (const_string "*")))])
12021 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12022 [(set (reg FLAGS_REG)
12024 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12025 (match_operand:QI 2 "const1_operand" ""))
12027 (clobber (match_scratch:DI 0 "=r"))]
12029 && (TARGET_SHIFT1 || optimize_size)
12030 && ix86_match_ccmode (insn, CCGOCmode)
12031 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12033 [(set_attr "type" "ishift")
12034 (set_attr "length" "2")])
12036 ;; This pattern can't accept a variable shift count, since shifts by
12037 ;; zero don't affect the flags. We assume that shifts by constant
12038 ;; zero are optimized away.
12039 (define_insn "*ashrdi3_cmp_rex64"
12040 [(set (reg FLAGS_REG)
12042 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12043 (match_operand:QI 2 "const_int_operand" "n"))
12045 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12046 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12048 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12049 && ix86_match_ccmode (insn, CCGOCmode)
12050 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12051 "sar{q}\t{%2, %0|%0, %2}"
12052 [(set_attr "type" "ishift")
12053 (set_attr "mode" "DI")])
12055 (define_insn "*ashrdi3_cconly_rex64"
12056 [(set (reg FLAGS_REG)
12058 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12059 (match_operand:QI 2 "const_int_operand" "n"))
12061 (clobber (match_scratch:DI 0 "=r"))]
12063 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12064 && ix86_match_ccmode (insn, CCGOCmode)
12065 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12066 "sar{q}\t{%2, %0|%0, %2}"
12067 [(set_attr "type" "ishift")
12068 (set_attr "mode" "DI")])
12070 (define_insn "*ashrdi3_1"
12071 [(set (match_operand:DI 0 "register_operand" "=r")
12072 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12073 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12074 (clobber (reg:CC FLAGS_REG))]
12077 [(set_attr "type" "multi")])
12079 ;; By default we don't ask for a scratch register, because when DImode
12080 ;; values are manipulated, registers are already at a premium. But if
12081 ;; we have one handy, we won't turn it away.
12083 [(match_scratch:SI 3 "r")
12084 (parallel [(set (match_operand:DI 0 "register_operand" "")
12085 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12086 (match_operand:QI 2 "nonmemory_operand" "")))
12087 (clobber (reg:CC FLAGS_REG))])
12089 "!TARGET_64BIT && TARGET_CMOVE"
12091 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12094 [(set (match_operand:DI 0 "register_operand" "")
12095 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12096 (match_operand:QI 2 "nonmemory_operand" "")))
12097 (clobber (reg:CC FLAGS_REG))]
12098 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12099 ? epilogue_completed : reload_completed)"
12101 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12103 (define_insn "x86_shrd_1"
12104 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12105 (ior:SI (ashiftrt:SI (match_dup 0)
12106 (match_operand:QI 2 "nonmemory_operand" "I,c"))
12107 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12108 (minus:QI (const_int 32) (match_dup 2)))))
12109 (clobber (reg:CC FLAGS_REG))]
12112 shrd{l}\t{%2, %1, %0|%0, %1, %2}
12113 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12114 [(set_attr "type" "ishift")
12115 (set_attr "prefix_0f" "1")
12116 (set_attr "pent_pair" "np")
12117 (set_attr "mode" "SI")])
12119 (define_expand "x86_shift_adj_3"
12120 [(use (match_operand:SI 0 "register_operand" ""))
12121 (use (match_operand:SI 1 "register_operand" ""))
12122 (use (match_operand:QI 2 "register_operand" ""))]
12125 rtx label = gen_label_rtx ();
12128 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12130 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12131 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12132 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12133 gen_rtx_LABEL_REF (VOIDmode, label),
12135 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12136 JUMP_LABEL (tmp) = label;
12138 emit_move_insn (operands[0], operands[1]);
12139 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12141 emit_label (label);
12142 LABEL_NUSES (label) = 1;
12147 (define_insn "ashrsi3_31"
12148 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12149 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12150 (match_operand:SI 2 "const_int_operand" "i,i")))
12151 (clobber (reg:CC FLAGS_REG))]
12152 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12153 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12156 sar{l}\t{%2, %0|%0, %2}"
12157 [(set_attr "type" "imovx,ishift")
12158 (set_attr "prefix_0f" "0,*")
12159 (set_attr "length_immediate" "0,*")
12160 (set_attr "modrm" "0,1")
12161 (set_attr "mode" "SI")])
12163 (define_insn "*ashrsi3_31_zext"
12164 [(set (match_operand:DI 0 "register_operand" "=*d,r")
12165 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12166 (match_operand:SI 2 "const_int_operand" "i,i"))))
12167 (clobber (reg:CC FLAGS_REG))]
12168 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12169 && INTVAL (operands[2]) == 31
12170 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12173 sar{l}\t{%2, %k0|%k0, %2}"
12174 [(set_attr "type" "imovx,ishift")
12175 (set_attr "prefix_0f" "0,*")
12176 (set_attr "length_immediate" "0,*")
12177 (set_attr "modrm" "0,1")
12178 (set_attr "mode" "SI")])
12180 (define_expand "ashrsi3"
12181 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12182 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12183 (match_operand:QI 2 "nonmemory_operand" "")))
12184 (clobber (reg:CC FLAGS_REG))]
12186 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12188 (define_insn "*ashrsi3_1_one_bit"
12189 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12190 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12191 (match_operand:QI 2 "const1_operand" "")))
12192 (clobber (reg:CC FLAGS_REG))]
12193 "(TARGET_SHIFT1 || optimize_size)
12194 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12196 [(set_attr "type" "ishift")
12197 (set (attr "length")
12198 (if_then_else (match_operand:SI 0 "register_operand" "")
12200 (const_string "*")))])
12202 (define_insn "*ashrsi3_1_one_bit_zext"
12203 [(set (match_operand:DI 0 "register_operand" "=r")
12204 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12205 (match_operand:QI 2 "const1_operand" ""))))
12206 (clobber (reg:CC FLAGS_REG))]
12208 && (TARGET_SHIFT1 || optimize_size)
12209 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12211 [(set_attr "type" "ishift")
12212 (set_attr "length" "2")])
12214 (define_insn "*ashrsi3_1"
12215 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12216 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12217 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12218 (clobber (reg:CC FLAGS_REG))]
12219 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12221 sar{l}\t{%2, %0|%0, %2}
12222 sar{l}\t{%b2, %0|%0, %b2}"
12223 [(set_attr "type" "ishift")
12224 (set_attr "mode" "SI")])
12226 (define_insn "*ashrsi3_1_zext"
12227 [(set (match_operand:DI 0 "register_operand" "=r,r")
12228 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12229 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12230 (clobber (reg:CC FLAGS_REG))]
12231 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12233 sar{l}\t{%2, %k0|%k0, %2}
12234 sar{l}\t{%b2, %k0|%k0, %b2}"
12235 [(set_attr "type" "ishift")
12236 (set_attr "mode" "SI")])
12238 ;; This pattern can't accept a variable shift count, since shifts by
12239 ;; zero don't affect the flags. We assume that shifts by constant
12240 ;; zero are optimized away.
12241 (define_insn "*ashrsi3_one_bit_cmp"
12242 [(set (reg FLAGS_REG)
12244 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12245 (match_operand:QI 2 "const1_operand" ""))
12247 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12248 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12249 "(TARGET_SHIFT1 || optimize_size)
12250 && ix86_match_ccmode (insn, CCGOCmode)
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_one_bit_cconly"
12260 [(set (reg FLAGS_REG)
12262 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12263 (match_operand:QI 2 "const1_operand" ""))
12265 (clobber (match_scratch:SI 0 "=r"))]
12266 "(TARGET_SHIFT1 || optimize_size)
12267 && ix86_match_ccmode (insn, CCGOCmode)
12268 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12270 [(set_attr "type" "ishift")
12271 (set_attr "length" "2")])
12273 (define_insn "*ashrsi3_one_bit_cmp_zext"
12274 [(set (reg FLAGS_REG)
12276 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12277 (match_operand:QI 2 "const1_operand" ""))
12279 (set (match_operand:DI 0 "register_operand" "=r")
12280 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12282 && (TARGET_SHIFT1 || optimize_size)
12283 && ix86_match_ccmode (insn, CCmode)
12284 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12286 [(set_attr "type" "ishift")
12287 (set_attr "length" "2")])
12289 ;; This pattern can't accept a variable shift count, since shifts by
12290 ;; zero don't affect the flags. We assume that shifts by constant
12291 ;; zero are optimized away.
12292 (define_insn "*ashrsi3_cmp"
12293 [(set (reg FLAGS_REG)
12295 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12296 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12298 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12299 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12300 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12301 && ix86_match_ccmode (insn, CCGOCmode)
12302 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12303 "sar{l}\t{%2, %0|%0, %2}"
12304 [(set_attr "type" "ishift")
12305 (set_attr "mode" "SI")])
12307 (define_insn "*ashrsi3_cconly"
12308 [(set (reg FLAGS_REG)
12310 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12311 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12313 (clobber (match_scratch:SI 0 "=r"))]
12314 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12315 && ix86_match_ccmode (insn, CCGOCmode)
12316 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12317 "sar{l}\t{%2, %0|%0, %2}"
12318 [(set_attr "type" "ishift")
12319 (set_attr "mode" "SI")])
12321 (define_insn "*ashrsi3_cmp_zext"
12322 [(set (reg FLAGS_REG)
12324 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12325 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12327 (set (match_operand:DI 0 "register_operand" "=r")
12328 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12330 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12331 && ix86_match_ccmode (insn, CCGOCmode)
12332 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12333 "sar{l}\t{%2, %k0|%k0, %2}"
12334 [(set_attr "type" "ishift")
12335 (set_attr "mode" "SI")])
12337 (define_expand "ashrhi3"
12338 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12339 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12340 (match_operand:QI 2 "nonmemory_operand" "")))
12341 (clobber (reg:CC FLAGS_REG))]
12342 "TARGET_HIMODE_MATH"
12343 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12345 (define_insn "*ashrhi3_1_one_bit"
12346 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12347 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12348 (match_operand:QI 2 "const1_operand" "")))
12349 (clobber (reg:CC FLAGS_REG))]
12350 "(TARGET_SHIFT1 || optimize_size)
12351 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12353 [(set_attr "type" "ishift")
12354 (set (attr "length")
12355 (if_then_else (match_operand 0 "register_operand" "")
12357 (const_string "*")))])
12359 (define_insn "*ashrhi3_1"
12360 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12361 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12362 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12363 (clobber (reg:CC FLAGS_REG))]
12364 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12366 sar{w}\t{%2, %0|%0, %2}
12367 sar{w}\t{%b2, %0|%0, %b2}"
12368 [(set_attr "type" "ishift")
12369 (set_attr "mode" "HI")])
12371 ;; This pattern can't accept a variable shift count, since shifts by
12372 ;; zero don't affect the flags. We assume that shifts by constant
12373 ;; zero are optimized away.
12374 (define_insn "*ashrhi3_one_bit_cmp"
12375 [(set (reg FLAGS_REG)
12377 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12378 (match_operand:QI 2 "const1_operand" ""))
12380 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12381 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12382 "(TARGET_SHIFT1 || optimize_size)
12383 && ix86_match_ccmode (insn, CCGOCmode)
12384 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12386 [(set_attr "type" "ishift")
12387 (set (attr "length")
12388 (if_then_else (match_operand 0 "register_operand" "")
12390 (const_string "*")))])
12392 (define_insn "*ashrhi3_one_bit_cconly"
12393 [(set (reg FLAGS_REG)
12395 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12396 (match_operand:QI 2 "const1_operand" ""))
12398 (clobber (match_scratch:HI 0 "=r"))]
12399 "(TARGET_SHIFT1 || optimize_size)
12400 && ix86_match_ccmode (insn, CCGOCmode)
12401 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12403 [(set_attr "type" "ishift")
12404 (set_attr "length" "2")])
12406 ;; This pattern can't accept a variable shift count, since shifts by
12407 ;; zero don't affect the flags. We assume that shifts by constant
12408 ;; zero are optimized away.
12409 (define_insn "*ashrhi3_cmp"
12410 [(set (reg FLAGS_REG)
12412 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12413 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12415 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12416 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12417 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12418 && ix86_match_ccmode (insn, CCGOCmode)
12419 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12420 "sar{w}\t{%2, %0|%0, %2}"
12421 [(set_attr "type" "ishift")
12422 (set_attr "mode" "HI")])
12424 (define_insn "*ashrhi3_cconly"
12425 [(set (reg FLAGS_REG)
12427 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12428 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12430 (clobber (match_scratch:HI 0 "=r"))]
12431 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12432 && ix86_match_ccmode (insn, CCGOCmode)
12433 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12434 "sar{w}\t{%2, %0|%0, %2}"
12435 [(set_attr "type" "ishift")
12436 (set_attr "mode" "HI")])
12438 (define_expand "ashrqi3"
12439 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12440 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12441 (match_operand:QI 2 "nonmemory_operand" "")))
12442 (clobber (reg:CC FLAGS_REG))]
12443 "TARGET_QIMODE_MATH"
12444 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12446 (define_insn "*ashrqi3_1_one_bit"
12447 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12448 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12449 (match_operand:QI 2 "const1_operand" "")))
12450 (clobber (reg:CC FLAGS_REG))]
12451 "(TARGET_SHIFT1 || optimize_size)
12452 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12454 [(set_attr "type" "ishift")
12455 (set (attr "length")
12456 (if_then_else (match_operand 0 "register_operand" "")
12458 (const_string "*")))])
12460 (define_insn "*ashrqi3_1_one_bit_slp"
12461 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12462 (ashiftrt:QI (match_dup 0)
12463 (match_operand:QI 1 "const1_operand" "")))
12464 (clobber (reg:CC FLAGS_REG))]
12465 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12466 && (TARGET_SHIFT1 || optimize_size)
12467 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12469 [(set_attr "type" "ishift1")
12470 (set (attr "length")
12471 (if_then_else (match_operand 0 "register_operand" "")
12473 (const_string "*")))])
12475 (define_insn "*ashrqi3_1"
12476 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12477 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12478 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12479 (clobber (reg:CC FLAGS_REG))]
12480 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12482 sar{b}\t{%2, %0|%0, %2}
12483 sar{b}\t{%b2, %0|%0, %b2}"
12484 [(set_attr "type" "ishift")
12485 (set_attr "mode" "QI")])
12487 (define_insn "*ashrqi3_1_slp"
12488 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12489 (ashiftrt:QI (match_dup 0)
12490 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12491 (clobber (reg:CC FLAGS_REG))]
12492 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12493 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12495 sar{b}\t{%1, %0|%0, %1}
12496 sar{b}\t{%b1, %0|%0, %b1}"
12497 [(set_attr "type" "ishift1")
12498 (set_attr "mode" "QI")])
12500 ;; This pattern can't accept a variable shift count, since shifts by
12501 ;; zero don't affect the flags. We assume that shifts by constant
12502 ;; zero are optimized away.
12503 (define_insn "*ashrqi3_one_bit_cmp"
12504 [(set (reg FLAGS_REG)
12506 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12507 (match_operand:QI 2 "const1_operand" "I"))
12509 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12510 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12511 "(TARGET_SHIFT1 || optimize_size)
12512 && ix86_match_ccmode (insn, CCGOCmode)
12513 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12515 [(set_attr "type" "ishift")
12516 (set (attr "length")
12517 (if_then_else (match_operand 0 "register_operand" "")
12519 (const_string "*")))])
12521 (define_insn "*ashrqi3_one_bit_cconly"
12522 [(set (reg FLAGS_REG)
12524 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12525 (match_operand:QI 2 "const1_operand" "I"))
12527 (clobber (match_scratch:QI 0 "=q"))]
12528 "(TARGET_SHIFT1 || optimize_size)
12529 && ix86_match_ccmode (insn, CCGOCmode)
12530 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12532 [(set_attr "type" "ishift")
12533 (set_attr "length" "2")])
12535 ;; This pattern can't accept a variable shift count, since shifts by
12536 ;; zero don't affect the flags. We assume that shifts by constant
12537 ;; zero are optimized away.
12538 (define_insn "*ashrqi3_cmp"
12539 [(set (reg FLAGS_REG)
12541 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12542 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12544 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12545 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12546 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12547 && ix86_match_ccmode (insn, CCGOCmode)
12548 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12549 "sar{b}\t{%2, %0|%0, %2}"
12550 [(set_attr "type" "ishift")
12551 (set_attr "mode" "QI")])
12553 (define_insn "*ashrqi3_cconly"
12554 [(set (reg FLAGS_REG)
12556 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12557 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12559 (clobber (match_scratch:QI 0 "=q"))]
12560 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12561 && ix86_match_ccmode (insn, CCGOCmode)
12562 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12563 "sar{b}\t{%2, %0|%0, %2}"
12564 [(set_attr "type" "ishift")
12565 (set_attr "mode" "QI")])
12568 ;; Logical shift instructions
12570 ;; See comment above `ashldi3' about how this works.
12572 (define_expand "lshrti3"
12573 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12574 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12575 (match_operand:QI 2 "nonmemory_operand" "")))
12576 (clobber (reg:CC FLAGS_REG))])]
12579 if (! immediate_operand (operands[2], QImode))
12581 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12584 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12588 (define_insn "lshrti3_1"
12589 [(set (match_operand:TI 0 "register_operand" "=r")
12590 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12591 (match_operand:QI 2 "register_operand" "c")))
12592 (clobber (match_scratch:DI 3 "=&r"))
12593 (clobber (reg:CC FLAGS_REG))]
12596 [(set_attr "type" "multi")])
12598 ;; This pattern must be defined before *lshrti3_2 to prevent
12599 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12601 (define_insn "sse2_lshrti3"
12602 [(set (match_operand:TI 0 "register_operand" "=x")
12603 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12604 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12607 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12608 return "psrldq\t{%2, %0|%0, %2}";
12610 [(set_attr "type" "sseishft")
12611 (set_attr "prefix_data16" "1")
12612 (set_attr "mode" "TI")])
12614 (define_insn "*lshrti3_2"
12615 [(set (match_operand:TI 0 "register_operand" "=r")
12616 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12617 (match_operand:QI 2 "immediate_operand" "O")))
12618 (clobber (reg:CC FLAGS_REG))]
12621 [(set_attr "type" "multi")])
12624 [(set (match_operand:TI 0 "register_operand" "")
12625 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12626 (match_operand:QI 2 "register_operand" "")))
12627 (clobber (match_scratch:DI 3 ""))
12628 (clobber (reg:CC FLAGS_REG))]
12629 "TARGET_64BIT && reload_completed"
12631 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12634 [(set (match_operand:TI 0 "register_operand" "")
12635 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12636 (match_operand:QI 2 "immediate_operand" "")))
12637 (clobber (reg:CC FLAGS_REG))]
12638 "TARGET_64BIT && reload_completed"
12640 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12642 (define_expand "lshrdi3"
12643 [(set (match_operand:DI 0 "shiftdi_operand" "")
12644 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12645 (match_operand:QI 2 "nonmemory_operand" "")))]
12647 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12649 (define_insn "*lshrdi3_1_one_bit_rex64"
12650 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12651 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12652 (match_operand:QI 2 "const1_operand" "")))
12653 (clobber (reg:CC FLAGS_REG))]
12655 && (TARGET_SHIFT1 || optimize_size)
12656 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12658 [(set_attr "type" "ishift")
12659 (set (attr "length")
12660 (if_then_else (match_operand:DI 0 "register_operand" "")
12662 (const_string "*")))])
12664 (define_insn "*lshrdi3_1_rex64"
12665 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12666 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12667 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12668 (clobber (reg:CC FLAGS_REG))]
12669 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12671 shr{q}\t{%2, %0|%0, %2}
12672 shr{q}\t{%b2, %0|%0, %b2}"
12673 [(set_attr "type" "ishift")
12674 (set_attr "mode" "DI")])
12676 ;; This pattern can't accept a variable shift count, since shifts by
12677 ;; zero don't affect the flags. We assume that shifts by constant
12678 ;; zero are optimized away.
12679 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12680 [(set (reg FLAGS_REG)
12682 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12683 (match_operand:QI 2 "const1_operand" ""))
12685 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12686 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12688 && (TARGET_SHIFT1 || optimize_size)
12689 && ix86_match_ccmode (insn, CCGOCmode)
12690 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12692 [(set_attr "type" "ishift")
12693 (set (attr "length")
12694 (if_then_else (match_operand:DI 0 "register_operand" "")
12696 (const_string "*")))])
12698 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12699 [(set (reg FLAGS_REG)
12701 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12702 (match_operand:QI 2 "const1_operand" ""))
12704 (clobber (match_scratch:DI 0 "=r"))]
12706 && (TARGET_SHIFT1 || optimize_size)
12707 && ix86_match_ccmode (insn, CCGOCmode)
12708 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12710 [(set_attr "type" "ishift")
12711 (set_attr "length" "2")])
12713 ;; This pattern can't accept a variable shift count, since shifts by
12714 ;; zero don't affect the flags. We assume that shifts by constant
12715 ;; zero are optimized away.
12716 (define_insn "*lshrdi3_cmp_rex64"
12717 [(set (reg FLAGS_REG)
12719 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12720 (match_operand:QI 2 "const_int_operand" "e"))
12722 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12723 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12725 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12726 && ix86_match_ccmode (insn, CCGOCmode)
12727 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12728 "shr{q}\t{%2, %0|%0, %2}"
12729 [(set_attr "type" "ishift")
12730 (set_attr "mode" "DI")])
12732 (define_insn "*lshrdi3_cconly_rex64"
12733 [(set (reg FLAGS_REG)
12735 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12736 (match_operand:QI 2 "const_int_operand" "e"))
12738 (clobber (match_scratch:DI 0 "=r"))]
12740 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12741 && ix86_match_ccmode (insn, CCGOCmode)
12742 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12743 "shr{q}\t{%2, %0|%0, %2}"
12744 [(set_attr "type" "ishift")
12745 (set_attr "mode" "DI")])
12747 (define_insn "*lshrdi3_1"
12748 [(set (match_operand:DI 0 "register_operand" "=r")
12749 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12750 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12751 (clobber (reg:CC FLAGS_REG))]
12754 [(set_attr "type" "multi")])
12756 ;; By default we don't ask for a scratch register, because when DImode
12757 ;; values are manipulated, registers are already at a premium. But if
12758 ;; we have one handy, we won't turn it away.
12760 [(match_scratch:SI 3 "r")
12761 (parallel [(set (match_operand:DI 0 "register_operand" "")
12762 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12763 (match_operand:QI 2 "nonmemory_operand" "")))
12764 (clobber (reg:CC FLAGS_REG))])
12766 "!TARGET_64BIT && TARGET_CMOVE"
12768 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12771 [(set (match_operand:DI 0 "register_operand" "")
12772 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12773 (match_operand:QI 2 "nonmemory_operand" "")))
12774 (clobber (reg:CC FLAGS_REG))]
12775 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12776 ? epilogue_completed : reload_completed)"
12778 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12780 (define_expand "lshrsi3"
12781 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12782 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12783 (match_operand:QI 2 "nonmemory_operand" "")))
12784 (clobber (reg:CC FLAGS_REG))]
12786 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12788 (define_insn "*lshrsi3_1_one_bit"
12789 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12790 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12791 (match_operand:QI 2 "const1_operand" "")))
12792 (clobber (reg:CC FLAGS_REG))]
12793 "(TARGET_SHIFT1 || optimize_size)
12794 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12796 [(set_attr "type" "ishift")
12797 (set (attr "length")
12798 (if_then_else (match_operand:SI 0 "register_operand" "")
12800 (const_string "*")))])
12802 (define_insn "*lshrsi3_1_one_bit_zext"
12803 [(set (match_operand:DI 0 "register_operand" "=r")
12804 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12805 (match_operand:QI 2 "const1_operand" "")))
12806 (clobber (reg:CC FLAGS_REG))]
12808 && (TARGET_SHIFT1 || optimize_size)
12809 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12811 [(set_attr "type" "ishift")
12812 (set_attr "length" "2")])
12814 (define_insn "*lshrsi3_1"
12815 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12816 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12817 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12818 (clobber (reg:CC FLAGS_REG))]
12819 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12821 shr{l}\t{%2, %0|%0, %2}
12822 shr{l}\t{%b2, %0|%0, %b2}"
12823 [(set_attr "type" "ishift")
12824 (set_attr "mode" "SI")])
12826 (define_insn "*lshrsi3_1_zext"
12827 [(set (match_operand:DI 0 "register_operand" "=r,r")
12829 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12830 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12831 (clobber (reg:CC FLAGS_REG))]
12832 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12834 shr{l}\t{%2, %k0|%k0, %2}
12835 shr{l}\t{%b2, %k0|%k0, %b2}"
12836 [(set_attr "type" "ishift")
12837 (set_attr "mode" "SI")])
12839 ;; This pattern can't accept a variable shift count, since shifts by
12840 ;; zero don't affect the flags. We assume that shifts by constant
12841 ;; zero are optimized away.
12842 (define_insn "*lshrsi3_one_bit_cmp"
12843 [(set (reg FLAGS_REG)
12845 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12846 (match_operand:QI 2 "const1_operand" ""))
12848 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12849 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12850 "(TARGET_SHIFT1 || optimize_size)
12851 && ix86_match_ccmode (insn, CCGOCmode)
12852 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12854 [(set_attr "type" "ishift")
12855 (set (attr "length")
12856 (if_then_else (match_operand:SI 0 "register_operand" "")
12858 (const_string "*")))])
12860 (define_insn "*lshrsi3_one_bit_cconly"
12861 [(set (reg FLAGS_REG)
12863 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12864 (match_operand:QI 2 "const1_operand" ""))
12866 (clobber (match_scratch:SI 0 "=r"))]
12867 "(TARGET_SHIFT1 || optimize_size)
12868 && ix86_match_ccmode (insn, CCGOCmode)
12869 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12871 [(set_attr "type" "ishift")
12872 (set_attr "length" "2")])
12874 (define_insn "*lshrsi3_cmp_one_bit_zext"
12875 [(set (reg FLAGS_REG)
12877 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12878 (match_operand:QI 2 "const1_operand" ""))
12880 (set (match_operand:DI 0 "register_operand" "=r")
12881 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12883 && (TARGET_SHIFT1 || optimize_size)
12884 && ix86_match_ccmode (insn, CCGOCmode)
12885 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12887 [(set_attr "type" "ishift")
12888 (set_attr "length" "2")])
12890 ;; This pattern can't accept a variable shift count, since shifts by
12891 ;; zero don't affect the flags. We assume that shifts by constant
12892 ;; zero are optimized away.
12893 (define_insn "*lshrsi3_cmp"
12894 [(set (reg FLAGS_REG)
12896 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12897 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12899 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12900 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12901 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12902 && ix86_match_ccmode (insn, CCGOCmode)
12903 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12904 "shr{l}\t{%2, %0|%0, %2}"
12905 [(set_attr "type" "ishift")
12906 (set_attr "mode" "SI")])
12908 (define_insn "*lshrsi3_cconly"
12909 [(set (reg FLAGS_REG)
12911 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12912 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12914 (clobber (match_scratch:SI 0 "=r"))]
12915 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12916 && ix86_match_ccmode (insn, CCGOCmode)
12917 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12918 "shr{l}\t{%2, %0|%0, %2}"
12919 [(set_attr "type" "ishift")
12920 (set_attr "mode" "SI")])
12922 (define_insn "*lshrsi3_cmp_zext"
12923 [(set (reg FLAGS_REG)
12925 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12926 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12928 (set (match_operand:DI 0 "register_operand" "=r")
12929 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12931 && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12932 && ix86_match_ccmode (insn, CCGOCmode)
12933 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12934 "shr{l}\t{%2, %k0|%k0, %2}"
12935 [(set_attr "type" "ishift")
12936 (set_attr "mode" "SI")])
12938 (define_expand "lshrhi3"
12939 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12940 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12941 (match_operand:QI 2 "nonmemory_operand" "")))
12942 (clobber (reg:CC FLAGS_REG))]
12943 "TARGET_HIMODE_MATH"
12944 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12946 (define_insn "*lshrhi3_1_one_bit"
12947 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12948 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12949 (match_operand:QI 2 "const1_operand" "")))
12950 (clobber (reg:CC FLAGS_REG))]
12951 "(TARGET_SHIFT1 || optimize_size)
12952 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12954 [(set_attr "type" "ishift")
12955 (set (attr "length")
12956 (if_then_else (match_operand 0 "register_operand" "")
12958 (const_string "*")))])
12960 (define_insn "*lshrhi3_1"
12961 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12962 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12963 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12964 (clobber (reg:CC FLAGS_REG))]
12965 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12967 shr{w}\t{%2, %0|%0, %2}
12968 shr{w}\t{%b2, %0|%0, %b2}"
12969 [(set_attr "type" "ishift")
12970 (set_attr "mode" "HI")])
12972 ;; This pattern can't accept a variable shift count, since shifts by
12973 ;; zero don't affect the flags. We assume that shifts by constant
12974 ;; zero are optimized away.
12975 (define_insn "*lshrhi3_one_bit_cmp"
12976 [(set (reg FLAGS_REG)
12978 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12979 (match_operand:QI 2 "const1_operand" ""))
12981 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12982 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12983 "(TARGET_SHIFT1 || optimize_size)
12984 && ix86_match_ccmode (insn, CCGOCmode)
12985 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12987 [(set_attr "type" "ishift")
12988 (set (attr "length")
12989 (if_then_else (match_operand:SI 0 "register_operand" "")
12991 (const_string "*")))])
12993 (define_insn "*lshrhi3_one_bit_cconly"
12994 [(set (reg FLAGS_REG)
12996 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12997 (match_operand:QI 2 "const1_operand" ""))
12999 (clobber (match_scratch:HI 0 "=r"))]
13000 "(TARGET_SHIFT1 || optimize_size)
13001 && ix86_match_ccmode (insn, CCGOCmode)
13002 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13004 [(set_attr "type" "ishift")
13005 (set_attr "length" "2")])
13007 ;; This pattern can't accept a variable shift count, since shifts by
13008 ;; zero don't affect the flags. We assume that shifts by constant
13009 ;; zero are optimized away.
13010 (define_insn "*lshrhi3_cmp"
13011 [(set (reg FLAGS_REG)
13013 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13014 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13016 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13017 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13018 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13019 && ix86_match_ccmode (insn, CCGOCmode)
13020 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13021 "shr{w}\t{%2, %0|%0, %2}"
13022 [(set_attr "type" "ishift")
13023 (set_attr "mode" "HI")])
13025 (define_insn "*lshrhi3_cconly"
13026 [(set (reg FLAGS_REG)
13028 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13029 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13031 (clobber (match_scratch:HI 0 "=r"))]
13032 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13033 && ix86_match_ccmode (insn, CCGOCmode)
13034 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13035 "shr{w}\t{%2, %0|%0, %2}"
13036 [(set_attr "type" "ishift")
13037 (set_attr "mode" "HI")])
13039 (define_expand "lshrqi3"
13040 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13041 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13042 (match_operand:QI 2 "nonmemory_operand" "")))
13043 (clobber (reg:CC FLAGS_REG))]
13044 "TARGET_QIMODE_MATH"
13045 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13047 (define_insn "*lshrqi3_1_one_bit"
13048 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13049 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13050 (match_operand:QI 2 "const1_operand" "")))
13051 (clobber (reg:CC FLAGS_REG))]
13052 "(TARGET_SHIFT1 || optimize_size)
13053 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13055 [(set_attr "type" "ishift")
13056 (set (attr "length")
13057 (if_then_else (match_operand 0 "register_operand" "")
13059 (const_string "*")))])
13061 (define_insn "*lshrqi3_1_one_bit_slp"
13062 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13063 (lshiftrt:QI (match_dup 0)
13064 (match_operand:QI 1 "const1_operand" "")))
13065 (clobber (reg:CC FLAGS_REG))]
13066 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13067 && (TARGET_SHIFT1 || optimize_size)"
13069 [(set_attr "type" "ishift1")
13070 (set (attr "length")
13071 (if_then_else (match_operand 0 "register_operand" "")
13073 (const_string "*")))])
13075 (define_insn "*lshrqi3_1"
13076 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13077 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13078 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13079 (clobber (reg:CC FLAGS_REG))]
13080 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13082 shr{b}\t{%2, %0|%0, %2}
13083 shr{b}\t{%b2, %0|%0, %b2}"
13084 [(set_attr "type" "ishift")
13085 (set_attr "mode" "QI")])
13087 (define_insn "*lshrqi3_1_slp"
13088 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13089 (lshiftrt:QI (match_dup 0)
13090 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13091 (clobber (reg:CC FLAGS_REG))]
13092 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13093 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13095 shr{b}\t{%1, %0|%0, %1}
13096 shr{b}\t{%b1, %0|%0, %b1}"
13097 [(set_attr "type" "ishift1")
13098 (set_attr "mode" "QI")])
13100 ;; This pattern can't accept a variable shift count, since shifts by
13101 ;; zero don't affect the flags. We assume that shifts by constant
13102 ;; zero are optimized away.
13103 (define_insn "*lshrqi2_one_bit_cmp"
13104 [(set (reg FLAGS_REG)
13106 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13107 (match_operand:QI 2 "const1_operand" ""))
13109 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13110 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13111 "(TARGET_SHIFT1 || optimize_size)
13112 && ix86_match_ccmode (insn, CCGOCmode)
13113 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13115 [(set_attr "type" "ishift")
13116 (set (attr "length")
13117 (if_then_else (match_operand:SI 0 "register_operand" "")
13119 (const_string "*")))])
13121 (define_insn "*lshrqi2_one_bit_cconly"
13122 [(set (reg FLAGS_REG)
13124 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13125 (match_operand:QI 2 "const1_operand" ""))
13127 (clobber (match_scratch:QI 0 "=q"))]
13128 "(TARGET_SHIFT1 || optimize_size)
13129 && ix86_match_ccmode (insn, CCGOCmode)
13130 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13132 [(set_attr "type" "ishift")
13133 (set_attr "length" "2")])
13135 ;; This pattern can't accept a variable shift count, since shifts by
13136 ;; zero don't affect the flags. We assume that shifts by constant
13137 ;; zero are optimized away.
13138 (define_insn "*lshrqi2_cmp"
13139 [(set (reg FLAGS_REG)
13141 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13142 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13144 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13145 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13146 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13147 && ix86_match_ccmode (insn, CCGOCmode)
13148 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13149 "shr{b}\t{%2, %0|%0, %2}"
13150 [(set_attr "type" "ishift")
13151 (set_attr "mode" "QI")])
13153 (define_insn "*lshrqi2_cconly"
13154 [(set (reg FLAGS_REG)
13156 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13157 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13159 (clobber (match_scratch:QI 0 "=q"))]
13160 "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13161 && ix86_match_ccmode (insn, CCGOCmode)
13162 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13163 "shr{b}\t{%2, %0|%0, %2}"
13164 [(set_attr "type" "ishift")
13165 (set_attr "mode" "QI")])
13167 ;; Rotate instructions
13169 (define_expand "rotldi3"
13170 [(set (match_operand:DI 0 "shiftdi_operand" "")
13171 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13172 (match_operand:QI 2 "nonmemory_operand" "")))
13173 (clobber (reg:CC FLAGS_REG))]
13178 ix86_expand_binary_operator (ROTATE, DImode, operands);
13181 if (!const_1_to_31_operand (operands[2], VOIDmode))
13183 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13187 ;; Implement rotation using two double-precision shift instructions
13188 ;; and a scratch register.
13189 (define_insn_and_split "ix86_rotldi3"
13190 [(set (match_operand:DI 0 "register_operand" "=r")
13191 (rotate:DI (match_operand:DI 1 "register_operand" "0")
13192 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13193 (clobber (reg:CC FLAGS_REG))
13194 (clobber (match_scratch:SI 3 "=&r"))]
13197 "&& reload_completed"
13198 [(set (match_dup 3) (match_dup 4))
13200 [(set (match_dup 4)
13201 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13202 (lshiftrt:SI (match_dup 5)
13203 (minus:QI (const_int 32) (match_dup 2)))))
13204 (clobber (reg:CC FLAGS_REG))])
13206 [(set (match_dup 5)
13207 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13208 (lshiftrt:SI (match_dup 3)
13209 (minus:QI (const_int 32) (match_dup 2)))))
13210 (clobber (reg:CC FLAGS_REG))])]
13211 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13213 (define_insn "*rotlsi3_1_one_bit_rex64"
13214 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13215 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13216 (match_operand:QI 2 "const1_operand" "")))
13217 (clobber (reg:CC FLAGS_REG))]
13219 && (TARGET_SHIFT1 || optimize_size)
13220 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13222 [(set_attr "type" "rotate")
13223 (set (attr "length")
13224 (if_then_else (match_operand:DI 0 "register_operand" "")
13226 (const_string "*")))])
13228 (define_insn "*rotldi3_1_rex64"
13229 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13230 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13231 (match_operand:QI 2 "nonmemory_operand" "e,c")))
13232 (clobber (reg:CC FLAGS_REG))]
13233 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13235 rol{q}\t{%2, %0|%0, %2}
13236 rol{q}\t{%b2, %0|%0, %b2}"
13237 [(set_attr "type" "rotate")
13238 (set_attr "mode" "DI")])
13240 (define_expand "rotlsi3"
13241 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13242 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13243 (match_operand:QI 2 "nonmemory_operand" "")))
13244 (clobber (reg:CC FLAGS_REG))]
13246 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13248 (define_insn "*rotlsi3_1_one_bit"
13249 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13250 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13251 (match_operand:QI 2 "const1_operand" "")))
13252 (clobber (reg:CC FLAGS_REG))]
13253 "(TARGET_SHIFT1 || optimize_size)
13254 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13256 [(set_attr "type" "rotate")
13257 (set (attr "length")
13258 (if_then_else (match_operand:SI 0 "register_operand" "")
13260 (const_string "*")))])
13262 (define_insn "*rotlsi3_1_one_bit_zext"
13263 [(set (match_operand:DI 0 "register_operand" "=r")
13265 (rotate:SI (match_operand:SI 1 "register_operand" "0")
13266 (match_operand:QI 2 "const1_operand" ""))))
13267 (clobber (reg:CC FLAGS_REG))]
13269 && (TARGET_SHIFT1 || optimize_size)
13270 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13272 [(set_attr "type" "rotate")
13273 (set_attr "length" "2")])
13275 (define_insn "*rotlsi3_1"
13276 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13277 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13278 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13279 (clobber (reg:CC FLAGS_REG))]
13280 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13282 rol{l}\t{%2, %0|%0, %2}
13283 rol{l}\t{%b2, %0|%0, %b2}"
13284 [(set_attr "type" "rotate")
13285 (set_attr "mode" "SI")])
13287 (define_insn "*rotlsi3_1_zext"
13288 [(set (match_operand:DI 0 "register_operand" "=r,r")
13290 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13291 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13292 (clobber (reg:CC FLAGS_REG))]
13293 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13295 rol{l}\t{%2, %k0|%k0, %2}
13296 rol{l}\t{%b2, %k0|%k0, %b2}"
13297 [(set_attr "type" "rotate")
13298 (set_attr "mode" "SI")])
13300 (define_expand "rotlhi3"
13301 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13302 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13303 (match_operand:QI 2 "nonmemory_operand" "")))
13304 (clobber (reg:CC FLAGS_REG))]
13305 "TARGET_HIMODE_MATH"
13306 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13308 (define_insn "*rotlhi3_1_one_bit"
13309 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13310 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13311 (match_operand:QI 2 "const1_operand" "")))
13312 (clobber (reg:CC FLAGS_REG))]
13313 "(TARGET_SHIFT1 || optimize_size)
13314 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13316 [(set_attr "type" "rotate")
13317 (set (attr "length")
13318 (if_then_else (match_operand 0 "register_operand" "")
13320 (const_string "*")))])
13322 (define_insn "*rotlhi3_1"
13323 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13324 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13325 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13326 (clobber (reg:CC FLAGS_REG))]
13327 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13329 rol{w}\t{%2, %0|%0, %2}
13330 rol{w}\t{%b2, %0|%0, %b2}"
13331 [(set_attr "type" "rotate")
13332 (set_attr "mode" "HI")])
13335 [(set (match_operand:HI 0 "register_operand" "")
13336 (rotate:HI (match_dup 0) (const_int 8)))
13337 (clobber (reg:CC FLAGS_REG))]
13339 [(parallel [(set (strict_low_part (match_dup 0))
13340 (bswap:HI (match_dup 0)))
13341 (clobber (reg:CC FLAGS_REG))])]
13344 (define_expand "rotlqi3"
13345 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13346 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13347 (match_operand:QI 2 "nonmemory_operand" "")))
13348 (clobber (reg:CC FLAGS_REG))]
13349 "TARGET_QIMODE_MATH"
13350 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13352 (define_insn "*rotlqi3_1_one_bit_slp"
13353 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13354 (rotate:QI (match_dup 0)
13355 (match_operand:QI 1 "const1_operand" "")))
13356 (clobber (reg:CC FLAGS_REG))]
13357 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13358 && (TARGET_SHIFT1 || optimize_size)"
13360 [(set_attr "type" "rotate1")
13361 (set (attr "length")
13362 (if_then_else (match_operand 0 "register_operand" "")
13364 (const_string "*")))])
13366 (define_insn "*rotlqi3_1_one_bit"
13367 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13368 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13369 (match_operand:QI 2 "const1_operand" "")))
13370 (clobber (reg:CC FLAGS_REG))]
13371 "(TARGET_SHIFT1 || optimize_size)
13372 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13374 [(set_attr "type" "rotate")
13375 (set (attr "length")
13376 (if_then_else (match_operand 0 "register_operand" "")
13378 (const_string "*")))])
13380 (define_insn "*rotlqi3_1_slp"
13381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13382 (rotate:QI (match_dup 0)
13383 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13384 (clobber (reg:CC FLAGS_REG))]
13385 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13386 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13388 rol{b}\t{%1, %0|%0, %1}
13389 rol{b}\t{%b1, %0|%0, %b1}"
13390 [(set_attr "type" "rotate1")
13391 (set_attr "mode" "QI")])
13393 (define_insn "*rotlqi3_1"
13394 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13395 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13396 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13397 (clobber (reg:CC FLAGS_REG))]
13398 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13400 rol{b}\t{%2, %0|%0, %2}
13401 rol{b}\t{%b2, %0|%0, %b2}"
13402 [(set_attr "type" "rotate")
13403 (set_attr "mode" "QI")])
13405 (define_expand "rotrdi3"
13406 [(set (match_operand:DI 0 "shiftdi_operand" "")
13407 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13408 (match_operand:QI 2 "nonmemory_operand" "")))
13409 (clobber (reg:CC FLAGS_REG))]
13414 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13417 if (!const_1_to_31_operand (operands[2], VOIDmode))
13419 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13423 ;; Implement rotation using two double-precision shift instructions
13424 ;; and a scratch register.
13425 (define_insn_and_split "ix86_rotrdi3"
13426 [(set (match_operand:DI 0 "register_operand" "=r")
13427 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13428 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13429 (clobber (reg:CC FLAGS_REG))
13430 (clobber (match_scratch:SI 3 "=&r"))]
13433 "&& reload_completed"
13434 [(set (match_dup 3) (match_dup 4))
13436 [(set (match_dup 4)
13437 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13438 (ashift:SI (match_dup 5)
13439 (minus:QI (const_int 32) (match_dup 2)))))
13440 (clobber (reg:CC FLAGS_REG))])
13442 [(set (match_dup 5)
13443 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13444 (ashift:SI (match_dup 3)
13445 (minus:QI (const_int 32) (match_dup 2)))))
13446 (clobber (reg:CC FLAGS_REG))])]
13447 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13449 (define_insn "*rotrdi3_1_one_bit_rex64"
13450 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13451 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13452 (match_operand:QI 2 "const1_operand" "")))
13453 (clobber (reg:CC FLAGS_REG))]
13455 && (TARGET_SHIFT1 || optimize_size)
13456 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13458 [(set_attr "type" "rotate")
13459 (set (attr "length")
13460 (if_then_else (match_operand:DI 0 "register_operand" "")
13462 (const_string "*")))])
13464 (define_insn "*rotrdi3_1_rex64"
13465 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13466 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13467 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13468 (clobber (reg:CC FLAGS_REG))]
13469 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13471 ror{q}\t{%2, %0|%0, %2}
13472 ror{q}\t{%b2, %0|%0, %b2}"
13473 [(set_attr "type" "rotate")
13474 (set_attr "mode" "DI")])
13476 (define_expand "rotrsi3"
13477 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13478 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13479 (match_operand:QI 2 "nonmemory_operand" "")))
13480 (clobber (reg:CC FLAGS_REG))]
13482 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13484 (define_insn "*rotrsi3_1_one_bit"
13485 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13486 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13487 (match_operand:QI 2 "const1_operand" "")))
13488 (clobber (reg:CC FLAGS_REG))]
13489 "(TARGET_SHIFT1 || optimize_size)
13490 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13492 [(set_attr "type" "rotate")
13493 (set (attr "length")
13494 (if_then_else (match_operand:SI 0 "register_operand" "")
13496 (const_string "*")))])
13498 (define_insn "*rotrsi3_1_one_bit_zext"
13499 [(set (match_operand:DI 0 "register_operand" "=r")
13501 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13502 (match_operand:QI 2 "const1_operand" ""))))
13503 (clobber (reg:CC FLAGS_REG))]
13505 && (TARGET_SHIFT1 || optimize_size)
13506 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13508 [(set_attr "type" "rotate")
13509 (set (attr "length")
13510 (if_then_else (match_operand:SI 0 "register_operand" "")
13512 (const_string "*")))])
13514 (define_insn "*rotrsi3_1"
13515 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13516 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13517 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13518 (clobber (reg:CC FLAGS_REG))]
13519 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13521 ror{l}\t{%2, %0|%0, %2}
13522 ror{l}\t{%b2, %0|%0, %b2}"
13523 [(set_attr "type" "rotate")
13524 (set_attr "mode" "SI")])
13526 (define_insn "*rotrsi3_1_zext"
13527 [(set (match_operand:DI 0 "register_operand" "=r,r")
13529 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13530 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13531 (clobber (reg:CC FLAGS_REG))]
13532 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13534 ror{l}\t{%2, %k0|%k0, %2}
13535 ror{l}\t{%b2, %k0|%k0, %b2}"
13536 [(set_attr "type" "rotate")
13537 (set_attr "mode" "SI")])
13539 (define_expand "rotrhi3"
13540 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13541 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13542 (match_operand:QI 2 "nonmemory_operand" "")))
13543 (clobber (reg:CC FLAGS_REG))]
13544 "TARGET_HIMODE_MATH"
13545 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13547 (define_insn "*rotrhi3_one_bit"
13548 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13549 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13550 (match_operand:QI 2 "const1_operand" "")))
13551 (clobber (reg:CC FLAGS_REG))]
13552 "(TARGET_SHIFT1 || optimize_size)
13553 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13555 [(set_attr "type" "rotate")
13556 (set (attr "length")
13557 (if_then_else (match_operand 0 "register_operand" "")
13559 (const_string "*")))])
13561 (define_insn "*rotrhi3_1"
13562 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13563 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13564 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13565 (clobber (reg:CC FLAGS_REG))]
13566 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13568 ror{w}\t{%2, %0|%0, %2}
13569 ror{w}\t{%b2, %0|%0, %b2}"
13570 [(set_attr "type" "rotate")
13571 (set_attr "mode" "HI")])
13574 [(set (match_operand:HI 0 "register_operand" "")
13575 (rotatert:HI (match_dup 0) (const_int 8)))
13576 (clobber (reg:CC FLAGS_REG))]
13578 [(parallel [(set (strict_low_part (match_dup 0))
13579 (bswap:HI (match_dup 0)))
13580 (clobber (reg:CC FLAGS_REG))])]
13583 (define_expand "rotrqi3"
13584 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13585 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13586 (match_operand:QI 2 "nonmemory_operand" "")))
13587 (clobber (reg:CC FLAGS_REG))]
13588 "TARGET_QIMODE_MATH"
13589 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13591 (define_insn "*rotrqi3_1_one_bit"
13592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13593 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13594 (match_operand:QI 2 "const1_operand" "")))
13595 (clobber (reg:CC FLAGS_REG))]
13596 "(TARGET_SHIFT1 || optimize_size)
13597 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13599 [(set_attr "type" "rotate")
13600 (set (attr "length")
13601 (if_then_else (match_operand 0 "register_operand" "")
13603 (const_string "*")))])
13605 (define_insn "*rotrqi3_1_one_bit_slp"
13606 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13607 (rotatert:QI (match_dup 0)
13608 (match_operand:QI 1 "const1_operand" "")))
13609 (clobber (reg:CC FLAGS_REG))]
13610 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13611 && (TARGET_SHIFT1 || optimize_size)"
13613 [(set_attr "type" "rotate1")
13614 (set (attr "length")
13615 (if_then_else (match_operand 0 "register_operand" "")
13617 (const_string "*")))])
13619 (define_insn "*rotrqi3_1"
13620 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13621 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13622 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13623 (clobber (reg:CC FLAGS_REG))]
13624 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13626 ror{b}\t{%2, %0|%0, %2}
13627 ror{b}\t{%b2, %0|%0, %b2}"
13628 [(set_attr "type" "rotate")
13629 (set_attr "mode" "QI")])
13631 (define_insn "*rotrqi3_1_slp"
13632 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13633 (rotatert:QI (match_dup 0)
13634 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13635 (clobber (reg:CC FLAGS_REG))]
13636 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13637 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13639 ror{b}\t{%1, %0|%0, %1}
13640 ror{b}\t{%b1, %0|%0, %b1}"
13641 [(set_attr "type" "rotate1")
13642 (set_attr "mode" "QI")])
13644 ;; Bit set / bit test instructions
13646 (define_expand "extv"
13647 [(set (match_operand:SI 0 "register_operand" "")
13648 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13649 (match_operand:SI 2 "const8_operand" "")
13650 (match_operand:SI 3 "const8_operand" "")))]
13653 /* Handle extractions from %ah et al. */
13654 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13657 /* From mips.md: extract_bit_field doesn't verify that our source
13658 matches the predicate, so check it again here. */
13659 if (! ext_register_operand (operands[1], VOIDmode))
13663 (define_expand "extzv"
13664 [(set (match_operand:SI 0 "register_operand" "")
13665 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13666 (match_operand:SI 2 "const8_operand" "")
13667 (match_operand:SI 3 "const8_operand" "")))]
13670 /* Handle extractions from %ah et al. */
13671 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13674 /* From mips.md: extract_bit_field doesn't verify that our source
13675 matches the predicate, so check it again here. */
13676 if (! ext_register_operand (operands[1], VOIDmode))
13680 (define_expand "insv"
13681 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13682 (match_operand 1 "const8_operand" "")
13683 (match_operand 2 "const8_operand" ""))
13684 (match_operand 3 "register_operand" ""))]
13687 /* Handle insertions to %ah et al. */
13688 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13691 /* From mips.md: insert_bit_field doesn't verify that our source
13692 matches the predicate, so check it again here. */
13693 if (! ext_register_operand (operands[0], VOIDmode))
13697 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13699 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13704 ;; %%% bts, btr, btc, bt.
13705 ;; In general these instructions are *slow* when applied to memory,
13706 ;; since they enforce atomic operation. When applied to registers,
13707 ;; it depends on the cpu implementation. They're never faster than
13708 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13709 ;; no point. But in 64-bit, we can't hold the relevant immediates
13710 ;; within the instruction itself, so operating on bits in the high
13711 ;; 32-bits of a register becomes easier.
13713 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13714 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13715 ;; negdf respectively, so they can never be disabled entirely.
13717 (define_insn "*btsq"
13718 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13720 (match_operand:DI 1 "const_0_to_63_operand" ""))
13722 (clobber (reg:CC FLAGS_REG))]
13723 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13725 [(set_attr "type" "alu1")])
13727 (define_insn "*btrq"
13728 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13730 (match_operand:DI 1 "const_0_to_63_operand" ""))
13732 (clobber (reg:CC FLAGS_REG))]
13733 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13735 [(set_attr "type" "alu1")])
13737 (define_insn "*btcq"
13738 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13740 (match_operand:DI 1 "const_0_to_63_operand" ""))
13741 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13742 (clobber (reg:CC FLAGS_REG))]
13743 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13745 [(set_attr "type" "alu1")])
13747 ;; Allow Nocona to avoid these instructions if a register is available.
13750 [(match_scratch:DI 2 "r")
13751 (parallel [(set (zero_extract:DI
13752 (match_operand:DI 0 "register_operand" "")
13754 (match_operand:DI 1 "const_0_to_63_operand" ""))
13756 (clobber (reg:CC FLAGS_REG))])]
13757 "TARGET_64BIT && !TARGET_USE_BT"
13760 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13763 if (HOST_BITS_PER_WIDE_INT >= 64)
13764 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13765 else if (i < HOST_BITS_PER_WIDE_INT)
13766 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13768 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13770 op1 = immed_double_const (lo, hi, DImode);
13773 emit_move_insn (operands[2], op1);
13777 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13782 [(match_scratch:DI 2 "r")
13783 (parallel [(set (zero_extract:DI
13784 (match_operand:DI 0 "register_operand" "")
13786 (match_operand:DI 1 "const_0_to_63_operand" ""))
13788 (clobber (reg:CC FLAGS_REG))])]
13789 "TARGET_64BIT && !TARGET_USE_BT"
13792 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13795 if (HOST_BITS_PER_WIDE_INT >= 64)
13796 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13797 else if (i < HOST_BITS_PER_WIDE_INT)
13798 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13800 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13802 op1 = immed_double_const (~lo, ~hi, DImode);
13805 emit_move_insn (operands[2], op1);
13809 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13814 [(match_scratch:DI 2 "r")
13815 (parallel [(set (zero_extract:DI
13816 (match_operand:DI 0 "register_operand" "")
13818 (match_operand:DI 1 "const_0_to_63_operand" ""))
13819 (not:DI (zero_extract:DI
13820 (match_dup 0) (const_int 1) (match_dup 1))))
13821 (clobber (reg:CC FLAGS_REG))])]
13822 "TARGET_64BIT && !TARGET_USE_BT"
13825 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13828 if (HOST_BITS_PER_WIDE_INT >= 64)
13829 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13830 else if (i < HOST_BITS_PER_WIDE_INT)
13831 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13833 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13835 op1 = immed_double_const (lo, hi, DImode);
13838 emit_move_insn (operands[2], op1);
13842 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13846 ;; Store-flag instructions.
13848 ;; For all sCOND expanders, also expand the compare or test insn that
13849 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13851 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13852 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13853 ;; way, which can later delete the movzx if only QImode is needed.
13855 (define_expand "s<code>"
13856 [(set (match_operand:QI 0 "register_operand" "")
13857 (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13859 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13861 (define_expand "s<code>"
13862 [(set (match_operand:QI 0 "register_operand" "")
13863 (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13864 "TARGET_80387 || TARGET_SSE"
13865 "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13867 (define_insn "*setcc_1"
13868 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13869 (match_operator:QI 1 "ix86_comparison_operator"
13870 [(reg FLAGS_REG) (const_int 0)]))]
13873 [(set_attr "type" "setcc")
13874 (set_attr "mode" "QI")])
13876 (define_insn "*setcc_2"
13877 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13878 (match_operator:QI 1 "ix86_comparison_operator"
13879 [(reg FLAGS_REG) (const_int 0)]))]
13882 [(set_attr "type" "setcc")
13883 (set_attr "mode" "QI")])
13885 ;; In general it is not safe to assume too much about CCmode registers,
13886 ;; so simplify-rtx stops when it sees a second one. Under certain
13887 ;; conditions this is safe on x86, so help combine not create
13894 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13895 (ne:QI (match_operator 1 "ix86_comparison_operator"
13896 [(reg FLAGS_REG) (const_int 0)])
13899 [(set (match_dup 0) (match_dup 1))]
13901 PUT_MODE (operands[1], QImode);
13905 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13906 (ne:QI (match_operator 1 "ix86_comparison_operator"
13907 [(reg FLAGS_REG) (const_int 0)])
13910 [(set (match_dup 0) (match_dup 1))]
13912 PUT_MODE (operands[1], QImode);
13916 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13917 (eq:QI (match_operator 1 "ix86_comparison_operator"
13918 [(reg FLAGS_REG) (const_int 0)])
13921 [(set (match_dup 0) (match_dup 1))]
13923 rtx new_op1 = copy_rtx (operands[1]);
13924 operands[1] = new_op1;
13925 PUT_MODE (new_op1, QImode);
13926 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13927 GET_MODE (XEXP (new_op1, 0))));
13929 /* Make sure that (a) the CCmode we have for the flags is strong
13930 enough for the reversed compare or (b) we have a valid FP compare. */
13931 if (! ix86_comparison_operator (new_op1, VOIDmode))
13936 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13937 (eq:QI (match_operator 1 "ix86_comparison_operator"
13938 [(reg FLAGS_REG) (const_int 0)])
13941 [(set (match_dup 0) (match_dup 1))]
13943 rtx new_op1 = copy_rtx (operands[1]);
13944 operands[1] = new_op1;
13945 PUT_MODE (new_op1, QImode);
13946 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13947 GET_MODE (XEXP (new_op1, 0))));
13949 /* Make sure that (a) the CCmode we have for the flags is strong
13950 enough for the reversed compare or (b) we have a valid FP compare. */
13951 if (! ix86_comparison_operator (new_op1, VOIDmode))
13955 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13956 ;; subsequent logical operations are used to imitate conditional moves.
13957 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13960 (define_insn "*sse_setcc<mode>"
13961 [(set (match_operand:MODEF 0 "register_operand" "=x")
13962 (match_operator:MODEF 1 "sse_comparison_operator"
13963 [(match_operand:MODEF 2 "register_operand" "0")
13964 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13965 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13966 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13967 [(set_attr "type" "ssecmp")
13968 (set_attr "mode" "<MODE>")])
13970 (define_insn "*sse5_setcc<mode>"
13971 [(set (match_operand:MODEF 0 "register_operand" "=x")
13972 (match_operator:MODEF 1 "sse5_comparison_float_operator"
13973 [(match_operand:MODEF 2 "register_operand" "x")
13974 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13976 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13977 [(set_attr "type" "sse4arg")
13978 (set_attr "mode" "<MODE>")])
13981 ;; Basic conditional jump instructions.
13982 ;; We ignore the overflow flag for signed branch instructions.
13984 ;; For all bCOND expanders, also expand the compare or test insn that
13985 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13987 (define_expand "b<code>"
13989 (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13991 (label_ref (match_operand 0 ""))
13994 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13996 (define_expand "b<code>"
13998 (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14000 (label_ref (match_operand 0 ""))
14002 "TARGET_80387 || TARGET_SSE_MATH"
14003 "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14005 (define_insn "*jcc_1"
14007 (if_then_else (match_operator 1 "ix86_comparison_operator"
14008 [(reg FLAGS_REG) (const_int 0)])
14009 (label_ref (match_operand 0 "" ""))
14013 [(set_attr "type" "ibr")
14014 (set_attr "modrm" "0")
14015 (set (attr "length")
14016 (if_then_else (and (ge (minus (match_dup 0) (pc))
14018 (lt (minus (match_dup 0) (pc))
14023 (define_insn "*jcc_2"
14025 (if_then_else (match_operator 1 "ix86_comparison_operator"
14026 [(reg FLAGS_REG) (const_int 0)])
14028 (label_ref (match_operand 0 "" ""))))]
14031 [(set_attr "type" "ibr")
14032 (set_attr "modrm" "0")
14033 (set (attr "length")
14034 (if_then_else (and (ge (minus (match_dup 0) (pc))
14036 (lt (minus (match_dup 0) (pc))
14041 ;; In general it is not safe to assume too much about CCmode registers,
14042 ;; so simplify-rtx stops when it sees a second one. Under certain
14043 ;; conditions this is safe on x86, so help combine not create
14051 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14052 [(reg FLAGS_REG) (const_int 0)])
14054 (label_ref (match_operand 1 "" ""))
14058 (if_then_else (match_dup 0)
14059 (label_ref (match_dup 1))
14062 PUT_MODE (operands[0], VOIDmode);
14067 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14068 [(reg FLAGS_REG) (const_int 0)])
14070 (label_ref (match_operand 1 "" ""))
14074 (if_then_else (match_dup 0)
14075 (label_ref (match_dup 1))
14078 rtx new_op0 = copy_rtx (operands[0]);
14079 operands[0] = new_op0;
14080 PUT_MODE (new_op0, VOIDmode);
14081 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14082 GET_MODE (XEXP (new_op0, 0))));
14084 /* Make sure that (a) the CCmode we have for the flags is strong
14085 enough for the reversed compare or (b) we have a valid FP compare. */
14086 if (! ix86_comparison_operator (new_op0, VOIDmode))
14090 ;; Define combination compare-and-branch fp compare instructions to use
14091 ;; during early optimization. Splitting the operation apart early makes
14092 ;; for bad code when we want to reverse the operation.
14094 (define_insn "*fp_jcc_1_mixed"
14096 (if_then_else (match_operator 0 "comparison_operator"
14097 [(match_operand 1 "register_operand" "f,x")
14098 (match_operand 2 "nonimmediate_operand" "f,xm")])
14099 (label_ref (match_operand 3 "" ""))
14101 (clobber (reg:CCFP FPSR_REG))
14102 (clobber (reg:CCFP FLAGS_REG))]
14103 "TARGET_MIX_SSE_I387
14104 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14105 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14106 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14109 (define_insn "*fp_jcc_1_sse"
14111 (if_then_else (match_operator 0 "comparison_operator"
14112 [(match_operand 1 "register_operand" "x")
14113 (match_operand 2 "nonimmediate_operand" "xm")])
14114 (label_ref (match_operand 3 "" ""))
14116 (clobber (reg:CCFP FPSR_REG))
14117 (clobber (reg:CCFP FLAGS_REG))]
14119 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14120 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14121 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14124 (define_insn "*fp_jcc_1_387"
14126 (if_then_else (match_operator 0 "comparison_operator"
14127 [(match_operand 1 "register_operand" "f")
14128 (match_operand 2 "register_operand" "f")])
14129 (label_ref (match_operand 3 "" ""))
14131 (clobber (reg:CCFP FPSR_REG))
14132 (clobber (reg:CCFP FLAGS_REG))]
14133 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14135 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14136 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14139 (define_insn "*fp_jcc_2_mixed"
14141 (if_then_else (match_operator 0 "comparison_operator"
14142 [(match_operand 1 "register_operand" "f,x")
14143 (match_operand 2 "nonimmediate_operand" "f,xm")])
14145 (label_ref (match_operand 3 "" ""))))
14146 (clobber (reg:CCFP FPSR_REG))
14147 (clobber (reg:CCFP FLAGS_REG))]
14148 "TARGET_MIX_SSE_I387
14149 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14150 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14151 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14154 (define_insn "*fp_jcc_2_sse"
14156 (if_then_else (match_operator 0 "comparison_operator"
14157 [(match_operand 1 "register_operand" "x")
14158 (match_operand 2 "nonimmediate_operand" "xm")])
14160 (label_ref (match_operand 3 "" ""))))
14161 (clobber (reg:CCFP FPSR_REG))
14162 (clobber (reg:CCFP FLAGS_REG))]
14164 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14165 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14166 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14169 (define_insn "*fp_jcc_2_387"
14171 (if_then_else (match_operator 0 "comparison_operator"
14172 [(match_operand 1 "register_operand" "f")
14173 (match_operand 2 "register_operand" "f")])
14175 (label_ref (match_operand 3 "" ""))))
14176 (clobber (reg:CCFP FPSR_REG))
14177 (clobber (reg:CCFP FLAGS_REG))]
14178 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14180 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14181 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14184 (define_insn "*fp_jcc_3_387"
14186 (if_then_else (match_operator 0 "comparison_operator"
14187 [(match_operand 1 "register_operand" "f")
14188 (match_operand 2 "nonimmediate_operand" "fm")])
14189 (label_ref (match_operand 3 "" ""))
14191 (clobber (reg:CCFP FPSR_REG))
14192 (clobber (reg:CCFP FLAGS_REG))
14193 (clobber (match_scratch:HI 4 "=a"))]
14195 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14196 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14197 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14198 && SELECT_CC_MODE (GET_CODE (operands[0]),
14199 operands[1], operands[2]) == CCFPmode
14200 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14203 (define_insn "*fp_jcc_4_387"
14205 (if_then_else (match_operator 0 "comparison_operator"
14206 [(match_operand 1 "register_operand" "f")
14207 (match_operand 2 "nonimmediate_operand" "fm")])
14209 (label_ref (match_operand 3 "" ""))))
14210 (clobber (reg:CCFP FPSR_REG))
14211 (clobber (reg:CCFP FLAGS_REG))
14212 (clobber (match_scratch:HI 4 "=a"))]
14214 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14215 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14216 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14217 && SELECT_CC_MODE (GET_CODE (operands[0]),
14218 operands[1], operands[2]) == CCFPmode
14219 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14222 (define_insn "*fp_jcc_5_387"
14224 (if_then_else (match_operator 0 "comparison_operator"
14225 [(match_operand 1 "register_operand" "f")
14226 (match_operand 2 "register_operand" "f")])
14227 (label_ref (match_operand 3 "" ""))
14229 (clobber (reg:CCFP FPSR_REG))
14230 (clobber (reg:CCFP FLAGS_REG))
14231 (clobber (match_scratch:HI 4 "=a"))]
14232 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14233 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14234 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14237 (define_insn "*fp_jcc_6_387"
14239 (if_then_else (match_operator 0 "comparison_operator"
14240 [(match_operand 1 "register_operand" "f")
14241 (match_operand 2 "register_operand" "f")])
14243 (label_ref (match_operand 3 "" ""))))
14244 (clobber (reg:CCFP FPSR_REG))
14245 (clobber (reg:CCFP FLAGS_REG))
14246 (clobber (match_scratch:HI 4 "=a"))]
14247 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14248 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14249 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14252 (define_insn "*fp_jcc_7_387"
14254 (if_then_else (match_operator 0 "comparison_operator"
14255 [(match_operand 1 "register_operand" "f")
14256 (match_operand 2 "const0_operand" "X")])
14257 (label_ref (match_operand 3 "" ""))
14259 (clobber (reg:CCFP FPSR_REG))
14260 (clobber (reg:CCFP FLAGS_REG))
14261 (clobber (match_scratch:HI 4 "=a"))]
14262 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14263 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14264 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14265 && SELECT_CC_MODE (GET_CODE (operands[0]),
14266 operands[1], operands[2]) == CCFPmode
14267 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14270 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14271 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14272 ;; with a precedence over other operators and is always put in the first
14273 ;; place. Swap condition and operands to match ficom instruction.
14275 (define_insn "*fp_jcc_8<mode>_387"
14277 (if_then_else (match_operator 0 "comparison_operator"
14278 [(match_operator 1 "float_operator"
14279 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14280 (match_operand 3 "register_operand" "f,f")])
14281 (label_ref (match_operand 4 "" ""))
14283 (clobber (reg:CCFP FPSR_REG))
14284 (clobber (reg:CCFP FLAGS_REG))
14285 (clobber (match_scratch:HI 5 "=a,a"))]
14286 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14287 && TARGET_USE_<MODE>MODE_FIOP
14288 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14289 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14290 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14291 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14296 (if_then_else (match_operator 0 "comparison_operator"
14297 [(match_operand 1 "register_operand" "")
14298 (match_operand 2 "nonimmediate_operand" "")])
14299 (match_operand 3 "" "")
14300 (match_operand 4 "" "")))
14301 (clobber (reg:CCFP FPSR_REG))
14302 (clobber (reg:CCFP FLAGS_REG))]
14306 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14307 operands[3], operands[4], NULL_RTX, NULL_RTX);
14313 (if_then_else (match_operator 0 "comparison_operator"
14314 [(match_operand 1 "register_operand" "")
14315 (match_operand 2 "general_operand" "")])
14316 (match_operand 3 "" "")
14317 (match_operand 4 "" "")))
14318 (clobber (reg:CCFP FPSR_REG))
14319 (clobber (reg:CCFP FLAGS_REG))
14320 (clobber (match_scratch:HI 5 "=a"))]
14324 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14325 operands[3], operands[4], operands[5], NULL_RTX);
14331 (if_then_else (match_operator 0 "comparison_operator"
14332 [(match_operator 1 "float_operator"
14333 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14334 (match_operand 3 "register_operand" "")])
14335 (match_operand 4 "" "")
14336 (match_operand 5 "" "")))
14337 (clobber (reg:CCFP FPSR_REG))
14338 (clobber (reg:CCFP FLAGS_REG))
14339 (clobber (match_scratch:HI 6 "=a"))]
14343 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14344 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14345 operands[3], operands[7],
14346 operands[4], operands[5], operands[6], NULL_RTX);
14350 ;; %%% Kill this when reload knows how to do it.
14353 (if_then_else (match_operator 0 "comparison_operator"
14354 [(match_operator 1 "float_operator"
14355 [(match_operand:X87MODEI12 2 "register_operand" "")])
14356 (match_operand 3 "register_operand" "")])
14357 (match_operand 4 "" "")
14358 (match_operand 5 "" "")))
14359 (clobber (reg:CCFP FPSR_REG))
14360 (clobber (reg:CCFP FLAGS_REG))
14361 (clobber (match_scratch:HI 6 "=a"))]
14365 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14366 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14367 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14368 operands[3], operands[7],
14369 operands[4], operands[5], operands[6], operands[2]);
14373 ;; Unconditional and other jump instructions
14375 (define_insn "jump"
14377 (label_ref (match_operand 0 "" "")))]
14380 [(set_attr "type" "ibr")
14381 (set (attr "length")
14382 (if_then_else (and (ge (minus (match_dup 0) (pc))
14384 (lt (minus (match_dup 0) (pc))
14388 (set_attr "modrm" "0")])
14390 (define_expand "indirect_jump"
14391 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14395 (define_insn "*indirect_jump"
14396 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14399 [(set_attr "type" "ibr")
14400 (set_attr "length_immediate" "0")])
14402 (define_insn "*indirect_jump_rtx64"
14403 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14406 [(set_attr "type" "ibr")
14407 (set_attr "length_immediate" "0")])
14409 (define_expand "tablejump"
14410 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14411 (use (label_ref (match_operand 1 "" "")))])]
14414 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14415 relative. Convert the relative address to an absolute address. */
14419 enum rtx_code code;
14421 /* We can't use @GOTOFF for text labels on VxWorks;
14422 see gotoff_operand. */
14423 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14427 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14429 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14433 op1 = pic_offset_table_rtx;
14438 op0 = pic_offset_table_rtx;
14442 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14447 (define_insn "*tablejump_1"
14448 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14449 (use (label_ref (match_operand 1 "" "")))]
14452 [(set_attr "type" "ibr")
14453 (set_attr "length_immediate" "0")])
14455 (define_insn "*tablejump_1_rtx64"
14456 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14457 (use (label_ref (match_operand 1 "" "")))]
14460 [(set_attr "type" "ibr")
14461 (set_attr "length_immediate" "0")])
14463 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14466 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14467 (set (match_operand:QI 1 "register_operand" "")
14468 (match_operator:QI 2 "ix86_comparison_operator"
14469 [(reg FLAGS_REG) (const_int 0)]))
14470 (set (match_operand 3 "q_regs_operand" "")
14471 (zero_extend (match_dup 1)))]
14472 "(peep2_reg_dead_p (3, operands[1])
14473 || operands_match_p (operands[1], operands[3]))
14474 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14475 [(set (match_dup 4) (match_dup 0))
14476 (set (strict_low_part (match_dup 5))
14479 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14480 operands[5] = gen_lowpart (QImode, operands[3]);
14481 ix86_expand_clear (operands[3]);
14484 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14487 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14488 (set (match_operand:QI 1 "register_operand" "")
14489 (match_operator:QI 2 "ix86_comparison_operator"
14490 [(reg FLAGS_REG) (const_int 0)]))
14491 (parallel [(set (match_operand 3 "q_regs_operand" "")
14492 (zero_extend (match_dup 1)))
14493 (clobber (reg:CC FLAGS_REG))])]
14494 "(peep2_reg_dead_p (3, operands[1])
14495 || operands_match_p (operands[1], operands[3]))
14496 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14497 [(set (match_dup 4) (match_dup 0))
14498 (set (strict_low_part (match_dup 5))
14501 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14502 operands[5] = gen_lowpart (QImode, operands[3]);
14503 ix86_expand_clear (operands[3]);
14506 ;; Call instructions.
14508 ;; The predicates normally associated with named expanders are not properly
14509 ;; checked for calls. This is a bug in the generic code, but it isn't that
14510 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14512 ;; Call subroutine returning no value.
14514 (define_expand "call_pop"
14515 [(parallel [(call (match_operand:QI 0 "" "")
14516 (match_operand:SI 1 "" ""))
14517 (set (reg:SI SP_REG)
14518 (plus:SI (reg:SI SP_REG)
14519 (match_operand:SI 3 "" "")))])]
14522 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14526 (define_insn "*call_pop_0"
14527 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14528 (match_operand:SI 1 "" ""))
14529 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14530 (match_operand:SI 2 "immediate_operand" "")))]
14533 if (SIBLING_CALL_P (insn))
14536 return "call\t%P0";
14538 [(set_attr "type" "call")])
14540 (define_insn "*call_pop_1"
14541 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14542 (match_operand:SI 1 "" ""))
14543 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14544 (match_operand:SI 2 "immediate_operand" "i")))]
14547 if (constant_call_address_operand (operands[0], Pmode))
14549 if (SIBLING_CALL_P (insn))
14552 return "call\t%P0";
14554 if (SIBLING_CALL_P (insn))
14557 return "call\t%A0";
14559 [(set_attr "type" "call")])
14561 (define_expand "call"
14562 [(call (match_operand:QI 0 "" "")
14563 (match_operand 1 "" ""))
14564 (use (match_operand 2 "" ""))]
14567 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14571 (define_expand "sibcall"
14572 [(call (match_operand:QI 0 "" "")
14573 (match_operand 1 "" ""))
14574 (use (match_operand 2 "" ""))]
14577 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14581 (define_insn "*call_0"
14582 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14583 (match_operand 1 "" ""))]
14586 if (SIBLING_CALL_P (insn))
14589 return "call\t%P0";
14591 [(set_attr "type" "call")])
14593 (define_insn "*call_1"
14594 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14595 (match_operand 1 "" ""))]
14596 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14598 if (constant_call_address_operand (operands[0], Pmode))
14599 return "call\t%P0";
14600 return "call\t%A0";
14602 [(set_attr "type" "call")])
14604 (define_insn "*sibcall_1"
14605 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14606 (match_operand 1 "" ""))]
14607 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14609 if (constant_call_address_operand (operands[0], Pmode))
14613 [(set_attr "type" "call")])
14615 (define_insn "*call_1_rex64"
14616 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14617 (match_operand 1 "" ""))]
14618 "!SIBLING_CALL_P (insn) && TARGET_64BIT
14619 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14621 if (constant_call_address_operand (operands[0], Pmode))
14622 return "call\t%P0";
14623 return "call\t%A0";
14625 [(set_attr "type" "call")])
14627 (define_insn "*call_1_rex64_large"
14628 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14629 (match_operand 1 "" ""))]
14630 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14632 [(set_attr "type" "call")])
14634 (define_insn "*sibcall_1_rex64"
14635 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14636 (match_operand 1 "" ""))]
14637 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14639 [(set_attr "type" "call")])
14641 (define_insn "*sibcall_1_rex64_v"
14642 [(call (mem:QI (reg:DI R11_REG))
14643 (match_operand 0 "" ""))]
14644 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14646 [(set_attr "type" "call")])
14649 ;; Call subroutine, returning value in operand 0
14651 (define_expand "call_value_pop"
14652 [(parallel [(set (match_operand 0 "" "")
14653 (call (match_operand:QI 1 "" "")
14654 (match_operand:SI 2 "" "")))
14655 (set (reg:SI SP_REG)
14656 (plus:SI (reg:SI SP_REG)
14657 (match_operand:SI 4 "" "")))])]
14660 ix86_expand_call (operands[0], operands[1], operands[2],
14661 operands[3], operands[4], 0);
14665 (define_expand "call_value"
14666 [(set (match_operand 0 "" "")
14667 (call (match_operand:QI 1 "" "")
14668 (match_operand:SI 2 "" "")))
14669 (use (match_operand:SI 3 "" ""))]
14670 ;; Operand 2 not used on the i386.
14673 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14677 (define_expand "sibcall_value"
14678 [(set (match_operand 0 "" "")
14679 (call (match_operand:QI 1 "" "")
14680 (match_operand:SI 2 "" "")))
14681 (use (match_operand:SI 3 "" ""))]
14682 ;; Operand 2 not used on the i386.
14685 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14689 ;; Call subroutine returning any type.
14691 (define_expand "untyped_call"
14692 [(parallel [(call (match_operand 0 "" "")
14694 (match_operand 1 "" "")
14695 (match_operand 2 "" "")])]
14700 /* In order to give reg-stack an easier job in validating two
14701 coprocessor registers as containing a possible return value,
14702 simply pretend the untyped call returns a complex long double
14705 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14706 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14707 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14710 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14712 rtx set = XVECEXP (operands[2], 0, i);
14713 emit_move_insn (SET_DEST (set), SET_SRC (set));
14716 /* The optimizer does not know that the call sets the function value
14717 registers we stored in the result block. We avoid problems by
14718 claiming that all hard registers are used and clobbered at this
14720 emit_insn (gen_blockage ());
14725 ;; Prologue and epilogue instructions
14727 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14728 ;; all of memory. This blocks insns from being moved across this point.
14730 (define_insn "blockage"
14731 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14734 [(set_attr "length" "0")])
14736 ;; As USE insns aren't meaningful after reload, this is used instead
14737 ;; to prevent deleting instructions setting registers for PIC code
14738 (define_insn "prologue_use"
14739 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14742 [(set_attr "length" "0")])
14744 ;; Insn emitted into the body of a function to return from a function.
14745 ;; This is only done if the function's epilogue is known to be simple.
14746 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14748 (define_expand "return"
14750 "ix86_can_use_return_insn_p ()"
14752 if (crtl->args.pops_args)
14754 rtx popc = GEN_INT (crtl->args.pops_args);
14755 emit_jump_insn (gen_return_pop_internal (popc));
14760 (define_insn "return_internal"
14764 [(set_attr "length" "1")
14765 (set_attr "length_immediate" "0")
14766 (set_attr "modrm" "0")])
14768 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14769 ;; instruction Athlon and K8 have.
14771 (define_insn "return_internal_long"
14773 (unspec [(const_int 0)] UNSPEC_REP)]
14776 [(set_attr "length" "1")
14777 (set_attr "length_immediate" "0")
14778 (set_attr "prefix_rep" "1")
14779 (set_attr "modrm" "0")])
14781 (define_insn "return_pop_internal"
14783 (use (match_operand:SI 0 "const_int_operand" ""))]
14786 [(set_attr "length" "3")
14787 (set_attr "length_immediate" "2")
14788 (set_attr "modrm" "0")])
14790 (define_insn "return_indirect_internal"
14792 (use (match_operand:SI 0 "register_operand" "r"))]
14795 [(set_attr "type" "ibr")
14796 (set_attr "length_immediate" "0")])
14802 [(set_attr "length" "1")
14803 (set_attr "length_immediate" "0")
14804 (set_attr "modrm" "0")])
14806 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14807 ;; branch prediction penalty for the third jump in a 16-byte
14810 (define_insn "align"
14811 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14814 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14815 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14817 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14818 The align insn is used to avoid 3 jump instructions in the row to improve
14819 branch prediction and the benefits hardly outweigh the cost of extra 8
14820 nops on the average inserted by full alignment pseudo operation. */
14824 [(set_attr "length" "16")])
14826 (define_expand "prologue"
14829 "ix86_expand_prologue (); DONE;")
14831 (define_insn "set_got"
14832 [(set (match_operand:SI 0 "register_operand" "=r")
14833 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14834 (clobber (reg:CC FLAGS_REG))]
14836 { return output_set_got (operands[0], NULL_RTX); }
14837 [(set_attr "type" "multi")
14838 (set_attr "length" "12")])
14840 (define_insn "set_got_labelled"
14841 [(set (match_operand:SI 0 "register_operand" "=r")
14842 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14844 (clobber (reg:CC FLAGS_REG))]
14846 { return output_set_got (operands[0], operands[1]); }
14847 [(set_attr "type" "multi")
14848 (set_attr "length" "12")])
14850 (define_insn "set_got_rex64"
14851 [(set (match_operand:DI 0 "register_operand" "=r")
14852 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14854 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14855 [(set_attr "type" "lea")
14856 (set_attr "length" "6")])
14858 (define_insn "set_rip_rex64"
14859 [(set (match_operand:DI 0 "register_operand" "=r")
14860 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14862 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14863 [(set_attr "type" "lea")
14864 (set_attr "length" "6")])
14866 (define_insn "set_got_offset_rex64"
14867 [(set (match_operand:DI 0 "register_operand" "=r")
14868 (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14870 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14871 [(set_attr "type" "imov")
14872 (set_attr "length" "11")])
14874 (define_expand "epilogue"
14877 "ix86_expand_epilogue (1); DONE;")
14879 (define_expand "sibcall_epilogue"
14882 "ix86_expand_epilogue (0); DONE;")
14884 (define_expand "eh_return"
14885 [(use (match_operand 0 "register_operand" ""))]
14888 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14890 /* Tricky bit: we write the address of the handler to which we will
14891 be returning into someone else's stack frame, one word below the
14892 stack address we wish to restore. */
14893 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14894 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14895 tmp = gen_rtx_MEM (Pmode, tmp);
14896 emit_move_insn (tmp, ra);
14898 if (Pmode == SImode)
14899 emit_jump_insn (gen_eh_return_si (sa));
14901 emit_jump_insn (gen_eh_return_di (sa));
14906 (define_insn_and_split "eh_return_si"
14908 (unspec [(match_operand:SI 0 "register_operand" "c")]
14909 UNSPEC_EH_RETURN))]
14914 "ix86_expand_epilogue (2); DONE;")
14916 (define_insn_and_split "eh_return_di"
14918 (unspec [(match_operand:DI 0 "register_operand" "c")]
14919 UNSPEC_EH_RETURN))]
14924 "ix86_expand_epilogue (2); DONE;")
14926 (define_insn "leave"
14927 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14928 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14929 (clobber (mem:BLK (scratch)))]
14932 [(set_attr "type" "leave")])
14934 (define_insn "leave_rex64"
14935 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14936 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14937 (clobber (mem:BLK (scratch)))]
14940 [(set_attr "type" "leave")])
14942 (define_expand "ffssi2"
14944 [(set (match_operand:SI 0 "register_operand" "")
14945 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14946 (clobber (match_scratch:SI 2 ""))
14947 (clobber (reg:CC FLAGS_REG))])]
14952 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14957 (define_expand "ffs_cmove"
14958 [(set (match_dup 2) (const_int -1))
14959 (parallel [(set (reg:CCZ FLAGS_REG)
14960 (compare:CCZ (match_operand:SI 1 "register_operand" "")
14962 (set (match_operand:SI 0 "nonimmediate_operand" "")
14963 (ctz:SI (match_dup 1)))])
14964 (set (match_dup 0) (if_then_else:SI
14965 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14968 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14969 (clobber (reg:CC FLAGS_REG))])]
14971 "operands[2] = gen_reg_rtx (SImode);")
14973 (define_insn_and_split "*ffs_no_cmove"
14974 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14975 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14976 (clobber (match_scratch:SI 2 "=&q"))
14977 (clobber (reg:CC FLAGS_REG))]
14980 "&& reload_completed"
14981 [(parallel [(set (reg:CCZ FLAGS_REG)
14982 (compare:CCZ (match_dup 1) (const_int 0)))
14983 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14984 (set (strict_low_part (match_dup 3))
14985 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14986 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14987 (clobber (reg:CC FLAGS_REG))])
14988 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14989 (clobber (reg:CC FLAGS_REG))])
14990 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14991 (clobber (reg:CC FLAGS_REG))])]
14993 operands[3] = gen_lowpart (QImode, operands[2]);
14994 ix86_expand_clear (operands[2]);
14997 (define_insn "*ffssi_1"
14998 [(set (reg:CCZ FLAGS_REG)
14999 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15001 (set (match_operand:SI 0 "register_operand" "=r")
15002 (ctz:SI (match_dup 1)))]
15004 "bsf{l}\t{%1, %0|%0, %1}"
15005 [(set_attr "prefix_0f" "1")])
15007 (define_expand "ffsdi2"
15008 [(set (match_dup 2) (const_int -1))
15009 (parallel [(set (reg:CCZ FLAGS_REG)
15010 (compare:CCZ (match_operand:DI 1 "register_operand" "")
15012 (set (match_operand:DI 0 "nonimmediate_operand" "")
15013 (ctz:DI (match_dup 1)))])
15014 (set (match_dup 0) (if_then_else:DI
15015 (eq (reg:CCZ FLAGS_REG) (const_int 0))
15018 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15019 (clobber (reg:CC FLAGS_REG))])]
15021 "operands[2] = gen_reg_rtx (DImode);")
15023 (define_insn "*ffsdi_1"
15024 [(set (reg:CCZ FLAGS_REG)
15025 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15027 (set (match_operand:DI 0 "register_operand" "=r")
15028 (ctz:DI (match_dup 1)))]
15030 "bsf{q}\t{%1, %0|%0, %1}"
15031 [(set_attr "prefix_0f" "1")])
15033 (define_insn "ctzsi2"
15034 [(set (match_operand:SI 0 "register_operand" "=r")
15035 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15036 (clobber (reg:CC FLAGS_REG))]
15038 "bsf{l}\t{%1, %0|%0, %1}"
15039 [(set_attr "prefix_0f" "1")])
15041 (define_insn "ctzdi2"
15042 [(set (match_operand:DI 0 "register_operand" "=r")
15043 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15044 (clobber (reg:CC FLAGS_REG))]
15046 "bsf{q}\t{%1, %0|%0, %1}"
15047 [(set_attr "prefix_0f" "1")])
15049 (define_expand "clzsi2"
15051 [(set (match_operand:SI 0 "register_operand" "")
15052 (minus:SI (const_int 31)
15053 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15054 (clobber (reg:CC FLAGS_REG))])
15056 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15057 (clobber (reg:CC FLAGS_REG))])]
15062 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15067 (define_insn "clzsi2_abm"
15068 [(set (match_operand:SI 0 "register_operand" "=r")
15069 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15070 (clobber (reg:CC FLAGS_REG))]
15072 "lzcnt{l}\t{%1, %0|%0, %1}"
15073 [(set_attr "prefix_rep" "1")
15074 (set_attr "type" "bitmanip")
15075 (set_attr "mode" "SI")])
15077 (define_insn "*bsr"
15078 [(set (match_operand:SI 0 "register_operand" "=r")
15079 (minus:SI (const_int 31)
15080 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15081 (clobber (reg:CC FLAGS_REG))]
15083 "bsr{l}\t{%1, %0|%0, %1}"
15084 [(set_attr "prefix_0f" "1")
15085 (set_attr "mode" "SI")])
15087 (define_insn "popcountsi2"
15088 [(set (match_operand:SI 0 "register_operand" "=r")
15089 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15090 (clobber (reg:CC FLAGS_REG))]
15092 "popcnt{l}\t{%1, %0|%0, %1}"
15093 [(set_attr "prefix_rep" "1")
15094 (set_attr "type" "bitmanip")
15095 (set_attr "mode" "SI")])
15097 (define_insn "*popcountsi2_cmp"
15098 [(set (reg FLAGS_REG)
15100 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15102 (set (match_operand:SI 0 "register_operand" "=r")
15103 (popcount:SI (match_dup 1)))]
15104 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15105 "popcnt{l}\t{%1, %0|%0, %1}"
15106 [(set_attr "prefix_rep" "1")
15107 (set_attr "type" "bitmanip")
15108 (set_attr "mode" "SI")])
15110 (define_insn "*popcountsi2_cmp_zext"
15111 [(set (reg FLAGS_REG)
15113 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15115 (set (match_operand:DI 0 "register_operand" "=r")
15116 (zero_extend:DI(popcount:SI (match_dup 1))))]
15117 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15118 "popcnt{l}\t{%1, %0|%0, %1}"
15119 [(set_attr "prefix_rep" "1")
15120 (set_attr "type" "bitmanip")
15121 (set_attr "mode" "SI")])
15123 (define_expand "bswapsi2"
15124 [(set (match_operand:SI 0 "register_operand" "")
15125 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15130 rtx x = operands[0];
15132 emit_move_insn (x, operands[1]);
15133 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15134 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15135 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15140 (define_insn "*bswapsi_1"
15141 [(set (match_operand:SI 0 "register_operand" "=r")
15142 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15145 [(set_attr "prefix_0f" "1")
15146 (set_attr "length" "2")])
15148 (define_insn "*bswaphi_lowpart_1"
15149 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15150 (bswap:HI (match_dup 0)))
15151 (clobber (reg:CC FLAGS_REG))]
15152 "TARGET_USE_XCHGB || optimize_size"
15154 xchg{b}\t{%h0, %b0|%b0, %h0}
15155 rol{w}\t{$8, %0|%0, 8}"
15156 [(set_attr "length" "2,4")
15157 (set_attr "mode" "QI,HI")])
15159 (define_insn "bswaphi_lowpart"
15160 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15161 (bswap:HI (match_dup 0)))
15162 (clobber (reg:CC FLAGS_REG))]
15164 "rol{w}\t{$8, %0|%0, 8}"
15165 [(set_attr "length" "4")
15166 (set_attr "mode" "HI")])
15168 (define_insn "bswapdi2"
15169 [(set (match_operand:DI 0 "register_operand" "=r")
15170 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15173 [(set_attr "prefix_0f" "1")
15174 (set_attr "length" "3")])
15176 (define_expand "clzdi2"
15178 [(set (match_operand:DI 0 "register_operand" "")
15179 (minus:DI (const_int 63)
15180 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15181 (clobber (reg:CC FLAGS_REG))])
15183 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15184 (clobber (reg:CC FLAGS_REG))])]
15189 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15194 (define_insn "clzdi2_abm"
15195 [(set (match_operand:DI 0 "register_operand" "=r")
15196 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15197 (clobber (reg:CC FLAGS_REG))]
15198 "TARGET_64BIT && TARGET_ABM"
15199 "lzcnt{q}\t{%1, %0|%0, %1}"
15200 [(set_attr "prefix_rep" "1")
15201 (set_attr "type" "bitmanip")
15202 (set_attr "mode" "DI")])
15204 (define_insn "*bsr_rex64"
15205 [(set (match_operand:DI 0 "register_operand" "=r")
15206 (minus:DI (const_int 63)
15207 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15208 (clobber (reg:CC FLAGS_REG))]
15210 "bsr{q}\t{%1, %0|%0, %1}"
15211 [(set_attr "prefix_0f" "1")
15212 (set_attr "mode" "DI")])
15214 (define_insn "popcountdi2"
15215 [(set (match_operand:DI 0 "register_operand" "=r")
15216 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15217 (clobber (reg:CC FLAGS_REG))]
15218 "TARGET_64BIT && TARGET_POPCNT"
15219 "popcnt{q}\t{%1, %0|%0, %1}"
15220 [(set_attr "prefix_rep" "1")
15221 (set_attr "type" "bitmanip")
15222 (set_attr "mode" "DI")])
15224 (define_insn "*popcountdi2_cmp"
15225 [(set (reg FLAGS_REG)
15227 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15229 (set (match_operand:DI 0 "register_operand" "=r")
15230 (popcount:DI (match_dup 1)))]
15231 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15232 "popcnt{q}\t{%1, %0|%0, %1}"
15233 [(set_attr "prefix_rep" "1")
15234 (set_attr "type" "bitmanip")
15235 (set_attr "mode" "DI")])
15237 (define_expand "clzhi2"
15239 [(set (match_operand:HI 0 "register_operand" "")
15240 (minus:HI (const_int 15)
15241 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15242 (clobber (reg:CC FLAGS_REG))])
15244 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15245 (clobber (reg:CC FLAGS_REG))])]
15250 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15255 (define_insn "clzhi2_abm"
15256 [(set (match_operand:HI 0 "register_operand" "=r")
15257 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15258 (clobber (reg:CC FLAGS_REG))]
15260 "lzcnt{w}\t{%1, %0|%0, %1}"
15261 [(set_attr "prefix_rep" "1")
15262 (set_attr "type" "bitmanip")
15263 (set_attr "mode" "HI")])
15265 (define_insn "*bsrhi"
15266 [(set (match_operand:HI 0 "register_operand" "=r")
15267 (minus:HI (const_int 15)
15268 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15269 (clobber (reg:CC FLAGS_REG))]
15271 "bsr{w}\t{%1, %0|%0, %1}"
15272 [(set_attr "prefix_0f" "1")
15273 (set_attr "mode" "HI")])
15275 (define_insn "popcounthi2"
15276 [(set (match_operand:HI 0 "register_operand" "=r")
15277 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15278 (clobber (reg:CC FLAGS_REG))]
15280 "popcnt{w}\t{%1, %0|%0, %1}"
15281 [(set_attr "prefix_rep" "1")
15282 (set_attr "type" "bitmanip")
15283 (set_attr "mode" "HI")])
15285 (define_insn "*popcounthi2_cmp"
15286 [(set (reg FLAGS_REG)
15288 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15290 (set (match_operand:HI 0 "register_operand" "=r")
15291 (popcount:HI (match_dup 1)))]
15292 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15293 "popcnt{w}\t{%1, %0|%0, %1}"
15294 [(set_attr "prefix_rep" "1")
15295 (set_attr "type" "bitmanip")
15296 (set_attr "mode" "HI")])
15298 (define_expand "paritydi2"
15299 [(set (match_operand:DI 0 "register_operand" "")
15300 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15303 rtx scratch = gen_reg_rtx (QImode);
15306 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15307 NULL_RTX, operands[1]));
15309 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15310 gen_rtx_REG (CCmode, FLAGS_REG),
15312 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15315 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15318 rtx tmp = gen_reg_rtx (SImode);
15320 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15321 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15326 (define_insn_and_split "paritydi2_cmp"
15327 [(set (reg:CC FLAGS_REG)
15328 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15329 (clobber (match_scratch:DI 0 "=r"))
15330 (clobber (match_scratch:SI 1 "=&r"))
15331 (clobber (match_scratch:HI 2 "=Q"))]
15334 "&& reload_completed"
15336 [(set (match_dup 1)
15337 (xor:SI (match_dup 1) (match_dup 4)))
15338 (clobber (reg:CC FLAGS_REG))])
15340 [(set (reg:CC FLAGS_REG)
15341 (parity:CC (match_dup 1)))
15342 (clobber (match_dup 1))
15343 (clobber (match_dup 2))])]
15345 operands[4] = gen_lowpart (SImode, operands[3]);
15349 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15350 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15353 operands[1] = gen_highpart (SImode, operands[3]);
15356 (define_expand "paritysi2"
15357 [(set (match_operand:SI 0 "register_operand" "")
15358 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15361 rtx scratch = gen_reg_rtx (QImode);
15364 emit_insn (gen_paritysi2_cmp (NULL_RTX, 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));
15371 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15375 (define_insn_and_split "paritysi2_cmp"
15376 [(set (reg:CC FLAGS_REG)
15377 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15378 (clobber (match_scratch:SI 0 "=r"))
15379 (clobber (match_scratch:HI 1 "=&Q"))]
15382 "&& reload_completed"
15384 [(set (match_dup 1)
15385 (xor:HI (match_dup 1) (match_dup 3)))
15386 (clobber (reg:CC FLAGS_REG))])
15388 [(set (reg:CC FLAGS_REG)
15389 (parity:CC (match_dup 1)))
15390 (clobber (match_dup 1))])]
15392 operands[3] = gen_lowpart (HImode, operands[2]);
15394 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15395 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15398 (define_insn "*parityhi2_cmp"
15399 [(set (reg:CC FLAGS_REG)
15400 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15401 (clobber (match_scratch:HI 0 "=Q"))]
15403 "xor{b}\t{%h0, %b0|%b0, %h0}"
15404 [(set_attr "length" "2")
15405 (set_attr "mode" "HI")])
15407 (define_insn "*parityqi2_cmp"
15408 [(set (reg:CC FLAGS_REG)
15409 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15412 [(set_attr "length" "2")
15413 (set_attr "mode" "QI")])
15415 ;; Thread-local storage patterns for ELF.
15417 ;; Note that these code sequences must appear exactly as shown
15418 ;; in order to allow linker relaxation.
15420 (define_insn "*tls_global_dynamic_32_gnu"
15421 [(set (match_operand:SI 0 "register_operand" "=a")
15422 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15423 (match_operand:SI 2 "tls_symbolic_operand" "")
15424 (match_operand:SI 3 "call_insn_operand" "")]
15426 (clobber (match_scratch:SI 4 "=d"))
15427 (clobber (match_scratch:SI 5 "=c"))
15428 (clobber (reg:CC FLAGS_REG))]
15429 "!TARGET_64BIT && TARGET_GNU_TLS"
15430 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15431 [(set_attr "type" "multi")
15432 (set_attr "length" "12")])
15434 (define_insn "*tls_global_dynamic_32_sun"
15435 [(set (match_operand:SI 0 "register_operand" "=a")
15436 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15437 (match_operand:SI 2 "tls_symbolic_operand" "")
15438 (match_operand:SI 3 "call_insn_operand" "")]
15440 (clobber (match_scratch:SI 4 "=d"))
15441 (clobber (match_scratch:SI 5 "=c"))
15442 (clobber (reg:CC FLAGS_REG))]
15443 "!TARGET_64BIT && TARGET_SUN_TLS"
15444 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15445 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15446 [(set_attr "type" "multi")
15447 (set_attr "length" "14")])
15449 (define_expand "tls_global_dynamic_32"
15450 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15453 (match_operand:SI 1 "tls_symbolic_operand" "")
15456 (clobber (match_scratch:SI 4 ""))
15457 (clobber (match_scratch:SI 5 ""))
15458 (clobber (reg:CC FLAGS_REG))])]
15462 operands[2] = pic_offset_table_rtx;
15465 operands[2] = gen_reg_rtx (Pmode);
15466 emit_insn (gen_set_got (operands[2]));
15468 if (TARGET_GNU2_TLS)
15470 emit_insn (gen_tls_dynamic_gnu2_32
15471 (operands[0], operands[1], operands[2]));
15474 operands[3] = ix86_tls_get_addr ();
15477 (define_insn "*tls_global_dynamic_64"
15478 [(set (match_operand:DI 0 "register_operand" "=a")
15479 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15480 (match_operand:DI 3 "" "")))
15481 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15484 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15485 [(set_attr "type" "multi")
15486 (set_attr "length" "16")])
15488 (define_expand "tls_global_dynamic_64"
15489 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15490 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15491 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15495 if (TARGET_GNU2_TLS)
15497 emit_insn (gen_tls_dynamic_gnu2_64
15498 (operands[0], operands[1]));
15501 operands[2] = ix86_tls_get_addr ();
15504 (define_insn "*tls_local_dynamic_base_32_gnu"
15505 [(set (match_operand:SI 0 "register_operand" "=a")
15506 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15507 (match_operand:SI 2 "call_insn_operand" "")]
15508 UNSPEC_TLS_LD_BASE))
15509 (clobber (match_scratch:SI 3 "=d"))
15510 (clobber (match_scratch:SI 4 "=c"))
15511 (clobber (reg:CC FLAGS_REG))]
15512 "!TARGET_64BIT && TARGET_GNU_TLS"
15513 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15514 [(set_attr "type" "multi")
15515 (set_attr "length" "11")])
15517 (define_insn "*tls_local_dynamic_base_32_sun"
15518 [(set (match_operand:SI 0 "register_operand" "=a")
15519 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15520 (match_operand:SI 2 "call_insn_operand" "")]
15521 UNSPEC_TLS_LD_BASE))
15522 (clobber (match_scratch:SI 3 "=d"))
15523 (clobber (match_scratch:SI 4 "=c"))
15524 (clobber (reg:CC FLAGS_REG))]
15525 "!TARGET_64BIT && TARGET_SUN_TLS"
15526 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15527 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15528 [(set_attr "type" "multi")
15529 (set_attr "length" "13")])
15531 (define_expand "tls_local_dynamic_base_32"
15532 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15533 (unspec:SI [(match_dup 1) (match_dup 2)]
15534 UNSPEC_TLS_LD_BASE))
15535 (clobber (match_scratch:SI 3 ""))
15536 (clobber (match_scratch:SI 4 ""))
15537 (clobber (reg:CC FLAGS_REG))])]
15541 operands[1] = pic_offset_table_rtx;
15544 operands[1] = gen_reg_rtx (Pmode);
15545 emit_insn (gen_set_got (operands[1]));
15547 if (TARGET_GNU2_TLS)
15549 emit_insn (gen_tls_dynamic_gnu2_32
15550 (operands[0], ix86_tls_module_base (), operands[1]));
15553 operands[2] = ix86_tls_get_addr ();
15556 (define_insn "*tls_local_dynamic_base_64"
15557 [(set (match_operand:DI 0 "register_operand" "=a")
15558 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15559 (match_operand:DI 2 "" "")))
15560 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15562 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15563 [(set_attr "type" "multi")
15564 (set_attr "length" "12")])
15566 (define_expand "tls_local_dynamic_base_64"
15567 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15568 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15569 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15572 if (TARGET_GNU2_TLS)
15574 emit_insn (gen_tls_dynamic_gnu2_64
15575 (operands[0], ix86_tls_module_base ()));
15578 operands[1] = ix86_tls_get_addr ();
15581 ;; Local dynamic of a single variable is a lose. Show combine how
15582 ;; to convert that back to global dynamic.
15584 (define_insn_and_split "*tls_local_dynamic_32_once"
15585 [(set (match_operand:SI 0 "register_operand" "=a")
15586 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15587 (match_operand:SI 2 "call_insn_operand" "")]
15588 UNSPEC_TLS_LD_BASE)
15589 (const:SI (unspec:SI
15590 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15592 (clobber (match_scratch:SI 4 "=d"))
15593 (clobber (match_scratch:SI 5 "=c"))
15594 (clobber (reg:CC FLAGS_REG))]
15598 [(parallel [(set (match_dup 0)
15599 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15601 (clobber (match_dup 4))
15602 (clobber (match_dup 5))
15603 (clobber (reg:CC FLAGS_REG))])]
15606 ;; Load and add the thread base pointer from %gs:0.
15608 (define_insn "*load_tp_si"
15609 [(set (match_operand:SI 0 "register_operand" "=r")
15610 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15612 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15613 [(set_attr "type" "imov")
15614 (set_attr "modrm" "0")
15615 (set_attr "length" "7")
15616 (set_attr "memory" "load")
15617 (set_attr "imm_disp" "false")])
15619 (define_insn "*add_tp_si"
15620 [(set (match_operand:SI 0 "register_operand" "=r")
15621 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15622 (match_operand:SI 1 "register_operand" "0")))
15623 (clobber (reg:CC FLAGS_REG))]
15625 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15626 [(set_attr "type" "alu")
15627 (set_attr "modrm" "0")
15628 (set_attr "length" "7")
15629 (set_attr "memory" "load")
15630 (set_attr "imm_disp" "false")])
15632 (define_insn "*load_tp_di"
15633 [(set (match_operand:DI 0 "register_operand" "=r")
15634 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15636 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15637 [(set_attr "type" "imov")
15638 (set_attr "modrm" "0")
15639 (set_attr "length" "7")
15640 (set_attr "memory" "load")
15641 (set_attr "imm_disp" "false")])
15643 (define_insn "*add_tp_di"
15644 [(set (match_operand:DI 0 "register_operand" "=r")
15645 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15646 (match_operand:DI 1 "register_operand" "0")))
15647 (clobber (reg:CC FLAGS_REG))]
15649 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15650 [(set_attr "type" "alu")
15651 (set_attr "modrm" "0")
15652 (set_attr "length" "7")
15653 (set_attr "memory" "load")
15654 (set_attr "imm_disp" "false")])
15656 ;; GNU2 TLS patterns can be split.
15658 (define_expand "tls_dynamic_gnu2_32"
15659 [(set (match_dup 3)
15660 (plus:SI (match_operand:SI 2 "register_operand" "")
15662 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15665 [(set (match_operand:SI 0 "register_operand" "")
15666 (unspec:SI [(match_dup 1) (match_dup 3)
15667 (match_dup 2) (reg:SI SP_REG)]
15669 (clobber (reg:CC FLAGS_REG))])]
15670 "!TARGET_64BIT && TARGET_GNU2_TLS"
15672 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15673 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15676 (define_insn "*tls_dynamic_lea_32"
15677 [(set (match_operand:SI 0 "register_operand" "=r")
15678 (plus:SI (match_operand:SI 1 "register_operand" "b")
15680 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15681 UNSPEC_TLSDESC))))]
15682 "!TARGET_64BIT && TARGET_GNU2_TLS"
15683 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15684 [(set_attr "type" "lea")
15685 (set_attr "mode" "SI")
15686 (set_attr "length" "6")
15687 (set_attr "length_address" "4")])
15689 (define_insn "*tls_dynamic_call_32"
15690 [(set (match_operand:SI 0 "register_operand" "=a")
15691 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15692 (match_operand:SI 2 "register_operand" "0")
15693 ;; we have to make sure %ebx still points to the GOT
15694 (match_operand:SI 3 "register_operand" "b")
15697 (clobber (reg:CC FLAGS_REG))]
15698 "!TARGET_64BIT && TARGET_GNU2_TLS"
15699 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15700 [(set_attr "type" "call")
15701 (set_attr "length" "2")
15702 (set_attr "length_address" "0")])
15704 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15705 [(set (match_operand:SI 0 "register_operand" "=&a")
15707 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15708 (match_operand:SI 4 "" "")
15709 (match_operand:SI 2 "register_operand" "b")
15712 (const:SI (unspec:SI
15713 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15715 (clobber (reg:CC FLAGS_REG))]
15716 "!TARGET_64BIT && TARGET_GNU2_TLS"
15719 [(set (match_dup 0) (match_dup 5))]
15721 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15722 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15725 (define_expand "tls_dynamic_gnu2_64"
15726 [(set (match_dup 2)
15727 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15730 [(set (match_operand:DI 0 "register_operand" "")
15731 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15733 (clobber (reg:CC FLAGS_REG))])]
15734 "TARGET_64BIT && TARGET_GNU2_TLS"
15736 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15737 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15740 (define_insn "*tls_dynamic_lea_64"
15741 [(set (match_operand:DI 0 "register_operand" "=r")
15742 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15744 "TARGET_64BIT && TARGET_GNU2_TLS"
15745 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15746 [(set_attr "type" "lea")
15747 (set_attr "mode" "DI")
15748 (set_attr "length" "7")
15749 (set_attr "length_address" "4")])
15751 (define_insn "*tls_dynamic_call_64"
15752 [(set (match_operand:DI 0 "register_operand" "=a")
15753 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15754 (match_operand:DI 2 "register_operand" "0")
15757 (clobber (reg:CC FLAGS_REG))]
15758 "TARGET_64BIT && TARGET_GNU2_TLS"
15759 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15760 [(set_attr "type" "call")
15761 (set_attr "length" "2")
15762 (set_attr "length_address" "0")])
15764 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15765 [(set (match_operand:DI 0 "register_operand" "=&a")
15767 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15768 (match_operand:DI 3 "" "")
15771 (const:DI (unspec:DI
15772 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15774 (clobber (reg:CC FLAGS_REG))]
15775 "TARGET_64BIT && TARGET_GNU2_TLS"
15778 [(set (match_dup 0) (match_dup 4))]
15780 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15781 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15786 ;; These patterns match the binary 387 instructions for addM3, subM3,
15787 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15788 ;; SFmode. The first is the normal insn, the second the same insn but
15789 ;; with one operand a conversion, and the third the same insn but with
15790 ;; the other operand a conversion. The conversion may be SFmode or
15791 ;; SImode if the target mode DFmode, but only SImode if the target mode
15794 ;; Gcc is slightly more smart about handling normal two address instructions
15795 ;; so use special patterns for add and mull.
15797 (define_insn "*fop_sf_comm_mixed"
15798 [(set (match_operand:SF 0 "register_operand" "=f,x")
15799 (match_operator:SF 3 "binary_fp_operator"
15800 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15801 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15802 "TARGET_MIX_SSE_I387
15803 && COMMUTATIVE_ARITH_P (operands[3])
15804 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15805 "* return output_387_binary_op (insn, operands);"
15806 [(set (attr "type")
15807 (if_then_else (eq_attr "alternative" "1")
15808 (if_then_else (match_operand:SF 3 "mult_operator" "")
15809 (const_string "ssemul")
15810 (const_string "sseadd"))
15811 (if_then_else (match_operand:SF 3 "mult_operator" "")
15812 (const_string "fmul")
15813 (const_string "fop"))))
15814 (set_attr "mode" "SF")])
15816 (define_insn "*fop_sf_comm_sse"
15817 [(set (match_operand:SF 0 "register_operand" "=x")
15818 (match_operator:SF 3 "binary_fp_operator"
15819 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15820 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15822 && COMMUTATIVE_ARITH_P (operands[3])
15823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15824 "* return output_387_binary_op (insn, operands);"
15825 [(set (attr "type")
15826 (if_then_else (match_operand:SF 3 "mult_operator" "")
15827 (const_string "ssemul")
15828 (const_string "sseadd")))
15829 (set_attr "mode" "SF")])
15831 (define_insn "*fop_sf_comm_i387"
15832 [(set (match_operand:SF 0 "register_operand" "=f")
15833 (match_operator:SF 3 "binary_fp_operator"
15834 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15835 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15837 && COMMUTATIVE_ARITH_P (operands[3])
15838 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15839 "* return output_387_binary_op (insn, operands);"
15840 [(set (attr "type")
15841 (if_then_else (match_operand:SF 3 "mult_operator" "")
15842 (const_string "fmul")
15843 (const_string "fop")))
15844 (set_attr "mode" "SF")])
15846 (define_insn "*fop_sf_1_mixed"
15847 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15848 (match_operator:SF 3 "binary_fp_operator"
15849 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15850 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15851 "TARGET_MIX_SSE_I387
15852 && !COMMUTATIVE_ARITH_P (operands[3])
15853 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15854 "* return output_387_binary_op (insn, operands);"
15855 [(set (attr "type")
15856 (cond [(and (eq_attr "alternative" "2")
15857 (match_operand:SF 3 "mult_operator" ""))
15858 (const_string "ssemul")
15859 (and (eq_attr "alternative" "2")
15860 (match_operand:SF 3 "div_operator" ""))
15861 (const_string "ssediv")
15862 (eq_attr "alternative" "2")
15863 (const_string "sseadd")
15864 (match_operand:SF 3 "mult_operator" "")
15865 (const_string "fmul")
15866 (match_operand:SF 3 "div_operator" "")
15867 (const_string "fdiv")
15869 (const_string "fop")))
15870 (set_attr "mode" "SF")])
15872 (define_insn "*rcpsf2_sse"
15873 [(set (match_operand:SF 0 "register_operand" "=x")
15874 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15877 "rcpss\t{%1, %0|%0, %1}"
15878 [(set_attr "type" "sse")
15879 (set_attr "mode" "SF")])
15881 (define_insn "*fop_sf_1_sse"
15882 [(set (match_operand:SF 0 "register_operand" "=x")
15883 (match_operator:SF 3 "binary_fp_operator"
15884 [(match_operand:SF 1 "register_operand" "0")
15885 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15887 && !COMMUTATIVE_ARITH_P (operands[3])"
15888 "* return output_387_binary_op (insn, operands);"
15889 [(set (attr "type")
15890 (cond [(match_operand:SF 3 "mult_operator" "")
15891 (const_string "ssemul")
15892 (match_operand:SF 3 "div_operator" "")
15893 (const_string "ssediv")
15895 (const_string "sseadd")))
15896 (set_attr "mode" "SF")])
15898 ;; This pattern is not fully shadowed by the pattern above.
15899 (define_insn "*fop_sf_1_i387"
15900 [(set (match_operand:SF 0 "register_operand" "=f,f")
15901 (match_operator:SF 3 "binary_fp_operator"
15902 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15903 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15904 "TARGET_80387 && !TARGET_SSE_MATH
15905 && !COMMUTATIVE_ARITH_P (operands[3])
15906 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15907 "* return output_387_binary_op (insn, operands);"
15908 [(set (attr "type")
15909 (cond [(match_operand:SF 3 "mult_operator" "")
15910 (const_string "fmul")
15911 (match_operand:SF 3 "div_operator" "")
15912 (const_string "fdiv")
15914 (const_string "fop")))
15915 (set_attr "mode" "SF")])
15917 ;; ??? Add SSE splitters for these!
15918 (define_insn "*fop_sf_2<mode>_i387"
15919 [(set (match_operand:SF 0 "register_operand" "=f,f")
15920 (match_operator:SF 3 "binary_fp_operator"
15921 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15922 (match_operand:SF 2 "register_operand" "0,0")]))]
15923 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15924 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15925 [(set (attr "type")
15926 (cond [(match_operand:SF 3 "mult_operator" "")
15927 (const_string "fmul")
15928 (match_operand:SF 3 "div_operator" "")
15929 (const_string "fdiv")
15931 (const_string "fop")))
15932 (set_attr "fp_int_src" "true")
15933 (set_attr "mode" "<MODE>")])
15935 (define_insn "*fop_sf_3<mode>_i387"
15936 [(set (match_operand:SF 0 "register_operand" "=f,f")
15937 (match_operator:SF 3 "binary_fp_operator"
15938 [(match_operand:SF 1 "register_operand" "0,0")
15939 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15940 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15941 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15942 [(set (attr "type")
15943 (cond [(match_operand:SF 3 "mult_operator" "")
15944 (const_string "fmul")
15945 (match_operand:SF 3 "div_operator" "")
15946 (const_string "fdiv")
15948 (const_string "fop")))
15949 (set_attr "fp_int_src" "true")
15950 (set_attr "mode" "<MODE>")])
15952 (define_insn "*fop_df_comm_mixed"
15953 [(set (match_operand:DF 0 "register_operand" "=f,x")
15954 (match_operator:DF 3 "binary_fp_operator"
15955 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15956 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15957 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15958 && COMMUTATIVE_ARITH_P (operands[3])
15959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15960 "* return output_387_binary_op (insn, operands);"
15961 [(set (attr "type")
15962 (if_then_else (eq_attr "alternative" "1")
15963 (if_then_else (match_operand:DF 3 "mult_operator" "")
15964 (const_string "ssemul")
15965 (const_string "sseadd"))
15966 (if_then_else (match_operand:DF 3 "mult_operator" "")
15967 (const_string "fmul")
15968 (const_string "fop"))))
15969 (set_attr "mode" "DF")])
15971 (define_insn "*fop_df_comm_sse"
15972 [(set (match_operand:DF 0 "register_operand" "=x")
15973 (match_operator:DF 3 "binary_fp_operator"
15974 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15975 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15976 "TARGET_SSE2 && TARGET_SSE_MATH
15977 && COMMUTATIVE_ARITH_P (operands[3])
15978 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15979 "* return output_387_binary_op (insn, operands);"
15980 [(set (attr "type")
15981 (if_then_else (match_operand:DF 3 "mult_operator" "")
15982 (const_string "ssemul")
15983 (const_string "sseadd")))
15984 (set_attr "mode" "DF")])
15986 (define_insn "*fop_df_comm_i387"
15987 [(set (match_operand:DF 0 "register_operand" "=f")
15988 (match_operator:DF 3 "binary_fp_operator"
15989 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15990 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15992 && COMMUTATIVE_ARITH_P (operands[3])
15993 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15994 "* return output_387_binary_op (insn, operands);"
15995 [(set (attr "type")
15996 (if_then_else (match_operand:DF 3 "mult_operator" "")
15997 (const_string "fmul")
15998 (const_string "fop")))
15999 (set_attr "mode" "DF")])
16001 (define_insn "*fop_df_1_mixed"
16002 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16003 (match_operator:DF 3 "binary_fp_operator"
16004 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16005 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16006 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16007 && !COMMUTATIVE_ARITH_P (operands[3])
16008 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16009 "* return output_387_binary_op (insn, operands);"
16010 [(set (attr "type")
16011 (cond [(and (eq_attr "alternative" "2")
16012 (match_operand:DF 3 "mult_operator" ""))
16013 (const_string "ssemul")
16014 (and (eq_attr "alternative" "2")
16015 (match_operand:DF 3 "div_operator" ""))
16016 (const_string "ssediv")
16017 (eq_attr "alternative" "2")
16018 (const_string "sseadd")
16019 (match_operand:DF 3 "mult_operator" "")
16020 (const_string "fmul")
16021 (match_operand:DF 3 "div_operator" "")
16022 (const_string "fdiv")
16024 (const_string "fop")))
16025 (set_attr "mode" "DF")])
16027 (define_insn "*fop_df_1_sse"
16028 [(set (match_operand:DF 0 "register_operand" "=x")
16029 (match_operator:DF 3 "binary_fp_operator"
16030 [(match_operand:DF 1 "register_operand" "0")
16031 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16032 "TARGET_SSE2 && TARGET_SSE_MATH
16033 && !COMMUTATIVE_ARITH_P (operands[3])"
16034 "* return output_387_binary_op (insn, operands);"
16035 [(set_attr "mode" "DF")
16037 (cond [(match_operand:DF 3 "mult_operator" "")
16038 (const_string "ssemul")
16039 (match_operand:DF 3 "div_operator" "")
16040 (const_string "ssediv")
16042 (const_string "sseadd")))])
16044 ;; This pattern is not fully shadowed by the pattern above.
16045 (define_insn "*fop_df_1_i387"
16046 [(set (match_operand:DF 0 "register_operand" "=f,f")
16047 (match_operator:DF 3 "binary_fp_operator"
16048 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16049 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16050 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16051 && !COMMUTATIVE_ARITH_P (operands[3])
16052 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16053 "* return output_387_binary_op (insn, operands);"
16054 [(set (attr "type")
16055 (cond [(match_operand:DF 3 "mult_operator" "")
16056 (const_string "fmul")
16057 (match_operand:DF 3 "div_operator" "")
16058 (const_string "fdiv")
16060 (const_string "fop")))
16061 (set_attr "mode" "DF")])
16063 ;; ??? Add SSE splitters for these!
16064 (define_insn "*fop_df_2<mode>_i387"
16065 [(set (match_operand:DF 0 "register_operand" "=f,f")
16066 (match_operator:DF 3 "binary_fp_operator"
16067 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16068 (match_operand:DF 2 "register_operand" "0,0")]))]
16069 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16070 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16071 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16072 [(set (attr "type")
16073 (cond [(match_operand:DF 3 "mult_operator" "")
16074 (const_string "fmul")
16075 (match_operand:DF 3 "div_operator" "")
16076 (const_string "fdiv")
16078 (const_string "fop")))
16079 (set_attr "fp_int_src" "true")
16080 (set_attr "mode" "<MODE>")])
16082 (define_insn "*fop_df_3<mode>_i387"
16083 [(set (match_operand:DF 0 "register_operand" "=f,f")
16084 (match_operator:DF 3 "binary_fp_operator"
16085 [(match_operand:DF 1 "register_operand" "0,0")
16086 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16087 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16088 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16089 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16090 [(set (attr "type")
16091 (cond [(match_operand:DF 3 "mult_operator" "")
16092 (const_string "fmul")
16093 (match_operand:DF 3 "div_operator" "")
16094 (const_string "fdiv")
16096 (const_string "fop")))
16097 (set_attr "fp_int_src" "true")
16098 (set_attr "mode" "<MODE>")])
16100 (define_insn "*fop_df_4_i387"
16101 [(set (match_operand:DF 0 "register_operand" "=f,f")
16102 (match_operator:DF 3 "binary_fp_operator"
16103 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16104 (match_operand:DF 2 "register_operand" "0,f")]))]
16105 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16106 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16107 "* return output_387_binary_op (insn, operands);"
16108 [(set (attr "type")
16109 (cond [(match_operand:DF 3 "mult_operator" "")
16110 (const_string "fmul")
16111 (match_operand:DF 3 "div_operator" "")
16112 (const_string "fdiv")
16114 (const_string "fop")))
16115 (set_attr "mode" "SF")])
16117 (define_insn "*fop_df_5_i387"
16118 [(set (match_operand:DF 0 "register_operand" "=f,f")
16119 (match_operator:DF 3 "binary_fp_operator"
16120 [(match_operand:DF 1 "register_operand" "0,f")
16122 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16123 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16124 "* return output_387_binary_op (insn, operands);"
16125 [(set (attr "type")
16126 (cond [(match_operand:DF 3 "mult_operator" "")
16127 (const_string "fmul")
16128 (match_operand:DF 3 "div_operator" "")
16129 (const_string "fdiv")
16131 (const_string "fop")))
16132 (set_attr "mode" "SF")])
16134 (define_insn "*fop_df_6_i387"
16135 [(set (match_operand:DF 0 "register_operand" "=f,f")
16136 (match_operator:DF 3 "binary_fp_operator"
16138 (match_operand:SF 1 "register_operand" "0,f"))
16140 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16141 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16142 "* return output_387_binary_op (insn, operands);"
16143 [(set (attr "type")
16144 (cond [(match_operand:DF 3 "mult_operator" "")
16145 (const_string "fmul")
16146 (match_operand:DF 3 "div_operator" "")
16147 (const_string "fdiv")
16149 (const_string "fop")))
16150 (set_attr "mode" "SF")])
16152 (define_insn "*fop_xf_comm_i387"
16153 [(set (match_operand:XF 0 "register_operand" "=f")
16154 (match_operator:XF 3 "binary_fp_operator"
16155 [(match_operand:XF 1 "register_operand" "%0")
16156 (match_operand:XF 2 "register_operand" "f")]))]
16158 && COMMUTATIVE_ARITH_P (operands[3])"
16159 "* return output_387_binary_op (insn, operands);"
16160 [(set (attr "type")
16161 (if_then_else (match_operand:XF 3 "mult_operator" "")
16162 (const_string "fmul")
16163 (const_string "fop")))
16164 (set_attr "mode" "XF")])
16166 (define_insn "*fop_xf_1_i387"
16167 [(set (match_operand:XF 0 "register_operand" "=f,f")
16168 (match_operator:XF 3 "binary_fp_operator"
16169 [(match_operand:XF 1 "register_operand" "0,f")
16170 (match_operand:XF 2 "register_operand" "f,0")]))]
16172 && !COMMUTATIVE_ARITH_P (operands[3])"
16173 "* return output_387_binary_op (insn, operands);"
16174 [(set (attr "type")
16175 (cond [(match_operand:XF 3 "mult_operator" "")
16176 (const_string "fmul")
16177 (match_operand:XF 3 "div_operator" "")
16178 (const_string "fdiv")
16180 (const_string "fop")))
16181 (set_attr "mode" "XF")])
16183 (define_insn "*fop_xf_2<mode>_i387"
16184 [(set (match_operand:XF 0 "register_operand" "=f,f")
16185 (match_operator:XF 3 "binary_fp_operator"
16186 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16187 (match_operand:XF 2 "register_operand" "0,0")]))]
16188 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16189 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16190 [(set (attr "type")
16191 (cond [(match_operand:XF 3 "mult_operator" "")
16192 (const_string "fmul")
16193 (match_operand:XF 3 "div_operator" "")
16194 (const_string "fdiv")
16196 (const_string "fop")))
16197 (set_attr "fp_int_src" "true")
16198 (set_attr "mode" "<MODE>")])
16200 (define_insn "*fop_xf_3<mode>_i387"
16201 [(set (match_operand:XF 0 "register_operand" "=f,f")
16202 (match_operator:XF 3 "binary_fp_operator"
16203 [(match_operand:XF 1 "register_operand" "0,0")
16204 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16205 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16206 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16207 [(set (attr "type")
16208 (cond [(match_operand:XF 3 "mult_operator" "")
16209 (const_string "fmul")
16210 (match_operand:XF 3 "div_operator" "")
16211 (const_string "fdiv")
16213 (const_string "fop")))
16214 (set_attr "fp_int_src" "true")
16215 (set_attr "mode" "<MODE>")])
16217 (define_insn "*fop_xf_4_i387"
16218 [(set (match_operand:XF 0 "register_operand" "=f,f")
16219 (match_operator:XF 3 "binary_fp_operator"
16221 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16222 (match_operand:XF 2 "register_operand" "0,f")]))]
16224 "* return output_387_binary_op (insn, operands);"
16225 [(set (attr "type")
16226 (cond [(match_operand:XF 3 "mult_operator" "")
16227 (const_string "fmul")
16228 (match_operand:XF 3 "div_operator" "")
16229 (const_string "fdiv")
16231 (const_string "fop")))
16232 (set_attr "mode" "SF")])
16234 (define_insn "*fop_xf_5_i387"
16235 [(set (match_operand:XF 0 "register_operand" "=f,f")
16236 (match_operator:XF 3 "binary_fp_operator"
16237 [(match_operand:XF 1 "register_operand" "0,f")
16239 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16241 "* return output_387_binary_op (insn, operands);"
16242 [(set (attr "type")
16243 (cond [(match_operand:XF 3 "mult_operator" "")
16244 (const_string "fmul")
16245 (match_operand:XF 3 "div_operator" "")
16246 (const_string "fdiv")
16248 (const_string "fop")))
16249 (set_attr "mode" "SF")])
16251 (define_insn "*fop_xf_6_i387"
16252 [(set (match_operand:XF 0 "register_operand" "=f,f")
16253 (match_operator:XF 3 "binary_fp_operator"
16255 (match_operand:MODEF 1 "register_operand" "0,f"))
16257 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16259 "* return output_387_binary_op (insn, operands);"
16260 [(set (attr "type")
16261 (cond [(match_operand:XF 3 "mult_operator" "")
16262 (const_string "fmul")
16263 (match_operand:XF 3 "div_operator" "")
16264 (const_string "fdiv")
16266 (const_string "fop")))
16267 (set_attr "mode" "SF")])
16270 [(set (match_operand 0 "register_operand" "")
16271 (match_operator 3 "binary_fp_operator"
16272 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16273 (match_operand 2 "register_operand" "")]))]
16275 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16278 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16279 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16280 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16281 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16282 GET_MODE (operands[3]),
16285 ix86_free_from_memory (GET_MODE (operands[1]));
16290 [(set (match_operand 0 "register_operand" "")
16291 (match_operator 3 "binary_fp_operator"
16292 [(match_operand 1 "register_operand" "")
16293 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16295 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16298 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16299 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16300 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16301 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16302 GET_MODE (operands[3]),
16305 ix86_free_from_memory (GET_MODE (operands[2]));
16309 ;; FPU special functions.
16311 ;; This pattern implements a no-op XFmode truncation for
16312 ;; all fancy i386 XFmode math functions.
16314 (define_insn "truncxf<mode>2_i387_noop_unspec"
16315 [(set (match_operand:MODEF 0 "register_operand" "=f")
16316 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16317 UNSPEC_TRUNC_NOOP))]
16318 "TARGET_USE_FANCY_MATH_387"
16319 "* return output_387_reg_move (insn, operands);"
16320 [(set_attr "type" "fmov")
16321 (set_attr "mode" "<MODE>")])
16323 (define_insn "sqrtxf2"
16324 [(set (match_operand:XF 0 "register_operand" "=f")
16325 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16326 "TARGET_USE_FANCY_MATH_387"
16328 [(set_attr "type" "fpspc")
16329 (set_attr "mode" "XF")
16330 (set_attr "athlon_decode" "direct")
16331 (set_attr "amdfam10_decode" "direct")])
16333 (define_insn "sqrt_extend<mode>xf2_i387"
16334 [(set (match_operand:XF 0 "register_operand" "=f")
16337 (match_operand:MODEF 1 "register_operand" "0"))))]
16338 "TARGET_USE_FANCY_MATH_387"
16340 [(set_attr "type" "fpspc")
16341 (set_attr "mode" "XF")
16342 (set_attr "athlon_decode" "direct")
16343 (set_attr "amdfam10_decode" "direct")])
16345 (define_insn "*rsqrtsf2_sse"
16346 [(set (match_operand:SF 0 "register_operand" "=x")
16347 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16350 "rsqrtss\t{%1, %0|%0, %1}"
16351 [(set_attr "type" "sse")
16352 (set_attr "mode" "SF")])
16354 (define_expand "rsqrtsf2"
16355 [(set (match_operand:SF 0 "register_operand" "")
16356 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16360 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16364 (define_insn "*sqrt<mode>2_sse"
16365 [(set (match_operand:MODEF 0 "register_operand" "=x")
16367 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16368 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16369 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16370 [(set_attr "type" "sse")
16371 (set_attr "mode" "<MODE>")
16372 (set_attr "athlon_decode" "*")
16373 (set_attr "amdfam10_decode" "*")])
16375 (define_expand "sqrt<mode>2"
16376 [(set (match_operand:MODEF 0 "register_operand" "")
16378 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16379 "TARGET_USE_FANCY_MATH_387
16380 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16382 if (<MODE>mode == SFmode
16383 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16384 && flag_finite_math_only && !flag_trapping_math
16385 && flag_unsafe_math_optimizations)
16387 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16391 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16393 rtx op0 = gen_reg_rtx (XFmode);
16394 rtx op1 = force_reg (<MODE>mode, operands[1]);
16396 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16397 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16402 (define_insn "fpremxf4_i387"
16403 [(set (match_operand:XF 0 "register_operand" "=f")
16404 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16405 (match_operand:XF 3 "register_operand" "1")]
16407 (set (match_operand:XF 1 "register_operand" "=u")
16408 (unspec:XF [(match_dup 2) (match_dup 3)]
16410 (set (reg:CCFP FPSR_REG)
16411 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16413 "TARGET_USE_FANCY_MATH_387"
16415 [(set_attr "type" "fpspc")
16416 (set_attr "mode" "XF")])
16418 (define_expand "fmodxf3"
16419 [(use (match_operand:XF 0 "register_operand" ""))
16420 (use (match_operand:XF 1 "general_operand" ""))
16421 (use (match_operand:XF 2 "general_operand" ""))]
16422 "TARGET_USE_FANCY_MATH_387"
16424 rtx label = gen_label_rtx ();
16426 rtx op1 = gen_reg_rtx (XFmode);
16427 rtx op2 = gen_reg_rtx (XFmode);
16429 emit_move_insn (op1, operands[1]);
16430 emit_move_insn (op2, operands[2]);
16432 emit_label (label);
16433 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16434 ix86_emit_fp_unordered_jump (label);
16435 LABEL_NUSES (label) = 1;
16437 emit_move_insn (operands[0], op1);
16441 (define_expand "fmod<mode>3"
16442 [(use (match_operand:MODEF 0 "register_operand" ""))
16443 (use (match_operand:MODEF 1 "general_operand" ""))
16444 (use (match_operand:MODEF 2 "general_operand" ""))]
16445 "TARGET_USE_FANCY_MATH_387"
16447 rtx label = gen_label_rtx ();
16449 rtx op1 = gen_reg_rtx (XFmode);
16450 rtx op2 = gen_reg_rtx (XFmode);
16452 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16453 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16455 emit_label (label);
16456 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16457 ix86_emit_fp_unordered_jump (label);
16458 LABEL_NUSES (label) = 1;
16460 /* Truncate the result properly for strict SSE math. */
16461 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16462 && !TARGET_MIX_SSE_I387)
16463 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16465 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16470 (define_insn "fprem1xf4_i387"
16471 [(set (match_operand:XF 0 "register_operand" "=f")
16472 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16473 (match_operand:XF 3 "register_operand" "1")]
16475 (set (match_operand:XF 1 "register_operand" "=u")
16476 (unspec:XF [(match_dup 2) (match_dup 3)]
16478 (set (reg:CCFP FPSR_REG)
16479 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16481 "TARGET_USE_FANCY_MATH_387"
16483 [(set_attr "type" "fpspc")
16484 (set_attr "mode" "XF")])
16486 (define_expand "remainderxf3"
16487 [(use (match_operand:XF 0 "register_operand" ""))
16488 (use (match_operand:XF 1 "general_operand" ""))
16489 (use (match_operand:XF 2 "general_operand" ""))]
16490 "TARGET_USE_FANCY_MATH_387"
16492 rtx label = gen_label_rtx ();
16494 rtx op1 = gen_reg_rtx (XFmode);
16495 rtx op2 = gen_reg_rtx (XFmode);
16497 emit_move_insn (op1, operands[1]);
16498 emit_move_insn (op2, operands[2]);
16500 emit_label (label);
16501 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16502 ix86_emit_fp_unordered_jump (label);
16503 LABEL_NUSES (label) = 1;
16505 emit_move_insn (operands[0], op1);
16509 (define_expand "remainder<mode>3"
16510 [(use (match_operand:MODEF 0 "register_operand" ""))
16511 (use (match_operand:MODEF 1 "general_operand" ""))
16512 (use (match_operand:MODEF 2 "general_operand" ""))]
16513 "TARGET_USE_FANCY_MATH_387"
16515 rtx label = gen_label_rtx ();
16517 rtx op1 = gen_reg_rtx (XFmode);
16518 rtx op2 = gen_reg_rtx (XFmode);
16520 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16521 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16523 emit_label (label);
16525 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16526 ix86_emit_fp_unordered_jump (label);
16527 LABEL_NUSES (label) = 1;
16529 /* Truncate the result properly for strict SSE math. */
16530 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16531 && !TARGET_MIX_SSE_I387)
16532 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16534 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16539 (define_insn "*sinxf2_i387"
16540 [(set (match_operand:XF 0 "register_operand" "=f")
16541 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16542 "TARGET_USE_FANCY_MATH_387
16543 && flag_unsafe_math_optimizations"
16545 [(set_attr "type" "fpspc")
16546 (set_attr "mode" "XF")])
16548 (define_insn "*sin_extend<mode>xf2_i387"
16549 [(set (match_operand:XF 0 "register_operand" "=f")
16550 (unspec:XF [(float_extend:XF
16551 (match_operand:MODEF 1 "register_operand" "0"))]
16553 "TARGET_USE_FANCY_MATH_387
16554 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16555 || TARGET_MIX_SSE_I387)
16556 && flag_unsafe_math_optimizations"
16558 [(set_attr "type" "fpspc")
16559 (set_attr "mode" "XF")])
16561 (define_insn "*cosxf2_i387"
16562 [(set (match_operand:XF 0 "register_operand" "=f")
16563 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16564 "TARGET_USE_FANCY_MATH_387
16565 && flag_unsafe_math_optimizations"
16567 [(set_attr "type" "fpspc")
16568 (set_attr "mode" "XF")])
16570 (define_insn "*cos_extend<mode>xf2_i387"
16571 [(set (match_operand:XF 0 "register_operand" "=f")
16572 (unspec:XF [(float_extend:XF
16573 (match_operand:MODEF 1 "register_operand" "0"))]
16575 "TARGET_USE_FANCY_MATH_387
16576 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16577 || TARGET_MIX_SSE_I387)
16578 && flag_unsafe_math_optimizations"
16580 [(set_attr "type" "fpspc")
16581 (set_attr "mode" "XF")])
16583 ;; When sincos pattern is defined, sin and cos builtin functions will be
16584 ;; expanded to sincos pattern with one of its outputs left unused.
16585 ;; CSE pass will figure out if two sincos patterns can be combined,
16586 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16587 ;; depending on the unused output.
16589 (define_insn "sincosxf3"
16590 [(set (match_operand:XF 0 "register_operand" "=f")
16591 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16592 UNSPEC_SINCOS_COS))
16593 (set (match_operand:XF 1 "register_operand" "=u")
16594 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16595 "TARGET_USE_FANCY_MATH_387
16596 && flag_unsafe_math_optimizations"
16598 [(set_attr "type" "fpspc")
16599 (set_attr "mode" "XF")])
16602 [(set (match_operand:XF 0 "register_operand" "")
16603 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16604 UNSPEC_SINCOS_COS))
16605 (set (match_operand:XF 1 "register_operand" "")
16606 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16607 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16608 && !(reload_completed || reload_in_progress)"
16609 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16613 [(set (match_operand:XF 0 "register_operand" "")
16614 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16615 UNSPEC_SINCOS_COS))
16616 (set (match_operand:XF 1 "register_operand" "")
16617 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16618 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16619 && !(reload_completed || reload_in_progress)"
16620 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16623 (define_insn "sincos_extend<mode>xf3_i387"
16624 [(set (match_operand:XF 0 "register_operand" "=f")
16625 (unspec:XF [(float_extend:XF
16626 (match_operand:MODEF 2 "register_operand" "0"))]
16627 UNSPEC_SINCOS_COS))
16628 (set (match_operand:XF 1 "register_operand" "=u")
16629 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16630 "TARGET_USE_FANCY_MATH_387
16631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16632 || TARGET_MIX_SSE_I387)
16633 && flag_unsafe_math_optimizations"
16635 [(set_attr "type" "fpspc")
16636 (set_attr "mode" "XF")])
16639 [(set (match_operand:XF 0 "register_operand" "")
16640 (unspec:XF [(float_extend:XF
16641 (match_operand:MODEF 2 "register_operand" ""))]
16642 UNSPEC_SINCOS_COS))
16643 (set (match_operand:XF 1 "register_operand" "")
16644 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16645 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16646 && !(reload_completed || reload_in_progress)"
16647 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16651 [(set (match_operand:XF 0 "register_operand" "")
16652 (unspec:XF [(float_extend:XF
16653 (match_operand:MODEF 2 "register_operand" ""))]
16654 UNSPEC_SINCOS_COS))
16655 (set (match_operand:XF 1 "register_operand" "")
16656 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16657 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16658 && !(reload_completed || reload_in_progress)"
16659 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16662 (define_expand "sincos<mode>3"
16663 [(use (match_operand:MODEF 0 "register_operand" ""))
16664 (use (match_operand:MODEF 1 "register_operand" ""))
16665 (use (match_operand:MODEF 2 "register_operand" ""))]
16666 "TARGET_USE_FANCY_MATH_387
16667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16668 || TARGET_MIX_SSE_I387)
16669 && flag_unsafe_math_optimizations"
16671 rtx op0 = gen_reg_rtx (XFmode);
16672 rtx op1 = gen_reg_rtx (XFmode);
16674 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16675 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16676 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16680 (define_insn "fptanxf4_i387"
16681 [(set (match_operand:XF 0 "register_operand" "=f")
16682 (match_operand:XF 3 "const_double_operand" "F"))
16683 (set (match_operand:XF 1 "register_operand" "=u")
16684 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16686 "TARGET_USE_FANCY_MATH_387
16687 && flag_unsafe_math_optimizations
16688 && standard_80387_constant_p (operands[3]) == 2"
16690 [(set_attr "type" "fpspc")
16691 (set_attr "mode" "XF")])
16693 (define_insn "fptan_extend<mode>xf4_i387"
16694 [(set (match_operand:MODEF 0 "register_operand" "=f")
16695 (match_operand:MODEF 3 "const_double_operand" "F"))
16696 (set (match_operand:XF 1 "register_operand" "=u")
16697 (unspec:XF [(float_extend:XF
16698 (match_operand:MODEF 2 "register_operand" "0"))]
16700 "TARGET_USE_FANCY_MATH_387
16701 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16702 || TARGET_MIX_SSE_I387)
16703 && flag_unsafe_math_optimizations
16704 && standard_80387_constant_p (operands[3]) == 2"
16706 [(set_attr "type" "fpspc")
16707 (set_attr "mode" "XF")])
16709 (define_expand "tanxf2"
16710 [(use (match_operand:XF 0 "register_operand" ""))
16711 (use (match_operand:XF 1 "register_operand" ""))]
16712 "TARGET_USE_FANCY_MATH_387
16713 && flag_unsafe_math_optimizations"
16715 rtx one = gen_reg_rtx (XFmode);
16716 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16718 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16722 (define_expand "tan<mode>2"
16723 [(use (match_operand:MODEF 0 "register_operand" ""))
16724 (use (match_operand:MODEF 1 "register_operand" ""))]
16725 "TARGET_USE_FANCY_MATH_387
16726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16727 || TARGET_MIX_SSE_I387)
16728 && flag_unsafe_math_optimizations"
16730 rtx op0 = gen_reg_rtx (XFmode);
16732 rtx one = gen_reg_rtx (<MODE>mode);
16733 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16735 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16736 operands[1], op2));
16737 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16741 (define_insn "*fpatanxf3_i387"
16742 [(set (match_operand:XF 0 "register_operand" "=f")
16743 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16744 (match_operand:XF 2 "register_operand" "u")]
16746 (clobber (match_scratch:XF 3 "=2"))]
16747 "TARGET_USE_FANCY_MATH_387
16748 && flag_unsafe_math_optimizations"
16750 [(set_attr "type" "fpspc")
16751 (set_attr "mode" "XF")])
16753 (define_insn "fpatan_extend<mode>xf3_i387"
16754 [(set (match_operand:XF 0 "register_operand" "=f")
16755 (unspec:XF [(float_extend:XF
16756 (match_operand:MODEF 1 "register_operand" "0"))
16758 (match_operand:MODEF 2 "register_operand" "u"))]
16760 (clobber (match_scratch:XF 3 "=2"))]
16761 "TARGET_USE_FANCY_MATH_387
16762 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16763 || TARGET_MIX_SSE_I387)
16764 && flag_unsafe_math_optimizations"
16766 [(set_attr "type" "fpspc")
16767 (set_attr "mode" "XF")])
16769 (define_expand "atan2xf3"
16770 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16771 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16772 (match_operand:XF 1 "register_operand" "")]
16774 (clobber (match_scratch:XF 3 ""))])]
16775 "TARGET_USE_FANCY_MATH_387
16776 && flag_unsafe_math_optimizations"
16779 (define_expand "atan2<mode>3"
16780 [(use (match_operand:MODEF 0 "register_operand" ""))
16781 (use (match_operand:MODEF 1 "register_operand" ""))
16782 (use (match_operand:MODEF 2 "register_operand" ""))]
16783 "TARGET_USE_FANCY_MATH_387
16784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16785 || TARGET_MIX_SSE_I387)
16786 && flag_unsafe_math_optimizations"
16788 rtx op0 = gen_reg_rtx (XFmode);
16790 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16791 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16795 (define_expand "atanxf2"
16796 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16797 (unspec:XF [(match_dup 2)
16798 (match_operand:XF 1 "register_operand" "")]
16800 (clobber (match_scratch:XF 3 ""))])]
16801 "TARGET_USE_FANCY_MATH_387
16802 && flag_unsafe_math_optimizations"
16804 operands[2] = gen_reg_rtx (XFmode);
16805 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16808 (define_expand "atan<mode>2"
16809 [(use (match_operand:MODEF 0 "register_operand" ""))
16810 (use (match_operand:MODEF 1 "register_operand" ""))]
16811 "TARGET_USE_FANCY_MATH_387
16812 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16813 || TARGET_MIX_SSE_I387)
16814 && flag_unsafe_math_optimizations"
16816 rtx op0 = gen_reg_rtx (XFmode);
16818 rtx op2 = gen_reg_rtx (<MODE>mode);
16819 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16821 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16822 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16826 (define_expand "asinxf2"
16827 [(set (match_dup 2)
16828 (mult:XF (match_operand:XF 1 "register_operand" "")
16830 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16831 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16832 (parallel [(set (match_operand:XF 0 "register_operand" "")
16833 (unspec:XF [(match_dup 5) (match_dup 1)]
16835 (clobber (match_scratch:XF 6 ""))])]
16836 "TARGET_USE_FANCY_MATH_387
16837 && flag_unsafe_math_optimizations && !optimize_size"
16841 for (i = 2; i < 6; i++)
16842 operands[i] = gen_reg_rtx (XFmode);
16844 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16847 (define_expand "asin<mode>2"
16848 [(use (match_operand:MODEF 0 "register_operand" ""))
16849 (use (match_operand:MODEF 1 "general_operand" ""))]
16850 "TARGET_USE_FANCY_MATH_387
16851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16852 || TARGET_MIX_SSE_I387)
16853 && flag_unsafe_math_optimizations && !optimize_size"
16855 rtx op0 = gen_reg_rtx (XFmode);
16856 rtx op1 = gen_reg_rtx (XFmode);
16858 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16859 emit_insn (gen_asinxf2 (op0, op1));
16860 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16864 (define_expand "acosxf2"
16865 [(set (match_dup 2)
16866 (mult:XF (match_operand:XF 1 "register_operand" "")
16868 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16869 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16870 (parallel [(set (match_operand:XF 0 "register_operand" "")
16871 (unspec:XF [(match_dup 1) (match_dup 5)]
16873 (clobber (match_scratch:XF 6 ""))])]
16874 "TARGET_USE_FANCY_MATH_387
16875 && flag_unsafe_math_optimizations && !optimize_size"
16879 for (i = 2; i < 6; i++)
16880 operands[i] = gen_reg_rtx (XFmode);
16882 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16885 (define_expand "acos<mode>2"
16886 [(use (match_operand:MODEF 0 "register_operand" ""))
16887 (use (match_operand:MODEF 1 "general_operand" ""))]
16888 "TARGET_USE_FANCY_MATH_387
16889 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16890 || TARGET_MIX_SSE_I387)
16891 && flag_unsafe_math_optimizations && !optimize_size"
16893 rtx op0 = gen_reg_rtx (XFmode);
16894 rtx op1 = gen_reg_rtx (XFmode);
16896 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16897 emit_insn (gen_acosxf2 (op0, op1));
16898 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16902 (define_insn "fyl2xxf3_i387"
16903 [(set (match_operand:XF 0 "register_operand" "=f")
16904 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16905 (match_operand:XF 2 "register_operand" "u")]
16907 (clobber (match_scratch:XF 3 "=2"))]
16908 "TARGET_USE_FANCY_MATH_387
16909 && flag_unsafe_math_optimizations"
16911 [(set_attr "type" "fpspc")
16912 (set_attr "mode" "XF")])
16914 (define_insn "fyl2x_extend<mode>xf3_i387"
16915 [(set (match_operand:XF 0 "register_operand" "=f")
16916 (unspec:XF [(float_extend:XF
16917 (match_operand:MODEF 1 "register_operand" "0"))
16918 (match_operand:XF 2 "register_operand" "u")]
16920 (clobber (match_scratch:XF 3 "=2"))]
16921 "TARGET_USE_FANCY_MATH_387
16922 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16923 || TARGET_MIX_SSE_I387)
16924 && flag_unsafe_math_optimizations"
16926 [(set_attr "type" "fpspc")
16927 (set_attr "mode" "XF")])
16929 (define_expand "logxf2"
16930 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16931 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16932 (match_dup 2)] UNSPEC_FYL2X))
16933 (clobber (match_scratch:XF 3 ""))])]
16934 "TARGET_USE_FANCY_MATH_387
16935 && flag_unsafe_math_optimizations"
16937 operands[2] = gen_reg_rtx (XFmode);
16938 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16941 (define_expand "log<mode>2"
16942 [(use (match_operand:MODEF 0 "register_operand" ""))
16943 (use (match_operand:MODEF 1 "register_operand" ""))]
16944 "TARGET_USE_FANCY_MATH_387
16945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16946 || TARGET_MIX_SSE_I387)
16947 && flag_unsafe_math_optimizations"
16949 rtx op0 = gen_reg_rtx (XFmode);
16951 rtx op2 = gen_reg_rtx (XFmode);
16952 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16954 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16955 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16959 (define_expand "log10xf2"
16960 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16961 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16962 (match_dup 2)] UNSPEC_FYL2X))
16963 (clobber (match_scratch:XF 3 ""))])]
16964 "TARGET_USE_FANCY_MATH_387
16965 && flag_unsafe_math_optimizations"
16967 operands[2] = gen_reg_rtx (XFmode);
16968 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16971 (define_expand "log10<mode>2"
16972 [(use (match_operand:MODEF 0 "register_operand" ""))
16973 (use (match_operand:MODEF 1 "register_operand" ""))]
16974 "TARGET_USE_FANCY_MATH_387
16975 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16976 || TARGET_MIX_SSE_I387)
16977 && flag_unsafe_math_optimizations"
16979 rtx op0 = gen_reg_rtx (XFmode);
16981 rtx op2 = gen_reg_rtx (XFmode);
16982 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16984 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16985 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16989 (define_expand "log2xf2"
16990 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16991 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16992 (match_dup 2)] UNSPEC_FYL2X))
16993 (clobber (match_scratch:XF 3 ""))])]
16994 "TARGET_USE_FANCY_MATH_387
16995 && flag_unsafe_math_optimizations"
16997 operands[2] = gen_reg_rtx (XFmode);
16998 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17001 (define_expand "log2<mode>2"
17002 [(use (match_operand:MODEF 0 "register_operand" ""))
17003 (use (match_operand:MODEF 1 "register_operand" ""))]
17004 "TARGET_USE_FANCY_MATH_387
17005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17006 || TARGET_MIX_SSE_I387)
17007 && flag_unsafe_math_optimizations"
17009 rtx op0 = gen_reg_rtx (XFmode);
17011 rtx op2 = gen_reg_rtx (XFmode);
17012 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17014 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17015 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17019 (define_insn "fyl2xp1xf3_i387"
17020 [(set (match_operand:XF 0 "register_operand" "=f")
17021 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17022 (match_operand:XF 2 "register_operand" "u")]
17024 (clobber (match_scratch:XF 3 "=2"))]
17025 "TARGET_USE_FANCY_MATH_387
17026 && flag_unsafe_math_optimizations"
17028 [(set_attr "type" "fpspc")
17029 (set_attr "mode" "XF")])
17031 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17032 [(set (match_operand:XF 0 "register_operand" "=f")
17033 (unspec:XF [(float_extend:XF
17034 (match_operand:MODEF 1 "register_operand" "0"))
17035 (match_operand:XF 2 "register_operand" "u")]
17037 (clobber (match_scratch:XF 3 "=2"))]
17038 "TARGET_USE_FANCY_MATH_387
17039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17040 || TARGET_MIX_SSE_I387)
17041 && flag_unsafe_math_optimizations"
17043 [(set_attr "type" "fpspc")
17044 (set_attr "mode" "XF")])
17046 (define_expand "log1pxf2"
17047 [(use (match_operand:XF 0 "register_operand" ""))
17048 (use (match_operand:XF 1 "register_operand" ""))]
17049 "TARGET_USE_FANCY_MATH_387
17050 && flag_unsafe_math_optimizations && !optimize_size"
17052 ix86_emit_i387_log1p (operands[0], operands[1]);
17056 (define_expand "log1p<mode>2"
17057 [(use (match_operand:MODEF 0 "register_operand" ""))
17058 (use (match_operand:MODEF 1 "register_operand" ""))]
17059 "TARGET_USE_FANCY_MATH_387
17060 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17061 || TARGET_MIX_SSE_I387)
17062 && flag_unsafe_math_optimizations && !optimize_size"
17064 rtx op0 = gen_reg_rtx (XFmode);
17066 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17068 ix86_emit_i387_log1p (op0, operands[1]);
17069 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17073 (define_insn "fxtractxf3_i387"
17074 [(set (match_operand:XF 0 "register_operand" "=f")
17075 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17076 UNSPEC_XTRACT_FRACT))
17077 (set (match_operand:XF 1 "register_operand" "=u")
17078 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17079 "TARGET_USE_FANCY_MATH_387
17080 && flag_unsafe_math_optimizations"
17082 [(set_attr "type" "fpspc")
17083 (set_attr "mode" "XF")])
17085 (define_insn "fxtract_extend<mode>xf3_i387"
17086 [(set (match_operand:XF 0 "register_operand" "=f")
17087 (unspec:XF [(float_extend:XF
17088 (match_operand:MODEF 2 "register_operand" "0"))]
17089 UNSPEC_XTRACT_FRACT))
17090 (set (match_operand:XF 1 "register_operand" "=u")
17091 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17092 "TARGET_USE_FANCY_MATH_387
17093 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17094 || TARGET_MIX_SSE_I387)
17095 && flag_unsafe_math_optimizations"
17097 [(set_attr "type" "fpspc")
17098 (set_attr "mode" "XF")])
17100 (define_expand "logbxf2"
17101 [(parallel [(set (match_dup 2)
17102 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17103 UNSPEC_XTRACT_FRACT))
17104 (set (match_operand:XF 0 "register_operand" "")
17105 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17106 "TARGET_USE_FANCY_MATH_387
17107 && flag_unsafe_math_optimizations"
17109 operands[2] = gen_reg_rtx (XFmode);
17112 (define_expand "logb<mode>2"
17113 [(use (match_operand:MODEF 0 "register_operand" ""))
17114 (use (match_operand:MODEF 1 "register_operand" ""))]
17115 "TARGET_USE_FANCY_MATH_387
17116 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17117 || TARGET_MIX_SSE_I387)
17118 && flag_unsafe_math_optimizations"
17120 rtx op0 = gen_reg_rtx (XFmode);
17121 rtx op1 = gen_reg_rtx (XFmode);
17123 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17124 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17128 (define_expand "ilogbxf2"
17129 [(use (match_operand:SI 0 "register_operand" ""))
17130 (use (match_operand:XF 1 "register_operand" ""))]
17131 "TARGET_USE_FANCY_MATH_387
17132 && flag_unsafe_math_optimizations && !optimize_size"
17134 rtx op0 = gen_reg_rtx (XFmode);
17135 rtx op1 = gen_reg_rtx (XFmode);
17137 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17138 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17142 (define_expand "ilogb<mode>2"
17143 [(use (match_operand:SI 0 "register_operand" ""))
17144 (use (match_operand:MODEF 1 "register_operand" ""))]
17145 "TARGET_USE_FANCY_MATH_387
17146 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17147 || TARGET_MIX_SSE_I387)
17148 && flag_unsafe_math_optimizations && !optimize_size"
17150 rtx op0 = gen_reg_rtx (XFmode);
17151 rtx op1 = gen_reg_rtx (XFmode);
17153 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17154 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17158 (define_insn "*f2xm1xf2_i387"
17159 [(set (match_operand:XF 0 "register_operand" "=f")
17160 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17162 "TARGET_USE_FANCY_MATH_387
17163 && flag_unsafe_math_optimizations"
17165 [(set_attr "type" "fpspc")
17166 (set_attr "mode" "XF")])
17168 (define_insn "*fscalexf4_i387"
17169 [(set (match_operand:XF 0 "register_operand" "=f")
17170 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17171 (match_operand:XF 3 "register_operand" "1")]
17172 UNSPEC_FSCALE_FRACT))
17173 (set (match_operand:XF 1 "register_operand" "=u")
17174 (unspec:XF [(match_dup 2) (match_dup 3)]
17175 UNSPEC_FSCALE_EXP))]
17176 "TARGET_USE_FANCY_MATH_387
17177 && flag_unsafe_math_optimizations"
17179 [(set_attr "type" "fpspc")
17180 (set_attr "mode" "XF")])
17182 (define_expand "expNcorexf3"
17183 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17184 (match_operand:XF 2 "register_operand" "")))
17185 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17186 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17187 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17188 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17189 (parallel [(set (match_operand:XF 0 "register_operand" "")
17190 (unspec:XF [(match_dup 8) (match_dup 4)]
17191 UNSPEC_FSCALE_FRACT))
17193 (unspec:XF [(match_dup 8) (match_dup 4)]
17194 UNSPEC_FSCALE_EXP))])]
17195 "TARGET_USE_FANCY_MATH_387
17196 && flag_unsafe_math_optimizations && !optimize_size"
17200 for (i = 3; i < 10; i++)
17201 operands[i] = gen_reg_rtx (XFmode);
17203 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17206 (define_expand "expxf2"
17207 [(use (match_operand:XF 0 "register_operand" ""))
17208 (use (match_operand:XF 1 "register_operand" ""))]
17209 "TARGET_USE_FANCY_MATH_387
17210 && flag_unsafe_math_optimizations && !optimize_size"
17212 rtx op2 = gen_reg_rtx (XFmode);
17213 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17215 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17219 (define_expand "exp<mode>2"
17220 [(use (match_operand:MODEF 0 "register_operand" ""))
17221 (use (match_operand:MODEF 1 "general_operand" ""))]
17222 "TARGET_USE_FANCY_MATH_387
17223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17224 || TARGET_MIX_SSE_I387)
17225 && flag_unsafe_math_optimizations && !optimize_size"
17227 rtx op0 = gen_reg_rtx (XFmode);
17228 rtx op1 = gen_reg_rtx (XFmode);
17230 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17231 emit_insn (gen_expxf2 (op0, op1));
17232 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17236 (define_expand "exp10xf2"
17237 [(use (match_operand:XF 0 "register_operand" ""))
17238 (use (match_operand:XF 1 "register_operand" ""))]
17239 "TARGET_USE_FANCY_MATH_387
17240 && flag_unsafe_math_optimizations && !optimize_size"
17242 rtx op2 = gen_reg_rtx (XFmode);
17243 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17245 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17249 (define_expand "exp10<mode>2"
17250 [(use (match_operand:MODEF 0 "register_operand" ""))
17251 (use (match_operand:MODEF 1 "general_operand" ""))]
17252 "TARGET_USE_FANCY_MATH_387
17253 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17254 || TARGET_MIX_SSE_I387)
17255 && flag_unsafe_math_optimizations && !optimize_size"
17257 rtx op0 = gen_reg_rtx (XFmode);
17258 rtx op1 = gen_reg_rtx (XFmode);
17260 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17261 emit_insn (gen_exp10xf2 (op0, op1));
17262 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17266 (define_expand "exp2xf2"
17267 [(use (match_operand:XF 0 "register_operand" ""))
17268 (use (match_operand:XF 1 "register_operand" ""))]
17269 "TARGET_USE_FANCY_MATH_387
17270 && flag_unsafe_math_optimizations && !optimize_size"
17272 rtx op2 = gen_reg_rtx (XFmode);
17273 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17275 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17279 (define_expand "exp2<mode>2"
17280 [(use (match_operand:MODEF 0 "register_operand" ""))
17281 (use (match_operand:MODEF 1 "general_operand" ""))]
17282 "TARGET_USE_FANCY_MATH_387
17283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17284 || TARGET_MIX_SSE_I387)
17285 && flag_unsafe_math_optimizations && !optimize_size"
17287 rtx op0 = gen_reg_rtx (XFmode);
17288 rtx op1 = gen_reg_rtx (XFmode);
17290 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17291 emit_insn (gen_exp2xf2 (op0, op1));
17292 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17296 (define_expand "expm1xf2"
17297 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17299 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17300 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17301 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17302 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17303 (parallel [(set (match_dup 7)
17304 (unspec:XF [(match_dup 6) (match_dup 4)]
17305 UNSPEC_FSCALE_FRACT))
17307 (unspec:XF [(match_dup 6) (match_dup 4)]
17308 UNSPEC_FSCALE_EXP))])
17309 (parallel [(set (match_dup 10)
17310 (unspec:XF [(match_dup 9) (match_dup 8)]
17311 UNSPEC_FSCALE_FRACT))
17312 (set (match_dup 11)
17313 (unspec:XF [(match_dup 9) (match_dup 8)]
17314 UNSPEC_FSCALE_EXP))])
17315 (set (match_dup 12) (minus:XF (match_dup 10)
17316 (float_extend:XF (match_dup 13))))
17317 (set (match_operand:XF 0 "register_operand" "")
17318 (plus:XF (match_dup 12) (match_dup 7)))]
17319 "TARGET_USE_FANCY_MATH_387
17320 && flag_unsafe_math_optimizations && !optimize_size"
17324 for (i = 2; i < 13; i++)
17325 operands[i] = gen_reg_rtx (XFmode);
17328 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17330 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17333 (define_expand "expm1<mode>2"
17334 [(use (match_operand:MODEF 0 "register_operand" ""))
17335 (use (match_operand:MODEF 1 "general_operand" ""))]
17336 "TARGET_USE_FANCY_MATH_387
17337 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17338 || TARGET_MIX_SSE_I387)
17339 && flag_unsafe_math_optimizations && !optimize_size"
17341 rtx op0 = gen_reg_rtx (XFmode);
17342 rtx op1 = gen_reg_rtx (XFmode);
17344 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17345 emit_insn (gen_expm1xf2 (op0, op1));
17346 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17350 (define_expand "ldexpxf3"
17351 [(set (match_dup 3)
17352 (float:XF (match_operand:SI 2 "register_operand" "")))
17353 (parallel [(set (match_operand:XF 0 " register_operand" "")
17354 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17356 UNSPEC_FSCALE_FRACT))
17358 (unspec:XF [(match_dup 1) (match_dup 3)]
17359 UNSPEC_FSCALE_EXP))])]
17360 "TARGET_USE_FANCY_MATH_387
17361 && flag_unsafe_math_optimizations && !optimize_size"
17363 operands[3] = gen_reg_rtx (XFmode);
17364 operands[4] = gen_reg_rtx (XFmode);
17367 (define_expand "ldexp<mode>3"
17368 [(use (match_operand:MODEF 0 "register_operand" ""))
17369 (use (match_operand:MODEF 1 "general_operand" ""))
17370 (use (match_operand:SI 2 "register_operand" ""))]
17371 "TARGET_USE_FANCY_MATH_387
17372 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17373 || TARGET_MIX_SSE_I387)
17374 && flag_unsafe_math_optimizations && !optimize_size"
17376 rtx op0 = gen_reg_rtx (XFmode);
17377 rtx op1 = gen_reg_rtx (XFmode);
17379 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17380 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17381 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17385 (define_expand "scalbxf3"
17386 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17387 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17388 (match_operand:XF 2 "register_operand" "")]
17389 UNSPEC_FSCALE_FRACT))
17391 (unspec:XF [(match_dup 1) (match_dup 2)]
17392 UNSPEC_FSCALE_EXP))])]
17393 "TARGET_USE_FANCY_MATH_387
17394 && flag_unsafe_math_optimizations && !optimize_size"
17396 operands[3] = gen_reg_rtx (XFmode);
17399 (define_expand "scalb<mode>3"
17400 [(use (match_operand:MODEF 0 "register_operand" ""))
17401 (use (match_operand:MODEF 1 "general_operand" ""))
17402 (use (match_operand:MODEF 2 "register_operand" ""))]
17403 "TARGET_USE_FANCY_MATH_387
17404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17405 || TARGET_MIX_SSE_I387)
17406 && flag_unsafe_math_optimizations && !optimize_size"
17408 rtx op0 = gen_reg_rtx (XFmode);
17409 rtx op1 = gen_reg_rtx (XFmode);
17410 rtx op2 = gen_reg_rtx (XFmode);
17412 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17413 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17414 emit_insn (gen_scalbxf3 (op0, op1, op2));
17415 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17420 (define_insn "sse4_1_round<mode>2"
17421 [(set (match_operand:MODEF 0 "register_operand" "=x")
17422 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17423 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17426 "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17427 [(set_attr "type" "ssecvt")
17428 (set_attr "prefix_extra" "1")
17429 (set_attr "mode" "<MODE>")])
17431 (define_insn "rintxf2"
17432 [(set (match_operand:XF 0 "register_operand" "=f")
17433 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17435 "TARGET_USE_FANCY_MATH_387
17436 && flag_unsafe_math_optimizations"
17438 [(set_attr "type" "fpspc")
17439 (set_attr "mode" "XF")])
17441 (define_expand "rint<mode>2"
17442 [(use (match_operand:MODEF 0 "register_operand" ""))
17443 (use (match_operand:MODEF 1 "register_operand" ""))]
17444 "(TARGET_USE_FANCY_MATH_387
17445 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17446 || TARGET_MIX_SSE_I387)
17447 && flag_unsafe_math_optimizations)
17448 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17449 && !flag_trapping_math
17450 && (TARGET_ROUND || !optimize_size))"
17452 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17453 && !flag_trapping_math
17454 && (TARGET_ROUND || !optimize_size))
17457 emit_insn (gen_sse4_1_round<mode>2
17458 (operands[0], operands[1], GEN_INT (0x04)));
17460 ix86_expand_rint (operand0, operand1);
17464 rtx op0 = gen_reg_rtx (XFmode);
17465 rtx op1 = gen_reg_rtx (XFmode);
17467 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17468 emit_insn (gen_rintxf2 (op0, op1));
17470 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17475 (define_expand "round<mode>2"
17476 [(match_operand:MODEF 0 "register_operand" "")
17477 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17478 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17479 && !flag_trapping_math && !flag_rounding_math
17482 if (TARGET_64BIT || (<MODE>mode != DFmode))
17483 ix86_expand_round (operand0, operand1);
17485 ix86_expand_rounddf_32 (operand0, operand1);
17489 (define_insn_and_split "*fistdi2_1"
17490 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17491 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17493 "TARGET_USE_FANCY_MATH_387
17494 && !(reload_completed || reload_in_progress)"
17499 if (memory_operand (operands[0], VOIDmode))
17500 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17503 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17504 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17509 [(set_attr "type" "fpspc")
17510 (set_attr "mode" "DI")])
17512 (define_insn "fistdi2"
17513 [(set (match_operand:DI 0 "memory_operand" "=m")
17514 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17516 (clobber (match_scratch:XF 2 "=&1f"))]
17517 "TARGET_USE_FANCY_MATH_387"
17518 "* return output_fix_trunc (insn, operands, 0);"
17519 [(set_attr "type" "fpspc")
17520 (set_attr "mode" "DI")])
17522 (define_insn "fistdi2_with_temp"
17523 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17524 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17526 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17527 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17528 "TARGET_USE_FANCY_MATH_387"
17530 [(set_attr "type" "fpspc")
17531 (set_attr "mode" "DI")])
17534 [(set (match_operand:DI 0 "register_operand" "")
17535 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17537 (clobber (match_operand:DI 2 "memory_operand" ""))
17538 (clobber (match_scratch 3 ""))]
17540 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17541 (clobber (match_dup 3))])
17542 (set (match_dup 0) (match_dup 2))]
17546 [(set (match_operand:DI 0 "memory_operand" "")
17547 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17549 (clobber (match_operand:DI 2 "memory_operand" ""))
17550 (clobber (match_scratch 3 ""))]
17552 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17553 (clobber (match_dup 3))])]
17556 (define_insn_and_split "*fist<mode>2_1"
17557 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17558 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17560 "TARGET_USE_FANCY_MATH_387
17561 && !(reload_completed || reload_in_progress)"
17566 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17567 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17571 [(set_attr "type" "fpspc")
17572 (set_attr "mode" "<MODE>")])
17574 (define_insn "fist<mode>2"
17575 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17576 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17578 "TARGET_USE_FANCY_MATH_387"
17579 "* return output_fix_trunc (insn, operands, 0);"
17580 [(set_attr "type" "fpspc")
17581 (set_attr "mode" "<MODE>")])
17583 (define_insn "fist<mode>2_with_temp"
17584 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17585 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17587 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17588 "TARGET_USE_FANCY_MATH_387"
17590 [(set_attr "type" "fpspc")
17591 (set_attr "mode" "<MODE>")])
17594 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17595 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17597 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17599 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17600 (set (match_dup 0) (match_dup 2))]
17604 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17605 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17607 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17609 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17612 (define_expand "lrintxf<mode>2"
17613 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17614 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17616 "TARGET_USE_FANCY_MATH_387"
17619 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17620 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17621 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17622 UNSPEC_FIX_NOTRUNC))]
17623 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17624 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17627 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17628 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17629 (match_operand:MODEF 1 "register_operand" "")]
17630 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17631 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17632 && !flag_trapping_math && !flag_rounding_math
17635 ix86_expand_lround (operand0, operand1);
17639 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17640 (define_insn_and_split "frndintxf2_floor"
17641 [(set (match_operand:XF 0 "register_operand" "")
17642 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17643 UNSPEC_FRNDINT_FLOOR))
17644 (clobber (reg:CC FLAGS_REG))]
17645 "TARGET_USE_FANCY_MATH_387
17646 && flag_unsafe_math_optimizations
17647 && !(reload_completed || reload_in_progress)"
17652 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17654 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17655 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17657 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17658 operands[2], operands[3]));
17661 [(set_attr "type" "frndint")
17662 (set_attr "i387_cw" "floor")
17663 (set_attr "mode" "XF")])
17665 (define_insn "frndintxf2_floor_i387"
17666 [(set (match_operand:XF 0 "register_operand" "=f")
17667 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17668 UNSPEC_FRNDINT_FLOOR))
17669 (use (match_operand:HI 2 "memory_operand" "m"))
17670 (use (match_operand:HI 3 "memory_operand" "m"))]
17671 "TARGET_USE_FANCY_MATH_387
17672 && flag_unsafe_math_optimizations"
17673 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17674 [(set_attr "type" "frndint")
17675 (set_attr "i387_cw" "floor")
17676 (set_attr "mode" "XF")])
17678 (define_expand "floorxf2"
17679 [(use (match_operand:XF 0 "register_operand" ""))
17680 (use (match_operand:XF 1 "register_operand" ""))]
17681 "TARGET_USE_FANCY_MATH_387
17682 && flag_unsafe_math_optimizations && !optimize_size"
17684 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17688 (define_expand "floor<mode>2"
17689 [(use (match_operand:MODEF 0 "register_operand" ""))
17690 (use (match_operand:MODEF 1 "register_operand" ""))]
17691 "(TARGET_USE_FANCY_MATH_387
17692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17693 || TARGET_MIX_SSE_I387)
17694 && flag_unsafe_math_optimizations && !optimize_size)
17695 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17696 && !flag_trapping_math
17697 && (TARGET_ROUND || !optimize_size))"
17699 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17700 && !flag_trapping_math
17701 && (TARGET_ROUND || !optimize_size))
17704 emit_insn (gen_sse4_1_round<mode>2
17705 (operands[0], operands[1], GEN_INT (0x01)));
17706 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17707 ix86_expand_floorceil (operand0, operand1, true);
17709 ix86_expand_floorceildf_32 (operand0, operand1, true);
17713 rtx op0 = gen_reg_rtx (XFmode);
17714 rtx op1 = gen_reg_rtx (XFmode);
17716 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17717 emit_insn (gen_frndintxf2_floor (op0, op1));
17719 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17724 (define_insn_and_split "*fist<mode>2_floor_1"
17725 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17726 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17727 UNSPEC_FIST_FLOOR))
17728 (clobber (reg:CC FLAGS_REG))]
17729 "TARGET_USE_FANCY_MATH_387
17730 && flag_unsafe_math_optimizations
17731 && !(reload_completed || reload_in_progress)"
17736 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17738 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17739 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17740 if (memory_operand (operands[0], VOIDmode))
17741 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17742 operands[2], operands[3]));
17745 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17746 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17747 operands[2], operands[3],
17752 [(set_attr "type" "fistp")
17753 (set_attr "i387_cw" "floor")
17754 (set_attr "mode" "<MODE>")])
17756 (define_insn "fistdi2_floor"
17757 [(set (match_operand:DI 0 "memory_operand" "=m")
17758 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17759 UNSPEC_FIST_FLOOR))
17760 (use (match_operand:HI 2 "memory_operand" "m"))
17761 (use (match_operand:HI 3 "memory_operand" "m"))
17762 (clobber (match_scratch:XF 4 "=&1f"))]
17763 "TARGET_USE_FANCY_MATH_387
17764 && flag_unsafe_math_optimizations"
17765 "* return output_fix_trunc (insn, operands, 0);"
17766 [(set_attr "type" "fistp")
17767 (set_attr "i387_cw" "floor")
17768 (set_attr "mode" "DI")])
17770 (define_insn "fistdi2_floor_with_temp"
17771 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17772 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17773 UNSPEC_FIST_FLOOR))
17774 (use (match_operand:HI 2 "memory_operand" "m,m"))
17775 (use (match_operand:HI 3 "memory_operand" "m,m"))
17776 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17777 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17778 "TARGET_USE_FANCY_MATH_387
17779 && flag_unsafe_math_optimizations"
17781 [(set_attr "type" "fistp")
17782 (set_attr "i387_cw" "floor")
17783 (set_attr "mode" "DI")])
17786 [(set (match_operand:DI 0 "register_operand" "")
17787 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17788 UNSPEC_FIST_FLOOR))
17789 (use (match_operand:HI 2 "memory_operand" ""))
17790 (use (match_operand:HI 3 "memory_operand" ""))
17791 (clobber (match_operand:DI 4 "memory_operand" ""))
17792 (clobber (match_scratch 5 ""))]
17794 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17795 (use (match_dup 2))
17796 (use (match_dup 3))
17797 (clobber (match_dup 5))])
17798 (set (match_dup 0) (match_dup 4))]
17802 [(set (match_operand:DI 0 "memory_operand" "")
17803 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17804 UNSPEC_FIST_FLOOR))
17805 (use (match_operand:HI 2 "memory_operand" ""))
17806 (use (match_operand:HI 3 "memory_operand" ""))
17807 (clobber (match_operand:DI 4 "memory_operand" ""))
17808 (clobber (match_scratch 5 ""))]
17810 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17811 (use (match_dup 2))
17812 (use (match_dup 3))
17813 (clobber (match_dup 5))])]
17816 (define_insn "fist<mode>2_floor"
17817 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17818 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17819 UNSPEC_FIST_FLOOR))
17820 (use (match_operand:HI 2 "memory_operand" "m"))
17821 (use (match_operand:HI 3 "memory_operand" "m"))]
17822 "TARGET_USE_FANCY_MATH_387
17823 && flag_unsafe_math_optimizations"
17824 "* return output_fix_trunc (insn, operands, 0);"
17825 [(set_attr "type" "fistp")
17826 (set_attr "i387_cw" "floor")
17827 (set_attr "mode" "<MODE>")])
17829 (define_insn "fist<mode>2_floor_with_temp"
17830 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17831 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17832 UNSPEC_FIST_FLOOR))
17833 (use (match_operand:HI 2 "memory_operand" "m,m"))
17834 (use (match_operand:HI 3 "memory_operand" "m,m"))
17835 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17836 "TARGET_USE_FANCY_MATH_387
17837 && flag_unsafe_math_optimizations"
17839 [(set_attr "type" "fistp")
17840 (set_attr "i387_cw" "floor")
17841 (set_attr "mode" "<MODE>")])
17844 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17845 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17846 UNSPEC_FIST_FLOOR))
17847 (use (match_operand:HI 2 "memory_operand" ""))
17848 (use (match_operand:HI 3 "memory_operand" ""))
17849 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17851 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17852 UNSPEC_FIST_FLOOR))
17853 (use (match_dup 2))
17854 (use (match_dup 3))])
17855 (set (match_dup 0) (match_dup 4))]
17859 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17860 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17861 UNSPEC_FIST_FLOOR))
17862 (use (match_operand:HI 2 "memory_operand" ""))
17863 (use (match_operand:HI 3 "memory_operand" ""))
17864 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17866 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17867 UNSPEC_FIST_FLOOR))
17868 (use (match_dup 2))
17869 (use (match_dup 3))])]
17872 (define_expand "lfloorxf<mode>2"
17873 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17874 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17875 UNSPEC_FIST_FLOOR))
17876 (clobber (reg:CC FLAGS_REG))])]
17877 "TARGET_USE_FANCY_MATH_387
17878 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17879 && flag_unsafe_math_optimizations"
17882 (define_expand "lfloor<mode>di2"
17883 [(match_operand:DI 0 "nonimmediate_operand" "")
17884 (match_operand:MODEF 1 "register_operand" "")]
17885 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17886 && !flag_trapping_math
17889 ix86_expand_lfloorceil (operand0, operand1, true);
17893 (define_expand "lfloor<mode>si2"
17894 [(match_operand:SI 0 "nonimmediate_operand" "")
17895 (match_operand:MODEF 1 "register_operand" "")]
17896 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17897 && !flag_trapping_math
17898 && (!optimize_size || !TARGET_64BIT)"
17900 ix86_expand_lfloorceil (operand0, operand1, true);
17904 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17905 (define_insn_and_split "frndintxf2_ceil"
17906 [(set (match_operand:XF 0 "register_operand" "")
17907 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17908 UNSPEC_FRNDINT_CEIL))
17909 (clobber (reg:CC FLAGS_REG))]
17910 "TARGET_USE_FANCY_MATH_387
17911 && flag_unsafe_math_optimizations
17912 && !(reload_completed || reload_in_progress)"
17917 ix86_optimize_mode_switching[I387_CEIL] = 1;
17919 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17920 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17922 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17923 operands[2], operands[3]));
17926 [(set_attr "type" "frndint")
17927 (set_attr "i387_cw" "ceil")
17928 (set_attr "mode" "XF")])
17930 (define_insn "frndintxf2_ceil_i387"
17931 [(set (match_operand:XF 0 "register_operand" "=f")
17932 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17933 UNSPEC_FRNDINT_CEIL))
17934 (use (match_operand:HI 2 "memory_operand" "m"))
17935 (use (match_operand:HI 3 "memory_operand" "m"))]
17936 "TARGET_USE_FANCY_MATH_387
17937 && flag_unsafe_math_optimizations"
17938 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17939 [(set_attr "type" "frndint")
17940 (set_attr "i387_cw" "ceil")
17941 (set_attr "mode" "XF")])
17943 (define_expand "ceilxf2"
17944 [(use (match_operand:XF 0 "register_operand" ""))
17945 (use (match_operand:XF 1 "register_operand" ""))]
17946 "TARGET_USE_FANCY_MATH_387
17947 && flag_unsafe_math_optimizations && !optimize_size"
17949 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17953 (define_expand "ceil<mode>2"
17954 [(use (match_operand:MODEF 0 "register_operand" ""))
17955 (use (match_operand:MODEF 1 "register_operand" ""))]
17956 "(TARGET_USE_FANCY_MATH_387
17957 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17958 || TARGET_MIX_SSE_I387)
17959 && flag_unsafe_math_optimizations && !optimize_size)
17960 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17961 && !flag_trapping_math
17962 && (TARGET_ROUND || !optimize_size))"
17964 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17965 && !flag_trapping_math
17966 && (TARGET_ROUND || !optimize_size))
17969 emit_insn (gen_sse4_1_round<mode>2
17970 (operands[0], operands[1], GEN_INT (0x02)));
17971 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17972 ix86_expand_floorceil (operand0, operand1, false);
17974 ix86_expand_floorceildf_32 (operand0, operand1, false);
17978 rtx op0 = gen_reg_rtx (XFmode);
17979 rtx op1 = gen_reg_rtx (XFmode);
17981 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17982 emit_insn (gen_frndintxf2_ceil (op0, op1));
17984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17989 (define_insn_and_split "*fist<mode>2_ceil_1"
17990 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17991 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17993 (clobber (reg:CC FLAGS_REG))]
17994 "TARGET_USE_FANCY_MATH_387
17995 && flag_unsafe_math_optimizations
17996 && !(reload_completed || reload_in_progress)"
18001 ix86_optimize_mode_switching[I387_CEIL] = 1;
18003 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18004 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18005 if (memory_operand (operands[0], VOIDmode))
18006 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18007 operands[2], operands[3]));
18010 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18011 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18012 operands[2], operands[3],
18017 [(set_attr "type" "fistp")
18018 (set_attr "i387_cw" "ceil")
18019 (set_attr "mode" "<MODE>")])
18021 (define_insn "fistdi2_ceil"
18022 [(set (match_operand:DI 0 "memory_operand" "=m")
18023 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18025 (use (match_operand:HI 2 "memory_operand" "m"))
18026 (use (match_operand:HI 3 "memory_operand" "m"))
18027 (clobber (match_scratch:XF 4 "=&1f"))]
18028 "TARGET_USE_FANCY_MATH_387
18029 && flag_unsafe_math_optimizations"
18030 "* return output_fix_trunc (insn, operands, 0);"
18031 [(set_attr "type" "fistp")
18032 (set_attr "i387_cw" "ceil")
18033 (set_attr "mode" "DI")])
18035 (define_insn "fistdi2_ceil_with_temp"
18036 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18037 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18039 (use (match_operand:HI 2 "memory_operand" "m,m"))
18040 (use (match_operand:HI 3 "memory_operand" "m,m"))
18041 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18042 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18043 "TARGET_USE_FANCY_MATH_387
18044 && flag_unsafe_math_optimizations"
18046 [(set_attr "type" "fistp")
18047 (set_attr "i387_cw" "ceil")
18048 (set_attr "mode" "DI")])
18051 [(set (match_operand:DI 0 "register_operand" "")
18052 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18054 (use (match_operand:HI 2 "memory_operand" ""))
18055 (use (match_operand:HI 3 "memory_operand" ""))
18056 (clobber (match_operand:DI 4 "memory_operand" ""))
18057 (clobber (match_scratch 5 ""))]
18059 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18060 (use (match_dup 2))
18061 (use (match_dup 3))
18062 (clobber (match_dup 5))])
18063 (set (match_dup 0) (match_dup 4))]
18067 [(set (match_operand:DI 0 "memory_operand" "")
18068 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18070 (use (match_operand:HI 2 "memory_operand" ""))
18071 (use (match_operand:HI 3 "memory_operand" ""))
18072 (clobber (match_operand:DI 4 "memory_operand" ""))
18073 (clobber (match_scratch 5 ""))]
18075 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18076 (use (match_dup 2))
18077 (use (match_dup 3))
18078 (clobber (match_dup 5))])]
18081 (define_insn "fist<mode>2_ceil"
18082 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18083 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18085 (use (match_operand:HI 2 "memory_operand" "m"))
18086 (use (match_operand:HI 3 "memory_operand" "m"))]
18087 "TARGET_USE_FANCY_MATH_387
18088 && flag_unsafe_math_optimizations"
18089 "* return output_fix_trunc (insn, operands, 0);"
18090 [(set_attr "type" "fistp")
18091 (set_attr "i387_cw" "ceil")
18092 (set_attr "mode" "<MODE>")])
18094 (define_insn "fist<mode>2_ceil_with_temp"
18095 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18096 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18098 (use (match_operand:HI 2 "memory_operand" "m,m"))
18099 (use (match_operand:HI 3 "memory_operand" "m,m"))
18100 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18101 "TARGET_USE_FANCY_MATH_387
18102 && flag_unsafe_math_optimizations"
18104 [(set_attr "type" "fistp")
18105 (set_attr "i387_cw" "ceil")
18106 (set_attr "mode" "<MODE>")])
18109 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18110 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18112 (use (match_operand:HI 2 "memory_operand" ""))
18113 (use (match_operand:HI 3 "memory_operand" ""))
18114 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18116 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18118 (use (match_dup 2))
18119 (use (match_dup 3))])
18120 (set (match_dup 0) (match_dup 4))]
18124 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18125 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18127 (use (match_operand:HI 2 "memory_operand" ""))
18128 (use (match_operand:HI 3 "memory_operand" ""))
18129 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18131 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18133 (use (match_dup 2))
18134 (use (match_dup 3))])]
18137 (define_expand "lceilxf<mode>2"
18138 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18139 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18141 (clobber (reg:CC FLAGS_REG))])]
18142 "TARGET_USE_FANCY_MATH_387
18143 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18144 && flag_unsafe_math_optimizations"
18147 (define_expand "lceil<mode>di2"
18148 [(match_operand:DI 0 "nonimmediate_operand" "")
18149 (match_operand:MODEF 1 "register_operand" "")]
18150 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18151 && !flag_trapping_math"
18153 ix86_expand_lfloorceil (operand0, operand1, false);
18157 (define_expand "lceil<mode>si2"
18158 [(match_operand:SI 0 "nonimmediate_operand" "")
18159 (match_operand:MODEF 1 "register_operand" "")]
18160 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18161 && !flag_trapping_math"
18163 ix86_expand_lfloorceil (operand0, operand1, false);
18167 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18168 (define_insn_and_split "frndintxf2_trunc"
18169 [(set (match_operand:XF 0 "register_operand" "")
18170 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18171 UNSPEC_FRNDINT_TRUNC))
18172 (clobber (reg:CC FLAGS_REG))]
18173 "TARGET_USE_FANCY_MATH_387
18174 && flag_unsafe_math_optimizations
18175 && !(reload_completed || reload_in_progress)"
18180 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18182 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18183 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18185 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18186 operands[2], operands[3]));
18189 [(set_attr "type" "frndint")
18190 (set_attr "i387_cw" "trunc")
18191 (set_attr "mode" "XF")])
18193 (define_insn "frndintxf2_trunc_i387"
18194 [(set (match_operand:XF 0 "register_operand" "=f")
18195 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18196 UNSPEC_FRNDINT_TRUNC))
18197 (use (match_operand:HI 2 "memory_operand" "m"))
18198 (use (match_operand:HI 3 "memory_operand" "m"))]
18199 "TARGET_USE_FANCY_MATH_387
18200 && flag_unsafe_math_optimizations"
18201 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18202 [(set_attr "type" "frndint")
18203 (set_attr "i387_cw" "trunc")
18204 (set_attr "mode" "XF")])
18206 (define_expand "btruncxf2"
18207 [(use (match_operand:XF 0 "register_operand" ""))
18208 (use (match_operand:XF 1 "register_operand" ""))]
18209 "TARGET_USE_FANCY_MATH_387
18210 && flag_unsafe_math_optimizations && !optimize_size"
18212 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18216 (define_expand "btrunc<mode>2"
18217 [(use (match_operand:MODEF 0 "register_operand" ""))
18218 (use (match_operand:MODEF 1 "register_operand" ""))]
18219 "(TARGET_USE_FANCY_MATH_387
18220 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18221 || TARGET_MIX_SSE_I387)
18222 && flag_unsafe_math_optimizations && !optimize_size)
18223 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18224 && !flag_trapping_math
18225 && (TARGET_ROUND || !optimize_size))"
18227 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18228 && !flag_trapping_math
18229 && (TARGET_ROUND || !optimize_size))
18232 emit_insn (gen_sse4_1_round<mode>2
18233 (operands[0], operands[1], GEN_INT (0x03)));
18234 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18235 ix86_expand_trunc (operand0, operand1);
18237 ix86_expand_truncdf_32 (operand0, operand1);
18241 rtx op0 = gen_reg_rtx (XFmode);
18242 rtx op1 = gen_reg_rtx (XFmode);
18244 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18245 emit_insn (gen_frndintxf2_trunc (op0, op1));
18247 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18252 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18253 (define_insn_and_split "frndintxf2_mask_pm"
18254 [(set (match_operand:XF 0 "register_operand" "")
18255 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18256 UNSPEC_FRNDINT_MASK_PM))
18257 (clobber (reg:CC FLAGS_REG))]
18258 "TARGET_USE_FANCY_MATH_387
18259 && flag_unsafe_math_optimizations
18260 && !(reload_completed || reload_in_progress)"
18265 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18267 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18268 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18270 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18271 operands[2], operands[3]));
18274 [(set_attr "type" "frndint")
18275 (set_attr "i387_cw" "mask_pm")
18276 (set_attr "mode" "XF")])
18278 (define_insn "frndintxf2_mask_pm_i387"
18279 [(set (match_operand:XF 0 "register_operand" "=f")
18280 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18281 UNSPEC_FRNDINT_MASK_PM))
18282 (use (match_operand:HI 2 "memory_operand" "m"))
18283 (use (match_operand:HI 3 "memory_operand" "m"))]
18284 "TARGET_USE_FANCY_MATH_387
18285 && flag_unsafe_math_optimizations"
18286 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18287 [(set_attr "type" "frndint")
18288 (set_attr "i387_cw" "mask_pm")
18289 (set_attr "mode" "XF")])
18291 (define_expand "nearbyintxf2"
18292 [(use (match_operand:XF 0 "register_operand" ""))
18293 (use (match_operand:XF 1 "register_operand" ""))]
18294 "TARGET_USE_FANCY_MATH_387
18295 && flag_unsafe_math_optimizations"
18297 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18302 (define_expand "nearbyint<mode>2"
18303 [(use (match_operand:MODEF 0 "register_operand" ""))
18304 (use (match_operand:MODEF 1 "register_operand" ""))]
18305 "TARGET_USE_FANCY_MATH_387
18306 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18307 || TARGET_MIX_SSE_I387)
18308 && flag_unsafe_math_optimizations"
18310 rtx op0 = gen_reg_rtx (XFmode);
18311 rtx op1 = gen_reg_rtx (XFmode);
18313 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18314 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18316 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18320 (define_insn "fxam<mode>2_i387"
18321 [(set (match_operand:HI 0 "register_operand" "=a")
18323 [(match_operand:X87MODEF 1 "register_operand" "f")]
18325 "TARGET_USE_FANCY_MATH_387"
18326 "fxam\n\tfnstsw\t%0"
18327 [(set_attr "type" "multi")
18328 (set_attr "unit" "i387")
18329 (set_attr "mode" "<MODE>")])
18331 (define_expand "isinf<mode>2"
18332 [(use (match_operand:SI 0 "register_operand" ""))
18333 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18334 "TARGET_USE_FANCY_MATH_387
18335 && TARGET_C99_FUNCTIONS
18336 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18338 rtx mask = GEN_INT (0x45);
18339 rtx val = GEN_INT (0x05);
18343 rtx scratch = gen_reg_rtx (HImode);
18344 rtx res = gen_reg_rtx (QImode);
18346 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18347 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18348 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18349 cond = gen_rtx_fmt_ee (EQ, QImode,
18350 gen_rtx_REG (CCmode, FLAGS_REG),
18352 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18353 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18357 (define_expand "signbit<mode>2"
18358 [(use (match_operand:SI 0 "register_operand" ""))
18359 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18360 "TARGET_USE_FANCY_MATH_387
18361 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18363 rtx mask = GEN_INT (0x0200);
18365 rtx scratch = gen_reg_rtx (HImode);
18367 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18368 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18372 ;; Block operation instructions
18374 (define_expand "movmemsi"
18375 [(use (match_operand:BLK 0 "memory_operand" ""))
18376 (use (match_operand:BLK 1 "memory_operand" ""))
18377 (use (match_operand:SI 2 "nonmemory_operand" ""))
18378 (use (match_operand:SI 3 "const_int_operand" ""))
18379 (use (match_operand:SI 4 "const_int_operand" ""))
18380 (use (match_operand:SI 5 "const_int_operand" ""))]
18383 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18384 operands[4], operands[5]))
18390 (define_expand "movmemdi"
18391 [(use (match_operand:BLK 0 "memory_operand" ""))
18392 (use (match_operand:BLK 1 "memory_operand" ""))
18393 (use (match_operand:DI 2 "nonmemory_operand" ""))
18394 (use (match_operand:DI 3 "const_int_operand" ""))
18395 (use (match_operand:SI 4 "const_int_operand" ""))
18396 (use (match_operand:SI 5 "const_int_operand" ""))]
18399 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18400 operands[4], operands[5]))
18406 ;; Most CPUs don't like single string operations
18407 ;; Handle this case here to simplify previous expander.
18409 (define_expand "strmov"
18410 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18411 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18412 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18413 (clobber (reg:CC FLAGS_REG))])
18414 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18415 (clobber (reg:CC FLAGS_REG))])]
18418 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18420 /* If .md ever supports :P for Pmode, these can be directly
18421 in the pattern above. */
18422 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18423 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18425 /* Can't use this if the user has appropriated esi or edi. */
18426 if ((TARGET_SINGLE_STRINGOP || optimize_size)
18427 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18429 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18430 operands[2], operands[3],
18431 operands[5], operands[6]));
18435 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18438 (define_expand "strmov_singleop"
18439 [(parallel [(set (match_operand 1 "memory_operand" "")
18440 (match_operand 3 "memory_operand" ""))
18441 (set (match_operand 0 "register_operand" "")
18442 (match_operand 4 "" ""))
18443 (set (match_operand 2 "register_operand" "")
18444 (match_operand 5 "" ""))])]
18445 "TARGET_SINGLE_STRINGOP || optimize_size"
18448 (define_insn "*strmovdi_rex_1"
18449 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18450 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18451 (set (match_operand:DI 0 "register_operand" "=D")
18452 (plus:DI (match_dup 2)
18454 (set (match_operand:DI 1 "register_operand" "=S")
18455 (plus:DI (match_dup 3)
18457 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18459 [(set_attr "type" "str")
18460 (set_attr "mode" "DI")
18461 (set_attr "memory" "both")])
18463 (define_insn "*strmovsi_1"
18464 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18465 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18466 (set (match_operand:SI 0 "register_operand" "=D")
18467 (plus:SI (match_dup 2)
18469 (set (match_operand:SI 1 "register_operand" "=S")
18470 (plus:SI (match_dup 3)
18472 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18474 [(set_attr "type" "str")
18475 (set_attr "mode" "SI")
18476 (set_attr "memory" "both")])
18478 (define_insn "*strmovsi_rex_1"
18479 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18480 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18481 (set (match_operand:DI 0 "register_operand" "=D")
18482 (plus:DI (match_dup 2)
18484 (set (match_operand:DI 1 "register_operand" "=S")
18485 (plus:DI (match_dup 3)
18487 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18489 [(set_attr "type" "str")
18490 (set_attr "mode" "SI")
18491 (set_attr "memory" "both")])
18493 (define_insn "*strmovhi_1"
18494 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18495 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18496 (set (match_operand:SI 0 "register_operand" "=D")
18497 (plus:SI (match_dup 2)
18499 (set (match_operand:SI 1 "register_operand" "=S")
18500 (plus:SI (match_dup 3)
18502 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18504 [(set_attr "type" "str")
18505 (set_attr "memory" "both")
18506 (set_attr "mode" "HI")])
18508 (define_insn "*strmovhi_rex_1"
18509 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18510 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18511 (set (match_operand:DI 0 "register_operand" "=D")
18512 (plus:DI (match_dup 2)
18514 (set (match_operand:DI 1 "register_operand" "=S")
18515 (plus:DI (match_dup 3)
18517 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18519 [(set_attr "type" "str")
18520 (set_attr "memory" "both")
18521 (set_attr "mode" "HI")])
18523 (define_insn "*strmovqi_1"
18524 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18525 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18526 (set (match_operand:SI 0 "register_operand" "=D")
18527 (plus:SI (match_dup 2)
18529 (set (match_operand:SI 1 "register_operand" "=S")
18530 (plus:SI (match_dup 3)
18532 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18534 [(set_attr "type" "str")
18535 (set_attr "memory" "both")
18536 (set_attr "mode" "QI")])
18538 (define_insn "*strmovqi_rex_1"
18539 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18540 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18541 (set (match_operand:DI 0 "register_operand" "=D")
18542 (plus:DI (match_dup 2)
18544 (set (match_operand:DI 1 "register_operand" "=S")
18545 (plus:DI (match_dup 3)
18547 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18549 [(set_attr "type" "str")
18550 (set_attr "memory" "both")
18551 (set_attr "mode" "QI")])
18553 (define_expand "rep_mov"
18554 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18555 (set (match_operand 0 "register_operand" "")
18556 (match_operand 5 "" ""))
18557 (set (match_operand 2 "register_operand" "")
18558 (match_operand 6 "" ""))
18559 (set (match_operand 1 "memory_operand" "")
18560 (match_operand 3 "memory_operand" ""))
18561 (use (match_dup 4))])]
18565 (define_insn "*rep_movdi_rex64"
18566 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18567 (set (match_operand:DI 0 "register_operand" "=D")
18568 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18570 (match_operand:DI 3 "register_operand" "0")))
18571 (set (match_operand:DI 1 "register_operand" "=S")
18572 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18573 (match_operand:DI 4 "register_operand" "1")))
18574 (set (mem:BLK (match_dup 3))
18575 (mem:BLK (match_dup 4)))
18576 (use (match_dup 5))]
18579 [(set_attr "type" "str")
18580 (set_attr "prefix_rep" "1")
18581 (set_attr "memory" "both")
18582 (set_attr "mode" "DI")])
18584 (define_insn "*rep_movsi"
18585 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18586 (set (match_operand:SI 0 "register_operand" "=D")
18587 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18589 (match_operand:SI 3 "register_operand" "0")))
18590 (set (match_operand:SI 1 "register_operand" "=S")
18591 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18592 (match_operand:SI 4 "register_operand" "1")))
18593 (set (mem:BLK (match_dup 3))
18594 (mem:BLK (match_dup 4)))
18595 (use (match_dup 5))]
18598 [(set_attr "type" "str")
18599 (set_attr "prefix_rep" "1")
18600 (set_attr "memory" "both")
18601 (set_attr "mode" "SI")])
18603 (define_insn "*rep_movsi_rex64"
18604 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18605 (set (match_operand:DI 0 "register_operand" "=D")
18606 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18608 (match_operand:DI 3 "register_operand" "0")))
18609 (set (match_operand:DI 1 "register_operand" "=S")
18610 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18611 (match_operand:DI 4 "register_operand" "1")))
18612 (set (mem:BLK (match_dup 3))
18613 (mem:BLK (match_dup 4)))
18614 (use (match_dup 5))]
18617 [(set_attr "type" "str")
18618 (set_attr "prefix_rep" "1")
18619 (set_attr "memory" "both")
18620 (set_attr "mode" "SI")])
18622 (define_insn "*rep_movqi"
18623 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18624 (set (match_operand:SI 0 "register_operand" "=D")
18625 (plus:SI (match_operand:SI 3 "register_operand" "0")
18626 (match_operand:SI 5 "register_operand" "2")))
18627 (set (match_operand:SI 1 "register_operand" "=S")
18628 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18629 (set (mem:BLK (match_dup 3))
18630 (mem:BLK (match_dup 4)))
18631 (use (match_dup 5))]
18634 [(set_attr "type" "str")
18635 (set_attr "prefix_rep" "1")
18636 (set_attr "memory" "both")
18637 (set_attr "mode" "SI")])
18639 (define_insn "*rep_movqi_rex64"
18640 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18641 (set (match_operand:DI 0 "register_operand" "=D")
18642 (plus:DI (match_operand:DI 3 "register_operand" "0")
18643 (match_operand:DI 5 "register_operand" "2")))
18644 (set (match_operand:DI 1 "register_operand" "=S")
18645 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18646 (set (mem:BLK (match_dup 3))
18647 (mem:BLK (match_dup 4)))
18648 (use (match_dup 5))]
18651 [(set_attr "type" "str")
18652 (set_attr "prefix_rep" "1")
18653 (set_attr "memory" "both")
18654 (set_attr "mode" "SI")])
18656 (define_expand "setmemsi"
18657 [(use (match_operand:BLK 0 "memory_operand" ""))
18658 (use (match_operand:SI 1 "nonmemory_operand" ""))
18659 (use (match_operand 2 "const_int_operand" ""))
18660 (use (match_operand 3 "const_int_operand" ""))
18661 (use (match_operand:SI 4 "const_int_operand" ""))
18662 (use (match_operand:SI 5 "const_int_operand" ""))]
18665 if (ix86_expand_setmem (operands[0], operands[1],
18666 operands[2], operands[3],
18667 operands[4], operands[5]))
18673 (define_expand "setmemdi"
18674 [(use (match_operand:BLK 0 "memory_operand" ""))
18675 (use (match_operand:DI 1 "nonmemory_operand" ""))
18676 (use (match_operand 2 "const_int_operand" ""))
18677 (use (match_operand 3 "const_int_operand" ""))
18678 (use (match_operand 4 "const_int_operand" ""))
18679 (use (match_operand 5 "const_int_operand" ""))]
18682 if (ix86_expand_setmem (operands[0], operands[1],
18683 operands[2], operands[3],
18684 operands[4], operands[5]))
18690 ;; Most CPUs don't like single string operations
18691 ;; Handle this case here to simplify previous expander.
18693 (define_expand "strset"
18694 [(set (match_operand 1 "memory_operand" "")
18695 (match_operand 2 "register_operand" ""))
18696 (parallel [(set (match_operand 0 "register_operand" "")
18698 (clobber (reg:CC FLAGS_REG))])]
18701 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18702 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18704 /* If .md ever supports :P for Pmode, this can be directly
18705 in the pattern above. */
18706 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18707 GEN_INT (GET_MODE_SIZE (GET_MODE
18709 if (TARGET_SINGLE_STRINGOP || optimize_size)
18711 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18717 (define_expand "strset_singleop"
18718 [(parallel [(set (match_operand 1 "memory_operand" "")
18719 (match_operand 2 "register_operand" ""))
18720 (set (match_operand 0 "register_operand" "")
18721 (match_operand 3 "" ""))])]
18722 "TARGET_SINGLE_STRINGOP || optimize_size"
18725 (define_insn "*strsetdi_rex_1"
18726 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18727 (match_operand:DI 2 "register_operand" "a"))
18728 (set (match_operand:DI 0 "register_operand" "=D")
18729 (plus:DI (match_dup 1)
18731 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18733 [(set_attr "type" "str")
18734 (set_attr "memory" "store")
18735 (set_attr "mode" "DI")])
18737 (define_insn "*strsetsi_1"
18738 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18739 (match_operand:SI 2 "register_operand" "a"))
18740 (set (match_operand:SI 0 "register_operand" "=D")
18741 (plus:SI (match_dup 1)
18743 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18745 [(set_attr "type" "str")
18746 (set_attr "memory" "store")
18747 (set_attr "mode" "SI")])
18749 (define_insn "*strsetsi_rex_1"
18750 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18751 (match_operand:SI 2 "register_operand" "a"))
18752 (set (match_operand:DI 0 "register_operand" "=D")
18753 (plus:DI (match_dup 1)
18755 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18757 [(set_attr "type" "str")
18758 (set_attr "memory" "store")
18759 (set_attr "mode" "SI")])
18761 (define_insn "*strsethi_1"
18762 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18763 (match_operand:HI 2 "register_operand" "a"))
18764 (set (match_operand:SI 0 "register_operand" "=D")
18765 (plus:SI (match_dup 1)
18767 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18769 [(set_attr "type" "str")
18770 (set_attr "memory" "store")
18771 (set_attr "mode" "HI")])
18773 (define_insn "*strsethi_rex_1"
18774 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18775 (match_operand:HI 2 "register_operand" "a"))
18776 (set (match_operand:DI 0 "register_operand" "=D")
18777 (plus:DI (match_dup 1)
18779 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18781 [(set_attr "type" "str")
18782 (set_attr "memory" "store")
18783 (set_attr "mode" "HI")])
18785 (define_insn "*strsetqi_1"
18786 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18787 (match_operand:QI 2 "register_operand" "a"))
18788 (set (match_operand:SI 0 "register_operand" "=D")
18789 (plus:SI (match_dup 1)
18791 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18793 [(set_attr "type" "str")
18794 (set_attr "memory" "store")
18795 (set_attr "mode" "QI")])
18797 (define_insn "*strsetqi_rex_1"
18798 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18799 (match_operand:QI 2 "register_operand" "a"))
18800 (set (match_operand:DI 0 "register_operand" "=D")
18801 (plus:DI (match_dup 1)
18803 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18805 [(set_attr "type" "str")
18806 (set_attr "memory" "store")
18807 (set_attr "mode" "QI")])
18809 (define_expand "rep_stos"
18810 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18811 (set (match_operand 0 "register_operand" "")
18812 (match_operand 4 "" ""))
18813 (set (match_operand 2 "memory_operand" "") (const_int 0))
18814 (use (match_operand 3 "register_operand" ""))
18815 (use (match_dup 1))])]
18819 (define_insn "*rep_stosdi_rex64"
18820 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18821 (set (match_operand:DI 0 "register_operand" "=D")
18822 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18824 (match_operand:DI 3 "register_operand" "0")))
18825 (set (mem:BLK (match_dup 3))
18827 (use (match_operand:DI 2 "register_operand" "a"))
18828 (use (match_dup 4))]
18831 [(set_attr "type" "str")
18832 (set_attr "prefix_rep" "1")
18833 (set_attr "memory" "store")
18834 (set_attr "mode" "DI")])
18836 (define_insn "*rep_stossi"
18837 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18838 (set (match_operand:SI 0 "register_operand" "=D")
18839 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18841 (match_operand:SI 3 "register_operand" "0")))
18842 (set (mem:BLK (match_dup 3))
18844 (use (match_operand:SI 2 "register_operand" "a"))
18845 (use (match_dup 4))]
18848 [(set_attr "type" "str")
18849 (set_attr "prefix_rep" "1")
18850 (set_attr "memory" "store")
18851 (set_attr "mode" "SI")])
18853 (define_insn "*rep_stossi_rex64"
18854 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18855 (set (match_operand:DI 0 "register_operand" "=D")
18856 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18858 (match_operand:DI 3 "register_operand" "0")))
18859 (set (mem:BLK (match_dup 3))
18861 (use (match_operand:SI 2 "register_operand" "a"))
18862 (use (match_dup 4))]
18865 [(set_attr "type" "str")
18866 (set_attr "prefix_rep" "1")
18867 (set_attr "memory" "store")
18868 (set_attr "mode" "SI")])
18870 (define_insn "*rep_stosqi"
18871 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18872 (set (match_operand:SI 0 "register_operand" "=D")
18873 (plus:SI (match_operand:SI 3 "register_operand" "0")
18874 (match_operand:SI 4 "register_operand" "1")))
18875 (set (mem:BLK (match_dup 3))
18877 (use (match_operand:QI 2 "register_operand" "a"))
18878 (use (match_dup 4))]
18881 [(set_attr "type" "str")
18882 (set_attr "prefix_rep" "1")
18883 (set_attr "memory" "store")
18884 (set_attr "mode" "QI")])
18886 (define_insn "*rep_stosqi_rex64"
18887 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18888 (set (match_operand:DI 0 "register_operand" "=D")
18889 (plus:DI (match_operand:DI 3 "register_operand" "0")
18890 (match_operand:DI 4 "register_operand" "1")))
18891 (set (mem:BLK (match_dup 3))
18893 (use (match_operand:QI 2 "register_operand" "a"))
18894 (use (match_dup 4))]
18897 [(set_attr "type" "str")
18898 (set_attr "prefix_rep" "1")
18899 (set_attr "memory" "store")
18900 (set_attr "mode" "QI")])
18902 (define_expand "cmpstrnsi"
18903 [(set (match_operand:SI 0 "register_operand" "")
18904 (compare:SI (match_operand:BLK 1 "general_operand" "")
18905 (match_operand:BLK 2 "general_operand" "")))
18906 (use (match_operand 3 "general_operand" ""))
18907 (use (match_operand 4 "immediate_operand" ""))]
18908 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18910 rtx addr1, addr2, out, outlow, count, countreg, align;
18912 /* Can't use this if the user has appropriated esi or edi. */
18913 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18918 out = gen_reg_rtx (SImode);
18920 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18921 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18922 if (addr1 != XEXP (operands[1], 0))
18923 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18924 if (addr2 != XEXP (operands[2], 0))
18925 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18927 count = operands[3];
18928 countreg = ix86_zero_extend_to_Pmode (count);
18930 /* %%% Iff we are testing strict equality, we can use known alignment
18931 to good advantage. This may be possible with combine, particularly
18932 once cc0 is dead. */
18933 align = operands[4];
18935 if (CONST_INT_P (count))
18937 if (INTVAL (count) == 0)
18939 emit_move_insn (operands[0], const0_rtx);
18942 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18943 operands[1], operands[2]));
18948 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18950 emit_insn (gen_cmpsi_1 (countreg, countreg));
18951 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18952 operands[1], operands[2]));
18955 outlow = gen_lowpart (QImode, out);
18956 emit_insn (gen_cmpintqi (outlow));
18957 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18959 if (operands[0] != out)
18960 emit_move_insn (operands[0], out);
18965 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18967 (define_expand "cmpintqi"
18968 [(set (match_dup 1)
18969 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18971 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18972 (parallel [(set (match_operand:QI 0 "register_operand" "")
18973 (minus:QI (match_dup 1)
18975 (clobber (reg:CC FLAGS_REG))])]
18977 "operands[1] = gen_reg_rtx (QImode);
18978 operands[2] = gen_reg_rtx (QImode);")
18980 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18981 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18983 (define_expand "cmpstrnqi_nz_1"
18984 [(parallel [(set (reg:CC FLAGS_REG)
18985 (compare:CC (match_operand 4 "memory_operand" "")
18986 (match_operand 5 "memory_operand" "")))
18987 (use (match_operand 2 "register_operand" ""))
18988 (use (match_operand:SI 3 "immediate_operand" ""))
18989 (clobber (match_operand 0 "register_operand" ""))
18990 (clobber (match_operand 1 "register_operand" ""))
18991 (clobber (match_dup 2))])]
18995 (define_insn "*cmpstrnqi_nz_1"
18996 [(set (reg:CC FLAGS_REG)
18997 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18998 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18999 (use (match_operand:SI 6 "register_operand" "2"))
19000 (use (match_operand:SI 3 "immediate_operand" "i"))
19001 (clobber (match_operand:SI 0 "register_operand" "=S"))
19002 (clobber (match_operand:SI 1 "register_operand" "=D"))
19003 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19006 [(set_attr "type" "str")
19007 (set_attr "mode" "QI")
19008 (set_attr "prefix_rep" "1")])
19010 (define_insn "*cmpstrnqi_nz_rex_1"
19011 [(set (reg:CC FLAGS_REG)
19012 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19013 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19014 (use (match_operand:DI 6 "register_operand" "2"))
19015 (use (match_operand:SI 3 "immediate_operand" "i"))
19016 (clobber (match_operand:DI 0 "register_operand" "=S"))
19017 (clobber (match_operand:DI 1 "register_operand" "=D"))
19018 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19021 [(set_attr "type" "str")
19022 (set_attr "mode" "QI")
19023 (set_attr "prefix_rep" "1")])
19025 ;; The same, but the count is not known to not be zero.
19027 (define_expand "cmpstrnqi_1"
19028 [(parallel [(set (reg:CC FLAGS_REG)
19029 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19031 (compare:CC (match_operand 4 "memory_operand" "")
19032 (match_operand 5 "memory_operand" ""))
19034 (use (match_operand:SI 3 "immediate_operand" ""))
19035 (use (reg:CC FLAGS_REG))
19036 (clobber (match_operand 0 "register_operand" ""))
19037 (clobber (match_operand 1 "register_operand" ""))
19038 (clobber (match_dup 2))])]
19042 (define_insn "*cmpstrnqi_1"
19043 [(set (reg:CC FLAGS_REG)
19044 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19046 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19047 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19049 (use (match_operand:SI 3 "immediate_operand" "i"))
19050 (use (reg:CC FLAGS_REG))
19051 (clobber (match_operand:SI 0 "register_operand" "=S"))
19052 (clobber (match_operand:SI 1 "register_operand" "=D"))
19053 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19056 [(set_attr "type" "str")
19057 (set_attr "mode" "QI")
19058 (set_attr "prefix_rep" "1")])
19060 (define_insn "*cmpstrnqi_rex_1"
19061 [(set (reg:CC FLAGS_REG)
19062 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19064 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19065 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19067 (use (match_operand:SI 3 "immediate_operand" "i"))
19068 (use (reg:CC FLAGS_REG))
19069 (clobber (match_operand:DI 0 "register_operand" "=S"))
19070 (clobber (match_operand:DI 1 "register_operand" "=D"))
19071 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19074 [(set_attr "type" "str")
19075 (set_attr "mode" "QI")
19076 (set_attr "prefix_rep" "1")])
19078 (define_expand "strlensi"
19079 [(set (match_operand:SI 0 "register_operand" "")
19080 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19081 (match_operand:QI 2 "immediate_operand" "")
19082 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19085 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19091 (define_expand "strlendi"
19092 [(set (match_operand:DI 0 "register_operand" "")
19093 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19094 (match_operand:QI 2 "immediate_operand" "")
19095 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19098 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19104 (define_expand "strlenqi_1"
19105 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19106 (clobber (match_operand 1 "register_operand" ""))
19107 (clobber (reg:CC FLAGS_REG))])]
19111 (define_insn "*strlenqi_1"
19112 [(set (match_operand:SI 0 "register_operand" "=&c")
19113 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19114 (match_operand:QI 2 "register_operand" "a")
19115 (match_operand:SI 3 "immediate_operand" "i")
19116 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19117 (clobber (match_operand:SI 1 "register_operand" "=D"))
19118 (clobber (reg:CC FLAGS_REG))]
19121 [(set_attr "type" "str")
19122 (set_attr "mode" "QI")
19123 (set_attr "prefix_rep" "1")])
19125 (define_insn "*strlenqi_rex_1"
19126 [(set (match_operand:DI 0 "register_operand" "=&c")
19127 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19128 (match_operand:QI 2 "register_operand" "a")
19129 (match_operand:DI 3 "immediate_operand" "i")
19130 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19131 (clobber (match_operand:DI 1 "register_operand" "=D"))
19132 (clobber (reg:CC FLAGS_REG))]
19135 [(set_attr "type" "str")
19136 (set_attr "mode" "QI")
19137 (set_attr "prefix_rep" "1")])
19139 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19140 ;; handled in combine, but it is not currently up to the task.
19141 ;; When used for their truth value, the cmpstrn* expanders generate
19150 ;; The intermediate three instructions are unnecessary.
19152 ;; This one handles cmpstrn*_nz_1...
19155 (set (reg:CC FLAGS_REG)
19156 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19157 (mem:BLK (match_operand 5 "register_operand" ""))))
19158 (use (match_operand 6 "register_operand" ""))
19159 (use (match_operand:SI 3 "immediate_operand" ""))
19160 (clobber (match_operand 0 "register_operand" ""))
19161 (clobber (match_operand 1 "register_operand" ""))
19162 (clobber (match_operand 2 "register_operand" ""))])
19163 (set (match_operand:QI 7 "register_operand" "")
19164 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19165 (set (match_operand:QI 8 "register_operand" "")
19166 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19167 (set (reg FLAGS_REG)
19168 (compare (match_dup 7) (match_dup 8)))
19170 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19172 (set (reg:CC FLAGS_REG)
19173 (compare:CC (mem:BLK (match_dup 4))
19174 (mem:BLK (match_dup 5))))
19175 (use (match_dup 6))
19176 (use (match_dup 3))
19177 (clobber (match_dup 0))
19178 (clobber (match_dup 1))
19179 (clobber (match_dup 2))])]
19182 ;; ...and this one handles cmpstrn*_1.
19185 (set (reg:CC FLAGS_REG)
19186 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19188 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19189 (mem:BLK (match_operand 5 "register_operand" "")))
19191 (use (match_operand:SI 3 "immediate_operand" ""))
19192 (use (reg:CC FLAGS_REG))
19193 (clobber (match_operand 0 "register_operand" ""))
19194 (clobber (match_operand 1 "register_operand" ""))
19195 (clobber (match_operand 2 "register_operand" ""))])
19196 (set (match_operand:QI 7 "register_operand" "")
19197 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19198 (set (match_operand:QI 8 "register_operand" "")
19199 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19200 (set (reg FLAGS_REG)
19201 (compare (match_dup 7) (match_dup 8)))
19203 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19205 (set (reg:CC FLAGS_REG)
19206 (if_then_else:CC (ne (match_dup 6)
19208 (compare:CC (mem:BLK (match_dup 4))
19209 (mem:BLK (match_dup 5)))
19211 (use (match_dup 3))
19212 (use (reg:CC FLAGS_REG))
19213 (clobber (match_dup 0))
19214 (clobber (match_dup 1))
19215 (clobber (match_dup 2))])]
19220 ;; Conditional move instructions.
19222 (define_expand "movdicc"
19223 [(set (match_operand:DI 0 "register_operand" "")
19224 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19225 (match_operand:DI 2 "general_operand" "")
19226 (match_operand:DI 3 "general_operand" "")))]
19228 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19230 (define_insn "x86_movdicc_0_m1_rex64"
19231 [(set (match_operand:DI 0 "register_operand" "=r")
19232 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19235 (clobber (reg:CC FLAGS_REG))]
19238 ; Since we don't have the proper number of operands for an alu insn,
19239 ; fill in all the blanks.
19240 [(set_attr "type" "alu")
19241 (set_attr "pent_pair" "pu")
19242 (set_attr "memory" "none")
19243 (set_attr "imm_disp" "false")
19244 (set_attr "mode" "DI")
19245 (set_attr "length_immediate" "0")])
19247 (define_insn "*x86_movdicc_0_m1_se"
19248 [(set (match_operand:DI 0 "register_operand" "=r")
19249 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19252 (clobber (reg:CC FLAGS_REG))]
19255 [(set_attr "type" "alu")
19256 (set_attr "pent_pair" "pu")
19257 (set_attr "memory" "none")
19258 (set_attr "imm_disp" "false")
19259 (set_attr "mode" "DI")
19260 (set_attr "length_immediate" "0")])
19262 (define_insn "*movdicc_c_rex64"
19263 [(set (match_operand:DI 0 "register_operand" "=r,r")
19264 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19265 [(reg FLAGS_REG) (const_int 0)])
19266 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19267 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19268 "TARGET_64BIT && TARGET_CMOVE
19269 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19271 cmov%O2%C1\t{%2, %0|%0, %2}
19272 cmov%O2%c1\t{%3, %0|%0, %3}"
19273 [(set_attr "type" "icmov")
19274 (set_attr "mode" "DI")])
19276 (define_expand "movsicc"
19277 [(set (match_operand:SI 0 "register_operand" "")
19278 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19279 (match_operand:SI 2 "general_operand" "")
19280 (match_operand:SI 3 "general_operand" "")))]
19282 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19284 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19285 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19286 ;; So just document what we're doing explicitly.
19288 (define_insn "x86_movsicc_0_m1"
19289 [(set (match_operand:SI 0 "register_operand" "=r")
19290 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19293 (clobber (reg:CC FLAGS_REG))]
19296 ; Since we don't have the proper number of operands for an alu insn,
19297 ; fill in all the blanks.
19298 [(set_attr "type" "alu")
19299 (set_attr "pent_pair" "pu")
19300 (set_attr "memory" "none")
19301 (set_attr "imm_disp" "false")
19302 (set_attr "mode" "SI")
19303 (set_attr "length_immediate" "0")])
19305 (define_insn "*x86_movsicc_0_m1_se"
19306 [(set (match_operand:SI 0 "register_operand" "=r")
19307 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19310 (clobber (reg:CC FLAGS_REG))]
19313 [(set_attr "type" "alu")
19314 (set_attr "pent_pair" "pu")
19315 (set_attr "memory" "none")
19316 (set_attr "imm_disp" "false")
19317 (set_attr "mode" "SI")
19318 (set_attr "length_immediate" "0")])
19320 (define_insn "*movsicc_noc"
19321 [(set (match_operand:SI 0 "register_operand" "=r,r")
19322 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19323 [(reg FLAGS_REG) (const_int 0)])
19324 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19325 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19327 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19329 cmov%O2%C1\t{%2, %0|%0, %2}
19330 cmov%O2%c1\t{%3, %0|%0, %3}"
19331 [(set_attr "type" "icmov")
19332 (set_attr "mode" "SI")])
19334 (define_expand "movhicc"
19335 [(set (match_operand:HI 0 "register_operand" "")
19336 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19337 (match_operand:HI 2 "general_operand" "")
19338 (match_operand:HI 3 "general_operand" "")))]
19339 "TARGET_HIMODE_MATH"
19340 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19342 (define_insn "*movhicc_noc"
19343 [(set (match_operand:HI 0 "register_operand" "=r,r")
19344 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19345 [(reg FLAGS_REG) (const_int 0)])
19346 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19347 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19349 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19351 cmov%O2%C1\t{%2, %0|%0, %2}
19352 cmov%O2%c1\t{%3, %0|%0, %3}"
19353 [(set_attr "type" "icmov")
19354 (set_attr "mode" "HI")])
19356 (define_expand "movqicc"
19357 [(set (match_operand:QI 0 "register_operand" "")
19358 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19359 (match_operand:QI 2 "general_operand" "")
19360 (match_operand:QI 3 "general_operand" "")))]
19361 "TARGET_QIMODE_MATH"
19362 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19364 (define_insn_and_split "*movqicc_noc"
19365 [(set (match_operand:QI 0 "register_operand" "=r,r")
19366 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19367 [(match_operand 4 "flags_reg_operand" "")
19369 (match_operand:QI 2 "register_operand" "r,0")
19370 (match_operand:QI 3 "register_operand" "0,r")))]
19371 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19373 "&& reload_completed"
19374 [(set (match_dup 0)
19375 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19378 "operands[0] = gen_lowpart (SImode, operands[0]);
19379 operands[2] = gen_lowpart (SImode, operands[2]);
19380 operands[3] = gen_lowpart (SImode, operands[3]);"
19381 [(set_attr "type" "icmov")
19382 (set_attr "mode" "SI")])
19384 (define_expand "mov<mode>cc"
19385 [(set (match_operand:X87MODEF 0 "register_operand" "")
19386 (if_then_else:X87MODEF
19387 (match_operand 1 "comparison_operator" "")
19388 (match_operand:X87MODEF 2 "register_operand" "")
19389 (match_operand:X87MODEF 3 "register_operand" "")))]
19390 "(TARGET_80387 && TARGET_CMOVE)
19391 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19392 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19394 (define_insn "*movsfcc_1_387"
19395 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19396 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19397 [(reg FLAGS_REG) (const_int 0)])
19398 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19399 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19400 "TARGET_80387 && TARGET_CMOVE
19401 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19403 fcmov%F1\t{%2, %0|%0, %2}
19404 fcmov%f1\t{%3, %0|%0, %3}
19405 cmov%O2%C1\t{%2, %0|%0, %2}
19406 cmov%O2%c1\t{%3, %0|%0, %3}"
19407 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19408 (set_attr "mode" "SF,SF,SI,SI")])
19410 (define_insn "*movdfcc_1"
19411 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19412 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19413 [(reg FLAGS_REG) (const_int 0)])
19414 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19415 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19416 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19417 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19419 fcmov%F1\t{%2, %0|%0, %2}
19420 fcmov%f1\t{%3, %0|%0, %3}
19423 [(set_attr "type" "fcmov,fcmov,multi,multi")
19424 (set_attr "mode" "DF")])
19426 (define_insn "*movdfcc_1_rex64"
19427 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19428 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19429 [(reg FLAGS_REG) (const_int 0)])
19430 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19431 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19432 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19433 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19435 fcmov%F1\t{%2, %0|%0, %2}
19436 fcmov%f1\t{%3, %0|%0, %3}
19437 cmov%O2%C1\t{%2, %0|%0, %2}
19438 cmov%O2%c1\t{%3, %0|%0, %3}"
19439 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19440 (set_attr "mode" "DF")])
19443 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19444 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19445 [(match_operand 4 "flags_reg_operand" "")
19447 (match_operand:DF 2 "nonimmediate_operand" "")
19448 (match_operand:DF 3 "nonimmediate_operand" "")))]
19449 "!TARGET_64BIT && reload_completed"
19450 [(set (match_dup 2)
19451 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19455 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19458 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19459 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19461 (define_insn "*movxfcc_1"
19462 [(set (match_operand:XF 0 "register_operand" "=f,f")
19463 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19464 [(reg FLAGS_REG) (const_int 0)])
19465 (match_operand:XF 2 "register_operand" "f,0")
19466 (match_operand:XF 3 "register_operand" "0,f")))]
19467 "TARGET_80387 && TARGET_CMOVE"
19469 fcmov%F1\t{%2, %0|%0, %2}
19470 fcmov%f1\t{%3, %0|%0, %3}"
19471 [(set_attr "type" "fcmov")
19472 (set_attr "mode" "XF")])
19474 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19475 ;; the scalar versions to have only XMM registers as operands.
19477 ;; SSE5 conditional move
19478 (define_insn "*sse5_pcmov_<mode>"
19479 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19480 (if_then_else:MODEF
19481 (match_operand:MODEF 1 "register_operand" "x,0")
19482 (match_operand:MODEF 2 "register_operand" "0,x")
19483 (match_operand:MODEF 3 "register_operand" "x,x")))]
19484 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19485 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19486 [(set_attr "type" "sse4arg")])
19488 ;; These versions of the min/max patterns are intentionally ignorant of
19489 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19490 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19491 ;; are undefined in this condition, we're certain this is correct.
19493 (define_insn "<code><mode>3"
19494 [(set (match_operand:MODEF 0 "register_operand" "=x")
19496 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19497 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19498 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19499 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19500 [(set_attr "type" "sseadd")
19501 (set_attr "mode" "<MODE>")])
19503 ;; These versions of the min/max patterns implement exactly the operations
19504 ;; min = (op1 < op2 ? op1 : op2)
19505 ;; max = (!(op1 < op2) ? op1 : op2)
19506 ;; Their operands are not commutative, and thus they may be used in the
19507 ;; presence of -0.0 and NaN.
19509 (define_insn "*ieee_smin<mode>3"
19510 [(set (match_operand:MODEF 0 "register_operand" "=x")
19512 [(match_operand:MODEF 1 "register_operand" "0")
19513 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19515 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19516 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19517 [(set_attr "type" "sseadd")
19518 (set_attr "mode" "<MODE>")])
19520 (define_insn "*ieee_smax<mode>3"
19521 [(set (match_operand:MODEF 0 "register_operand" "=x")
19523 [(match_operand:MODEF 1 "register_operand" "0")
19524 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19526 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19527 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19528 [(set_attr "type" "sseadd")
19529 (set_attr "mode" "<MODE>")])
19531 ;; Make two stack loads independent:
19533 ;; fld %st(0) -> fld bb
19534 ;; fmul bb fmul %st(1), %st
19536 ;; Actually we only match the last two instructions for simplicity.
19538 [(set (match_operand 0 "fp_register_operand" "")
19539 (match_operand 1 "fp_register_operand" ""))
19541 (match_operator 2 "binary_fp_operator"
19543 (match_operand 3 "memory_operand" "")]))]
19544 "REGNO (operands[0]) != REGNO (operands[1])"
19545 [(set (match_dup 0) (match_dup 3))
19546 (set (match_dup 0) (match_dup 4))]
19548 ;; The % modifier is not operational anymore in peephole2's, so we have to
19549 ;; swap the operands manually in the case of addition and multiplication.
19550 "if (COMMUTATIVE_ARITH_P (operands[2]))
19551 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19552 operands[0], operands[1]);
19554 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19555 operands[1], operands[0]);")
19557 ;; Conditional addition patterns
19558 (define_expand "add<mode>cc"
19559 [(match_operand:SWI 0 "register_operand" "")
19560 (match_operand 1 "comparison_operator" "")
19561 (match_operand:SWI 2 "register_operand" "")
19562 (match_operand:SWI 3 "const_int_operand" "")]
19564 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19567 ;; Misc patterns (?)
19569 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19570 ;; Otherwise there will be nothing to keep
19572 ;; [(set (reg ebp) (reg esp))]
19573 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19574 ;; (clobber (eflags)]
19575 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19577 ;; in proper program order.
19578 (define_insn "pro_epilogue_adjust_stack_1"
19579 [(set (match_operand:SI 0 "register_operand" "=r,r")
19580 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19581 (match_operand:SI 2 "immediate_operand" "i,i")))
19582 (clobber (reg:CC FLAGS_REG))
19583 (clobber (mem:BLK (scratch)))]
19586 switch (get_attr_type (insn))
19589 return "mov{l}\t{%1, %0|%0, %1}";
19592 if (CONST_INT_P (operands[2])
19593 && (INTVAL (operands[2]) == 128
19594 || (INTVAL (operands[2]) < 0
19595 && INTVAL (operands[2]) != -128)))
19597 operands[2] = GEN_INT (-INTVAL (operands[2]));
19598 return "sub{l}\t{%2, %0|%0, %2}";
19600 return "add{l}\t{%2, %0|%0, %2}";
19603 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19604 return "lea{l}\t{%a2, %0|%0, %a2}";
19607 gcc_unreachable ();
19610 [(set (attr "type")
19611 (cond [(eq_attr "alternative" "0")
19612 (const_string "alu")
19613 (match_operand:SI 2 "const0_operand" "")
19614 (const_string "imov")
19616 (const_string "lea")))
19617 (set_attr "mode" "SI")])
19619 (define_insn "pro_epilogue_adjust_stack_rex64"
19620 [(set (match_operand:DI 0 "register_operand" "=r,r")
19621 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19622 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19623 (clobber (reg:CC FLAGS_REG))
19624 (clobber (mem:BLK (scratch)))]
19627 switch (get_attr_type (insn))
19630 return "mov{q}\t{%1, %0|%0, %1}";
19633 if (CONST_INT_P (operands[2])
19634 /* Avoid overflows. */
19635 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19636 && (INTVAL (operands[2]) == 128
19637 || (INTVAL (operands[2]) < 0
19638 && INTVAL (operands[2]) != -128)))
19640 operands[2] = GEN_INT (-INTVAL (operands[2]));
19641 return "sub{q}\t{%2, %0|%0, %2}";
19643 return "add{q}\t{%2, %0|%0, %2}";
19646 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19647 return "lea{q}\t{%a2, %0|%0, %a2}";
19650 gcc_unreachable ();
19653 [(set (attr "type")
19654 (cond [(eq_attr "alternative" "0")
19655 (const_string "alu")
19656 (match_operand:DI 2 "const0_operand" "")
19657 (const_string "imov")
19659 (const_string "lea")))
19660 (set_attr "mode" "DI")])
19662 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19663 [(set (match_operand:DI 0 "register_operand" "=r,r")
19664 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19665 (match_operand:DI 3 "immediate_operand" "i,i")))
19666 (use (match_operand:DI 2 "register_operand" "r,r"))
19667 (clobber (reg:CC FLAGS_REG))
19668 (clobber (mem:BLK (scratch)))]
19671 switch (get_attr_type (insn))
19674 return "add{q}\t{%2, %0|%0, %2}";
19677 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19678 return "lea{q}\t{%a2, %0|%0, %a2}";
19681 gcc_unreachable ();
19684 [(set_attr "type" "alu,lea")
19685 (set_attr "mode" "DI")])
19687 (define_insn "allocate_stack_worker_32"
19688 [(set (match_operand:SI 0 "register_operand" "+a")
19689 (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19690 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19691 (clobber (reg:CC FLAGS_REG))]
19692 "!TARGET_64BIT && TARGET_STACK_PROBE"
19694 [(set_attr "type" "multi")
19695 (set_attr "length" "5")])
19697 (define_insn "allocate_stack_worker_64"
19698 [(set (match_operand:DI 0 "register_operand" "=a")
19699 (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19700 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19701 (clobber (reg:DI R10_REG))
19702 (clobber (reg:DI R11_REG))
19703 (clobber (reg:CC FLAGS_REG))]
19704 "TARGET_64BIT && TARGET_STACK_PROBE"
19706 [(set_attr "type" "multi")
19707 (set_attr "length" "5")])
19709 (define_expand "allocate_stack"
19710 [(match_operand 0 "register_operand" "")
19711 (match_operand 1 "general_operand" "")]
19712 "TARGET_STACK_PROBE"
19716 #ifndef CHECK_STACK_LIMIT
19717 #define CHECK_STACK_LIMIT 0
19720 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19721 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19723 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19724 stack_pointer_rtx, 0, OPTAB_DIRECT);
19725 if (x != stack_pointer_rtx)
19726 emit_move_insn (stack_pointer_rtx, x);
19730 x = copy_to_mode_reg (Pmode, operands[1]);
19732 x = gen_allocate_stack_worker_64 (x);
19734 x = gen_allocate_stack_worker_32 (x);
19738 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19742 (define_expand "builtin_setjmp_receiver"
19743 [(label_ref (match_operand 0 "" ""))]
19744 "!TARGET_64BIT && flag_pic"
19749 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19750 rtx label_rtx = gen_label_rtx ();
19751 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19752 xops[0] = xops[1] = picreg;
19753 xops[2] = gen_rtx_CONST (SImode,
19754 gen_rtx_MINUS (SImode,
19755 gen_rtx_LABEL_REF (SImode, label_rtx),
19756 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19757 ix86_expand_binary_operator (MINUS, SImode, xops);
19760 emit_insn (gen_set_got (pic_offset_table_rtx));
19764 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19767 [(set (match_operand 0 "register_operand" "")
19768 (match_operator 3 "promotable_binary_operator"
19769 [(match_operand 1 "register_operand" "")
19770 (match_operand 2 "aligned_operand" "")]))
19771 (clobber (reg:CC FLAGS_REG))]
19772 "! TARGET_PARTIAL_REG_STALL && reload_completed
19773 && ((GET_MODE (operands[0]) == HImode
19774 && ((!optimize_size && !TARGET_FAST_PREFIX)
19775 /* ??? next two lines just !satisfies_constraint_K (...) */
19776 || !CONST_INT_P (operands[2])
19777 || satisfies_constraint_K (operands[2])))
19778 || (GET_MODE (operands[0]) == QImode
19779 && (TARGET_PROMOTE_QImode || optimize_size)))"
19780 [(parallel [(set (match_dup 0)
19781 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19782 (clobber (reg:CC FLAGS_REG))])]
19783 "operands[0] = gen_lowpart (SImode, operands[0]);
19784 operands[1] = gen_lowpart (SImode, operands[1]);
19785 if (GET_CODE (operands[3]) != ASHIFT)
19786 operands[2] = gen_lowpart (SImode, operands[2]);
19787 PUT_MODE (operands[3], SImode);")
19789 ; Promote the QImode tests, as i386 has encoding of the AND
19790 ; instruction with 32-bit sign-extended immediate and thus the
19791 ; instruction size is unchanged, except in the %eax case for
19792 ; which it is increased by one byte, hence the ! optimize_size.
19794 [(set (match_operand 0 "flags_reg_operand" "")
19795 (match_operator 2 "compare_operator"
19796 [(and (match_operand 3 "aligned_operand" "")
19797 (match_operand 4 "const_int_operand" ""))
19799 (set (match_operand 1 "register_operand" "")
19800 (and (match_dup 3) (match_dup 4)))]
19801 "! TARGET_PARTIAL_REG_STALL && reload_completed
19803 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19804 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19805 /* Ensure that the operand will remain sign-extended immediate. */
19806 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19807 [(parallel [(set (match_dup 0)
19808 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19811 (and:SI (match_dup 3) (match_dup 4)))])]
19814 = gen_int_mode (INTVAL (operands[4])
19815 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19816 operands[1] = gen_lowpart (SImode, operands[1]);
19817 operands[3] = gen_lowpart (SImode, operands[3]);
19820 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19821 ; the TEST instruction with 32-bit sign-extended immediate and thus
19822 ; the instruction size would at least double, which is not what we
19823 ; want even with ! optimize_size.
19825 [(set (match_operand 0 "flags_reg_operand" "")
19826 (match_operator 1 "compare_operator"
19827 [(and (match_operand:HI 2 "aligned_operand" "")
19828 (match_operand:HI 3 "const_int_operand" ""))
19830 "! TARGET_PARTIAL_REG_STALL && reload_completed
19831 && ! TARGET_FAST_PREFIX
19833 /* Ensure that the operand will remain sign-extended immediate. */
19834 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19835 [(set (match_dup 0)
19836 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19840 = gen_int_mode (INTVAL (operands[3])
19841 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19842 operands[2] = gen_lowpart (SImode, operands[2]);
19846 [(set (match_operand 0 "register_operand" "")
19847 (neg (match_operand 1 "register_operand" "")))
19848 (clobber (reg:CC FLAGS_REG))]
19849 "! TARGET_PARTIAL_REG_STALL && reload_completed
19850 && (GET_MODE (operands[0]) == HImode
19851 || (GET_MODE (operands[0]) == QImode
19852 && (TARGET_PROMOTE_QImode || optimize_size)))"
19853 [(parallel [(set (match_dup 0)
19854 (neg:SI (match_dup 1)))
19855 (clobber (reg:CC FLAGS_REG))])]
19856 "operands[0] = gen_lowpart (SImode, operands[0]);
19857 operands[1] = gen_lowpart (SImode, operands[1]);")
19860 [(set (match_operand 0 "register_operand" "")
19861 (not (match_operand 1 "register_operand" "")))]
19862 "! TARGET_PARTIAL_REG_STALL && reload_completed
19863 && (GET_MODE (operands[0]) == HImode
19864 || (GET_MODE (operands[0]) == QImode
19865 && (TARGET_PROMOTE_QImode || optimize_size)))"
19866 [(set (match_dup 0)
19867 (not:SI (match_dup 1)))]
19868 "operands[0] = gen_lowpart (SImode, operands[0]);
19869 operands[1] = gen_lowpart (SImode, operands[1]);")
19872 [(set (match_operand 0 "register_operand" "")
19873 (if_then_else (match_operator 1 "comparison_operator"
19874 [(reg FLAGS_REG) (const_int 0)])
19875 (match_operand 2 "register_operand" "")
19876 (match_operand 3 "register_operand" "")))]
19877 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19878 && (GET_MODE (operands[0]) == HImode
19879 || (GET_MODE (operands[0]) == QImode
19880 && (TARGET_PROMOTE_QImode || optimize_size)))"
19881 [(set (match_dup 0)
19882 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19883 "operands[0] = gen_lowpart (SImode, operands[0]);
19884 operands[2] = gen_lowpart (SImode, operands[2]);
19885 operands[3] = gen_lowpart (SImode, operands[3]);")
19888 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19889 ;; transform a complex memory operation into two memory to register operations.
19891 ;; Don't push memory operands
19893 [(set (match_operand:SI 0 "push_operand" "")
19894 (match_operand:SI 1 "memory_operand" ""))
19895 (match_scratch:SI 2 "r")]
19896 "!optimize_size && !TARGET_PUSH_MEMORY
19897 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19898 [(set (match_dup 2) (match_dup 1))
19899 (set (match_dup 0) (match_dup 2))]
19903 [(set (match_operand:DI 0 "push_operand" "")
19904 (match_operand:DI 1 "memory_operand" ""))
19905 (match_scratch:DI 2 "r")]
19906 "!optimize_size && !TARGET_PUSH_MEMORY
19907 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19908 [(set (match_dup 2) (match_dup 1))
19909 (set (match_dup 0) (match_dup 2))]
19912 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19915 [(set (match_operand:SF 0 "push_operand" "")
19916 (match_operand:SF 1 "memory_operand" ""))
19917 (match_scratch:SF 2 "r")]
19918 "!optimize_size && !TARGET_PUSH_MEMORY
19919 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19920 [(set (match_dup 2) (match_dup 1))
19921 (set (match_dup 0) (match_dup 2))]
19925 [(set (match_operand:HI 0 "push_operand" "")
19926 (match_operand:HI 1 "memory_operand" ""))
19927 (match_scratch:HI 2 "r")]
19928 "!optimize_size && !TARGET_PUSH_MEMORY
19929 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19930 [(set (match_dup 2) (match_dup 1))
19931 (set (match_dup 0) (match_dup 2))]
19935 [(set (match_operand:QI 0 "push_operand" "")
19936 (match_operand:QI 1 "memory_operand" ""))
19937 (match_scratch:QI 2 "q")]
19938 "!optimize_size && !TARGET_PUSH_MEMORY
19939 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19940 [(set (match_dup 2) (match_dup 1))
19941 (set (match_dup 0) (match_dup 2))]
19944 ;; Don't move an immediate directly to memory when the instruction
19947 [(match_scratch:SI 1 "r")
19948 (set (match_operand:SI 0 "memory_operand" "")
19951 && ! TARGET_USE_MOV0
19952 && TARGET_SPLIT_LONG_MOVES
19953 && get_attr_length (insn) >= ix86_cost->large_insn
19954 && peep2_regno_dead_p (0, FLAGS_REG)"
19955 [(parallel [(set (match_dup 1) (const_int 0))
19956 (clobber (reg:CC FLAGS_REG))])
19957 (set (match_dup 0) (match_dup 1))]
19961 [(match_scratch:HI 1 "r")
19962 (set (match_operand:HI 0 "memory_operand" "")
19965 && ! TARGET_USE_MOV0
19966 && TARGET_SPLIT_LONG_MOVES
19967 && get_attr_length (insn) >= ix86_cost->large_insn
19968 && peep2_regno_dead_p (0, FLAGS_REG)"
19969 [(parallel [(set (match_dup 2) (const_int 0))
19970 (clobber (reg:CC FLAGS_REG))])
19971 (set (match_dup 0) (match_dup 1))]
19972 "operands[2] = gen_lowpart (SImode, operands[1]);")
19975 [(match_scratch:QI 1 "q")
19976 (set (match_operand:QI 0 "memory_operand" "")
19979 && ! TARGET_USE_MOV0
19980 && TARGET_SPLIT_LONG_MOVES
19981 && get_attr_length (insn) >= ix86_cost->large_insn
19982 && peep2_regno_dead_p (0, FLAGS_REG)"
19983 [(parallel [(set (match_dup 2) (const_int 0))
19984 (clobber (reg:CC FLAGS_REG))])
19985 (set (match_dup 0) (match_dup 1))]
19986 "operands[2] = gen_lowpart (SImode, operands[1]);")
19989 [(match_scratch:SI 2 "r")
19990 (set (match_operand:SI 0 "memory_operand" "")
19991 (match_operand:SI 1 "immediate_operand" ""))]
19993 && TARGET_SPLIT_LONG_MOVES
19994 && get_attr_length (insn) >= ix86_cost->large_insn"
19995 [(set (match_dup 2) (match_dup 1))
19996 (set (match_dup 0) (match_dup 2))]
20000 [(match_scratch:HI 2 "r")
20001 (set (match_operand:HI 0 "memory_operand" "")
20002 (match_operand:HI 1 "immediate_operand" ""))]
20004 && TARGET_SPLIT_LONG_MOVES
20005 && get_attr_length (insn) >= ix86_cost->large_insn"
20006 [(set (match_dup 2) (match_dup 1))
20007 (set (match_dup 0) (match_dup 2))]
20011 [(match_scratch:QI 2 "q")
20012 (set (match_operand:QI 0 "memory_operand" "")
20013 (match_operand:QI 1 "immediate_operand" ""))]
20015 && TARGET_SPLIT_LONG_MOVES
20016 && get_attr_length (insn) >= ix86_cost->large_insn"
20017 [(set (match_dup 2) (match_dup 1))
20018 (set (match_dup 0) (match_dup 2))]
20021 ;; Don't compare memory with zero, load and use a test instead.
20023 [(set (match_operand 0 "flags_reg_operand" "")
20024 (match_operator 1 "compare_operator"
20025 [(match_operand:SI 2 "memory_operand" "")
20027 (match_scratch:SI 3 "r")]
20028 " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20029 [(set (match_dup 3) (match_dup 2))
20030 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20033 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20034 ;; Don't split NOTs with a displacement operand, because resulting XOR
20035 ;; will not be pairable anyway.
20037 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20038 ;; represented using a modRM byte. The XOR replacement is long decoded,
20039 ;; so this split helps here as well.
20041 ;; Note: Can't do this as a regular split because we can't get proper
20042 ;; lifetime information then.
20045 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20046 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20048 && ((TARGET_NOT_UNPAIRABLE
20049 && (!MEM_P (operands[0])
20050 || !memory_displacement_operand (operands[0], SImode)))
20051 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20052 && peep2_regno_dead_p (0, FLAGS_REG)"
20053 [(parallel [(set (match_dup 0)
20054 (xor:SI (match_dup 1) (const_int -1)))
20055 (clobber (reg:CC FLAGS_REG))])]
20059 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20060 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20062 && ((TARGET_NOT_UNPAIRABLE
20063 && (!MEM_P (operands[0])
20064 || !memory_displacement_operand (operands[0], HImode)))
20065 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20066 && peep2_regno_dead_p (0, FLAGS_REG)"
20067 [(parallel [(set (match_dup 0)
20068 (xor:HI (match_dup 1) (const_int -1)))
20069 (clobber (reg:CC FLAGS_REG))])]
20073 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20074 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20076 && ((TARGET_NOT_UNPAIRABLE
20077 && (!MEM_P (operands[0])
20078 || !memory_displacement_operand (operands[0], QImode)))
20079 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20080 && peep2_regno_dead_p (0, FLAGS_REG)"
20081 [(parallel [(set (match_dup 0)
20082 (xor:QI (match_dup 1) (const_int -1)))
20083 (clobber (reg:CC FLAGS_REG))])]
20086 ;; Non pairable "test imm, reg" instructions can be translated to
20087 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20088 ;; byte opcode instead of two, have a short form for byte operands),
20089 ;; so do it for other CPUs as well. Given that the value was dead,
20090 ;; this should not create any new dependencies. Pass on the sub-word
20091 ;; versions if we're concerned about partial register stalls.
20094 [(set (match_operand 0 "flags_reg_operand" "")
20095 (match_operator 1 "compare_operator"
20096 [(and:SI (match_operand:SI 2 "register_operand" "")
20097 (match_operand:SI 3 "immediate_operand" ""))
20099 "ix86_match_ccmode (insn, CCNOmode)
20100 && (true_regnum (operands[2]) != AX_REG
20101 || satisfies_constraint_K (operands[3]))
20102 && peep2_reg_dead_p (1, operands[2])"
20104 [(set (match_dup 0)
20105 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20108 (and:SI (match_dup 2) (match_dup 3)))])]
20111 ;; We don't need to handle HImode case, because it will be promoted to SImode
20112 ;; on ! TARGET_PARTIAL_REG_STALL
20115 [(set (match_operand 0 "flags_reg_operand" "")
20116 (match_operator 1 "compare_operator"
20117 [(and:QI (match_operand:QI 2 "register_operand" "")
20118 (match_operand:QI 3 "immediate_operand" ""))
20120 "! TARGET_PARTIAL_REG_STALL
20121 && ix86_match_ccmode (insn, CCNOmode)
20122 && true_regnum (operands[2]) != AX_REG
20123 && peep2_reg_dead_p (1, operands[2])"
20125 [(set (match_dup 0)
20126 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20129 (and:QI (match_dup 2) (match_dup 3)))])]
20133 [(set (match_operand 0 "flags_reg_operand" "")
20134 (match_operator 1 "compare_operator"
20137 (match_operand 2 "ext_register_operand" "")
20140 (match_operand 3 "const_int_operand" ""))
20142 "! TARGET_PARTIAL_REG_STALL
20143 && ix86_match_ccmode (insn, CCNOmode)
20144 && true_regnum (operands[2]) != AX_REG
20145 && peep2_reg_dead_p (1, operands[2])"
20146 [(parallel [(set (match_dup 0)
20155 (set (zero_extract:SI (match_dup 2)
20166 ;; Don't do logical operations with memory inputs.
20168 [(match_scratch:SI 2 "r")
20169 (parallel [(set (match_operand:SI 0 "register_operand" "")
20170 (match_operator:SI 3 "arith_or_logical_operator"
20172 (match_operand:SI 1 "memory_operand" "")]))
20173 (clobber (reg:CC FLAGS_REG))])]
20174 "! optimize_size && ! TARGET_READ_MODIFY"
20175 [(set (match_dup 2) (match_dup 1))
20176 (parallel [(set (match_dup 0)
20177 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20178 (clobber (reg:CC FLAGS_REG))])]
20182 [(match_scratch:SI 2 "r")
20183 (parallel [(set (match_operand:SI 0 "register_operand" "")
20184 (match_operator:SI 3 "arith_or_logical_operator"
20185 [(match_operand:SI 1 "memory_operand" "")
20187 (clobber (reg:CC FLAGS_REG))])]
20188 "! optimize_size && ! TARGET_READ_MODIFY"
20189 [(set (match_dup 2) (match_dup 1))
20190 (parallel [(set (match_dup 0)
20191 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20192 (clobber (reg:CC FLAGS_REG))])]
20195 ; Don't do logical operations with memory outputs
20197 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20198 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20199 ; the same decoder scheduling characteristics as the original.
20202 [(match_scratch:SI 2 "r")
20203 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20204 (match_operator:SI 3 "arith_or_logical_operator"
20206 (match_operand:SI 1 "nonmemory_operand" "")]))
20207 (clobber (reg:CC FLAGS_REG))])]
20208 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20209 [(set (match_dup 2) (match_dup 0))
20210 (parallel [(set (match_dup 2)
20211 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20212 (clobber (reg:CC FLAGS_REG))])
20213 (set (match_dup 0) (match_dup 2))]
20217 [(match_scratch:SI 2 "r")
20218 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20219 (match_operator:SI 3 "arith_or_logical_operator"
20220 [(match_operand:SI 1 "nonmemory_operand" "")
20222 (clobber (reg:CC FLAGS_REG))])]
20223 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20224 [(set (match_dup 2) (match_dup 0))
20225 (parallel [(set (match_dup 2)
20226 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20227 (clobber (reg:CC FLAGS_REG))])
20228 (set (match_dup 0) (match_dup 2))]
20231 ;; Attempt to always use XOR for zeroing registers.
20233 [(set (match_operand 0 "register_operand" "")
20234 (match_operand 1 "const0_operand" ""))]
20235 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20236 && (! TARGET_USE_MOV0 || optimize_size)
20237 && GENERAL_REG_P (operands[0])
20238 && peep2_regno_dead_p (0, FLAGS_REG)"
20239 [(parallel [(set (match_dup 0) (const_int 0))
20240 (clobber (reg:CC FLAGS_REG))])]
20242 operands[0] = gen_lowpart (word_mode, operands[0]);
20246 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20248 "(GET_MODE (operands[0]) == QImode
20249 || GET_MODE (operands[0]) == HImode)
20250 && (! TARGET_USE_MOV0 || optimize_size)
20251 && peep2_regno_dead_p (0, FLAGS_REG)"
20252 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20253 (clobber (reg:CC FLAGS_REG))])])
20255 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20257 [(set (match_operand 0 "register_operand" "")
20259 "(GET_MODE (operands[0]) == HImode
20260 || GET_MODE (operands[0]) == SImode
20261 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20262 && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20263 && peep2_regno_dead_p (0, FLAGS_REG)"
20264 [(parallel [(set (match_dup 0) (const_int -1))
20265 (clobber (reg:CC FLAGS_REG))])]
20266 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20269 ;; Attempt to convert simple leas to adds. These can be created by
20272 [(set (match_operand:SI 0 "register_operand" "")
20273 (plus:SI (match_dup 0)
20274 (match_operand:SI 1 "nonmemory_operand" "")))]
20275 "peep2_regno_dead_p (0, FLAGS_REG)"
20276 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20277 (clobber (reg:CC FLAGS_REG))])]
20281 [(set (match_operand:SI 0 "register_operand" "")
20282 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20283 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20284 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20285 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20286 (clobber (reg:CC FLAGS_REG))])]
20287 "operands[2] = gen_lowpart (SImode, operands[2]);")
20290 [(set (match_operand:DI 0 "register_operand" "")
20291 (plus:DI (match_dup 0)
20292 (match_operand:DI 1 "x86_64_general_operand" "")))]
20293 "peep2_regno_dead_p (0, FLAGS_REG)"
20294 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20295 (clobber (reg:CC FLAGS_REG))])]
20299 [(set (match_operand:SI 0 "register_operand" "")
20300 (mult:SI (match_dup 0)
20301 (match_operand:SI 1 "const_int_operand" "")))]
20302 "exact_log2 (INTVAL (operands[1])) >= 0
20303 && peep2_regno_dead_p (0, FLAGS_REG)"
20304 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20305 (clobber (reg:CC FLAGS_REG))])]
20306 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20309 [(set (match_operand:DI 0 "register_operand" "")
20310 (mult:DI (match_dup 0)
20311 (match_operand:DI 1 "const_int_operand" "")))]
20312 "exact_log2 (INTVAL (operands[1])) >= 0
20313 && peep2_regno_dead_p (0, FLAGS_REG)"
20314 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20315 (clobber (reg:CC FLAGS_REG))])]
20316 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20319 [(set (match_operand:SI 0 "register_operand" "")
20320 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20321 (match_operand:DI 2 "const_int_operand" "")) 0))]
20322 "exact_log2 (INTVAL (operands[2])) >= 0
20323 && REGNO (operands[0]) == REGNO (operands[1])
20324 && peep2_regno_dead_p (0, FLAGS_REG)"
20325 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20326 (clobber (reg:CC FLAGS_REG))])]
20327 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20329 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20330 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20331 ;; many CPUs it is also faster, since special hardware to avoid esp
20332 ;; dependencies is present.
20334 ;; While some of these conversions may be done using splitters, we use peepholes
20335 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20337 ;; Convert prologue esp subtractions to push.
20338 ;; We need register to push. In order to keep verify_flow_info happy we have
20340 ;; - use scratch and clobber it in order to avoid dependencies
20341 ;; - use already live register
20342 ;; We can't use the second way right now, since there is no reliable way how to
20343 ;; verify that given register is live. First choice will also most likely in
20344 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20345 ;; call clobbered registers are dead. We may want to use base pointer as an
20346 ;; alternative when no register is available later.
20349 [(match_scratch:SI 0 "r")
20350 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20351 (clobber (reg:CC FLAGS_REG))
20352 (clobber (mem:BLK (scratch)))])]
20353 "optimize_size || !TARGET_SUB_ESP_4"
20354 [(clobber (match_dup 0))
20355 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20356 (clobber (mem:BLK (scratch)))])])
20359 [(match_scratch:SI 0 "r")
20360 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20361 (clobber (reg:CC FLAGS_REG))
20362 (clobber (mem:BLK (scratch)))])]
20363 "optimize_size || !TARGET_SUB_ESP_8"
20364 [(clobber (match_dup 0))
20365 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20366 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20367 (clobber (mem:BLK (scratch)))])])
20369 ;; Convert esp subtractions to push.
20371 [(match_scratch:SI 0 "r")
20372 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20373 (clobber (reg:CC FLAGS_REG))])]
20374 "optimize_size || !TARGET_SUB_ESP_4"
20375 [(clobber (match_dup 0))
20376 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20379 [(match_scratch:SI 0 "r")
20380 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20381 (clobber (reg:CC FLAGS_REG))])]
20382 "optimize_size || !TARGET_SUB_ESP_8"
20383 [(clobber (match_dup 0))
20384 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20385 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20387 ;; Convert epilogue deallocator to pop.
20389 [(match_scratch:SI 0 "r")
20390 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20391 (clobber (reg:CC FLAGS_REG))
20392 (clobber (mem:BLK (scratch)))])]
20393 "optimize_size || !TARGET_ADD_ESP_4"
20394 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20395 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20396 (clobber (mem:BLK (scratch)))])]
20399 ;; Two pops case is tricky, since pop causes dependency on destination register.
20400 ;; We use two registers if available.
20402 [(match_scratch:SI 0 "r")
20403 (match_scratch:SI 1 "r")
20404 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20405 (clobber (reg:CC FLAGS_REG))
20406 (clobber (mem:BLK (scratch)))])]
20407 "optimize_size || !TARGET_ADD_ESP_8"
20408 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20409 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20410 (clobber (mem:BLK (scratch)))])
20411 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20412 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20416 [(match_scratch:SI 0 "r")
20417 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20418 (clobber (reg:CC FLAGS_REG))
20419 (clobber (mem:BLK (scratch)))])]
20421 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20422 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20423 (clobber (mem:BLK (scratch)))])
20424 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20425 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20428 ;; Convert esp additions to pop.
20430 [(match_scratch:SI 0 "r")
20431 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20432 (clobber (reg:CC FLAGS_REG))])]
20434 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20435 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20438 ;; Two pops case is tricky, since pop causes dependency on destination register.
20439 ;; We use two registers if available.
20441 [(match_scratch:SI 0 "r")
20442 (match_scratch:SI 1 "r")
20443 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20444 (clobber (reg:CC FLAGS_REG))])]
20446 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20447 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20448 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20449 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20453 [(match_scratch:SI 0 "r")
20454 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20455 (clobber (reg:CC FLAGS_REG))])]
20457 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20458 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20459 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20460 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20463 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20464 ;; required and register dies. Similarly for 128 to plus -128.
20466 [(set (match_operand 0 "flags_reg_operand" "")
20467 (match_operator 1 "compare_operator"
20468 [(match_operand 2 "register_operand" "")
20469 (match_operand 3 "const_int_operand" "")]))]
20470 "(INTVAL (operands[3]) == -1
20471 || INTVAL (operands[3]) == 1
20472 || INTVAL (operands[3]) == 128)
20473 && ix86_match_ccmode (insn, CCGCmode)
20474 && peep2_reg_dead_p (1, operands[2])"
20475 [(parallel [(set (match_dup 0)
20476 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20477 (clobber (match_dup 2))])]
20481 [(match_scratch:DI 0 "r")
20482 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20483 (clobber (reg:CC FLAGS_REG))
20484 (clobber (mem:BLK (scratch)))])]
20485 "optimize_size || !TARGET_SUB_ESP_4"
20486 [(clobber (match_dup 0))
20487 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20488 (clobber (mem:BLK (scratch)))])])
20491 [(match_scratch:DI 0 "r")
20492 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20493 (clobber (reg:CC FLAGS_REG))
20494 (clobber (mem:BLK (scratch)))])]
20495 "optimize_size || !TARGET_SUB_ESP_8"
20496 [(clobber (match_dup 0))
20497 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20498 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20499 (clobber (mem:BLK (scratch)))])])
20501 ;; Convert esp subtractions to push.
20503 [(match_scratch:DI 0 "r")
20504 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20505 (clobber (reg:CC FLAGS_REG))])]
20506 "optimize_size || !TARGET_SUB_ESP_4"
20507 [(clobber (match_dup 0))
20508 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20511 [(match_scratch:DI 0 "r")
20512 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20513 (clobber (reg:CC FLAGS_REG))])]
20514 "optimize_size || !TARGET_SUB_ESP_8"
20515 [(clobber (match_dup 0))
20516 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20517 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20519 ;; Convert epilogue deallocator to pop.
20521 [(match_scratch:DI 0 "r")
20522 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20523 (clobber (reg:CC FLAGS_REG))
20524 (clobber (mem:BLK (scratch)))])]
20525 "optimize_size || !TARGET_ADD_ESP_4"
20526 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20527 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20528 (clobber (mem:BLK (scratch)))])]
20531 ;; Two pops case is tricky, since pop causes dependency on destination register.
20532 ;; We use two registers if available.
20534 [(match_scratch:DI 0 "r")
20535 (match_scratch:DI 1 "r")
20536 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20537 (clobber (reg:CC FLAGS_REG))
20538 (clobber (mem:BLK (scratch)))])]
20539 "optimize_size || !TARGET_ADD_ESP_8"
20540 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20541 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20542 (clobber (mem:BLK (scratch)))])
20543 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20544 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20548 [(match_scratch:DI 0 "r")
20549 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20550 (clobber (reg:CC FLAGS_REG))
20551 (clobber (mem:BLK (scratch)))])]
20553 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20554 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20555 (clobber (mem:BLK (scratch)))])
20556 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20557 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20560 ;; Convert esp additions to pop.
20562 [(match_scratch:DI 0 "r")
20563 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20564 (clobber (reg:CC FLAGS_REG))])]
20566 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20567 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20570 ;; Two pops case is tricky, since pop causes dependency on destination register.
20571 ;; We use two registers if available.
20573 [(match_scratch:DI 0 "r")
20574 (match_scratch:DI 1 "r")
20575 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20576 (clobber (reg:CC FLAGS_REG))])]
20578 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20579 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20580 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20581 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20585 [(match_scratch:DI 0 "r")
20586 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20587 (clobber (reg:CC FLAGS_REG))])]
20589 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20590 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20591 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20592 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20595 ;; Convert imul by three, five and nine into lea
20598 [(set (match_operand:SI 0 "register_operand" "")
20599 (mult:SI (match_operand:SI 1 "register_operand" "")
20600 (match_operand:SI 2 "const_int_operand" "")))
20601 (clobber (reg:CC FLAGS_REG))])]
20602 "INTVAL (operands[2]) == 3
20603 || INTVAL (operands[2]) == 5
20604 || INTVAL (operands[2]) == 9"
20605 [(set (match_dup 0)
20606 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20608 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20612 [(set (match_operand:SI 0 "register_operand" "")
20613 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20614 (match_operand:SI 2 "const_int_operand" "")))
20615 (clobber (reg:CC FLAGS_REG))])]
20617 && (INTVAL (operands[2]) == 3
20618 || INTVAL (operands[2]) == 5
20619 || INTVAL (operands[2]) == 9)"
20620 [(set (match_dup 0) (match_dup 1))
20622 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20624 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20628 [(set (match_operand:DI 0 "register_operand" "")
20629 (mult:DI (match_operand:DI 1 "register_operand" "")
20630 (match_operand:DI 2 "const_int_operand" "")))
20631 (clobber (reg:CC FLAGS_REG))])]
20633 && (INTVAL (operands[2]) == 3
20634 || INTVAL (operands[2]) == 5
20635 || INTVAL (operands[2]) == 9)"
20636 [(set (match_dup 0)
20637 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20639 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20643 [(set (match_operand:DI 0 "register_operand" "")
20644 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20645 (match_operand:DI 2 "const_int_operand" "")))
20646 (clobber (reg:CC FLAGS_REG))])]
20649 && (INTVAL (operands[2]) == 3
20650 || INTVAL (operands[2]) == 5
20651 || INTVAL (operands[2]) == 9)"
20652 [(set (match_dup 0) (match_dup 1))
20654 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20656 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20658 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20659 ;; imul $32bit_imm, reg, reg is direct decoded.
20661 [(match_scratch:DI 3 "r")
20662 (parallel [(set (match_operand:DI 0 "register_operand" "")
20663 (mult:DI (match_operand:DI 1 "memory_operand" "")
20664 (match_operand:DI 2 "immediate_operand" "")))
20665 (clobber (reg:CC FLAGS_REG))])]
20666 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20667 && !satisfies_constraint_K (operands[2])"
20668 [(set (match_dup 3) (match_dup 1))
20669 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20670 (clobber (reg:CC FLAGS_REG))])]
20674 [(match_scratch:SI 3 "r")
20675 (parallel [(set (match_operand:SI 0 "register_operand" "")
20676 (mult:SI (match_operand:SI 1 "memory_operand" "")
20677 (match_operand:SI 2 "immediate_operand" "")))
20678 (clobber (reg:CC FLAGS_REG))])]
20679 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20680 && !satisfies_constraint_K (operands[2])"
20681 [(set (match_dup 3) (match_dup 1))
20682 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20683 (clobber (reg:CC FLAGS_REG))])]
20687 [(match_scratch:SI 3 "r")
20688 (parallel [(set (match_operand:DI 0 "register_operand" "")
20690 (mult:SI (match_operand:SI 1 "memory_operand" "")
20691 (match_operand:SI 2 "immediate_operand" ""))))
20692 (clobber (reg:CC FLAGS_REG))])]
20693 "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20694 && !satisfies_constraint_K (operands[2])"
20695 [(set (match_dup 3) (match_dup 1))
20696 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20697 (clobber (reg:CC FLAGS_REG))])]
20700 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20701 ;; Convert it into imul reg, reg
20702 ;; It would be better to force assembler to encode instruction using long
20703 ;; immediate, but there is apparently no way to do so.
20705 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20706 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20707 (match_operand:DI 2 "const_int_operand" "")))
20708 (clobber (reg:CC FLAGS_REG))])
20709 (match_scratch:DI 3 "r")]
20710 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20711 && satisfies_constraint_K (operands[2])"
20712 [(set (match_dup 3) (match_dup 2))
20713 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20714 (clobber (reg:CC FLAGS_REG))])]
20716 if (!rtx_equal_p (operands[0], operands[1]))
20717 emit_move_insn (operands[0], operands[1]);
20721 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20722 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20723 (match_operand:SI 2 "const_int_operand" "")))
20724 (clobber (reg:CC FLAGS_REG))])
20725 (match_scratch:SI 3 "r")]
20726 "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20727 && satisfies_constraint_K (operands[2])"
20728 [(set (match_dup 3) (match_dup 2))
20729 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20730 (clobber (reg:CC FLAGS_REG))])]
20732 if (!rtx_equal_p (operands[0], operands[1]))
20733 emit_move_insn (operands[0], operands[1]);
20737 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20738 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20739 (match_operand:HI 2 "immediate_operand" "")))
20740 (clobber (reg:CC FLAGS_REG))])
20741 (match_scratch:HI 3 "r")]
20742 "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20743 [(set (match_dup 3) (match_dup 2))
20744 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20745 (clobber (reg:CC FLAGS_REG))])]
20747 if (!rtx_equal_p (operands[0], operands[1]))
20748 emit_move_insn (operands[0], operands[1]);
20751 ;; After splitting up read-modify operations, array accesses with memory
20752 ;; operands might end up in form:
20754 ;; movl 4(%esp), %edx
20756 ;; instead of pre-splitting:
20758 ;; addl 4(%esp), %eax
20760 ;; movl 4(%esp), %edx
20761 ;; leal (%edx,%eax,4), %eax
20764 [(parallel [(set (match_operand 0 "register_operand" "")
20765 (ashift (match_operand 1 "register_operand" "")
20766 (match_operand 2 "const_int_operand" "")))
20767 (clobber (reg:CC FLAGS_REG))])
20768 (set (match_operand 3 "register_operand")
20769 (match_operand 4 "x86_64_general_operand" ""))
20770 (parallel [(set (match_operand 5 "register_operand" "")
20771 (plus (match_operand 6 "register_operand" "")
20772 (match_operand 7 "register_operand" "")))
20773 (clobber (reg:CC FLAGS_REG))])]
20774 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20775 /* Validate MODE for lea. */
20776 && ((!TARGET_PARTIAL_REG_STALL
20777 && (GET_MODE (operands[0]) == QImode
20778 || GET_MODE (operands[0]) == HImode))
20779 || GET_MODE (operands[0]) == SImode
20780 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20781 /* We reorder load and the shift. */
20782 && !rtx_equal_p (operands[1], operands[3])
20783 && !reg_overlap_mentioned_p (operands[0], operands[4])
20784 /* Last PLUS must consist of operand 0 and 3. */
20785 && !rtx_equal_p (operands[0], operands[3])
20786 && (rtx_equal_p (operands[3], operands[6])
20787 || rtx_equal_p (operands[3], operands[7]))
20788 && (rtx_equal_p (operands[0], operands[6])
20789 || rtx_equal_p (operands[0], operands[7]))
20790 /* The intermediate operand 0 must die or be same as output. */
20791 && (rtx_equal_p (operands[0], operands[5])
20792 || peep2_reg_dead_p (3, operands[0]))"
20793 [(set (match_dup 3) (match_dup 4))
20794 (set (match_dup 0) (match_dup 1))]
20796 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20797 int scale = 1 << INTVAL (operands[2]);
20798 rtx index = gen_lowpart (Pmode, operands[1]);
20799 rtx base = gen_lowpart (Pmode, operands[3]);
20800 rtx dest = gen_lowpart (mode, operands[5]);
20802 operands[1] = gen_rtx_PLUS (Pmode, base,
20803 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20805 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20806 operands[0] = dest;
20809 ;; Call-value patterns last so that the wildcard operand does not
20810 ;; disrupt insn-recog's switch tables.
20812 (define_insn "*call_value_pop_0"
20813 [(set (match_operand 0 "" "")
20814 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20815 (match_operand:SI 2 "" "")))
20816 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20817 (match_operand:SI 3 "immediate_operand" "")))]
20820 if (SIBLING_CALL_P (insn))
20823 return "call\t%P1";
20825 [(set_attr "type" "callv")])
20827 (define_insn "*call_value_pop_1"
20828 [(set (match_operand 0 "" "")
20829 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20830 (match_operand:SI 2 "" "")))
20831 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20832 (match_operand:SI 3 "immediate_operand" "i")))]
20835 if (constant_call_address_operand (operands[1], Pmode))
20837 if (SIBLING_CALL_P (insn))
20840 return "call\t%P1";
20842 if (SIBLING_CALL_P (insn))
20845 return "call\t%A1";
20847 [(set_attr "type" "callv")])
20849 (define_insn "*call_value_0"
20850 [(set (match_operand 0 "" "")
20851 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20852 (match_operand:SI 2 "" "")))]
20855 if (SIBLING_CALL_P (insn))
20858 return "call\t%P1";
20860 [(set_attr "type" "callv")])
20862 (define_insn "*call_value_0_rex64"
20863 [(set (match_operand 0 "" "")
20864 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20865 (match_operand:DI 2 "const_int_operand" "")))]
20868 if (SIBLING_CALL_P (insn))
20871 return "call\t%P1";
20873 [(set_attr "type" "callv")])
20875 (define_insn "*call_value_1"
20876 [(set (match_operand 0 "" "")
20877 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20878 (match_operand:SI 2 "" "")))]
20879 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20881 if (constant_call_address_operand (operands[1], Pmode))
20882 return "call\t%P1";
20883 return "call\t%A1";
20885 [(set_attr "type" "callv")])
20887 (define_insn "*sibcall_value_1"
20888 [(set (match_operand 0 "" "")
20889 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20890 (match_operand:SI 2 "" "")))]
20891 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20893 if (constant_call_address_operand (operands[1], Pmode))
20897 [(set_attr "type" "callv")])
20899 (define_insn "*call_value_1_rex64"
20900 [(set (match_operand 0 "" "")
20901 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20902 (match_operand:DI 2 "" "")))]
20903 "!SIBLING_CALL_P (insn) && TARGET_64BIT
20904 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20906 if (constant_call_address_operand (operands[1], Pmode))
20907 return "call\t%P1";
20908 return "call\t%A1";
20910 [(set_attr "type" "callv")])
20912 (define_insn "*call_value_1_rex64_large"
20913 [(set (match_operand 0 "" "")
20914 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20915 (match_operand:DI 2 "" "")))]
20916 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20918 [(set_attr "type" "callv")])
20920 (define_insn "*sibcall_value_1_rex64"
20921 [(set (match_operand 0 "" "")
20922 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20923 (match_operand:DI 2 "" "")))]
20924 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20926 [(set_attr "type" "callv")])
20928 (define_insn "*sibcall_value_1_rex64_v"
20929 [(set (match_operand 0 "" "")
20930 (call (mem:QI (reg:DI R11_REG))
20931 (match_operand:DI 1 "" "")))]
20932 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20934 [(set_attr "type" "callv")])
20936 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20937 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20938 ;; caught for use by garbage collectors and the like. Using an insn that
20939 ;; maps to SIGILL makes it more likely the program will rightfully die.
20940 ;; Keeping with tradition, "6" is in honor of #UD.
20941 (define_insn "trap"
20942 [(trap_if (const_int 1) (const_int 6))]
20944 { return ASM_SHORT "0x0b0f"; }
20945 [(set_attr "length" "2")])
20947 (define_expand "sse_prologue_save"
20948 [(parallel [(set (match_operand:BLK 0 "" "")
20949 (unspec:BLK [(reg:DI 21)
20956 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20957 (use (match_operand:DI 1 "register_operand" ""))
20958 (use (match_operand:DI 2 "immediate_operand" ""))
20959 (use (label_ref:DI (match_operand 3 "" "")))])]
20963 (define_insn "*sse_prologue_save_insn"
20964 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20965 (match_operand:DI 4 "const_int_operand" "n")))
20966 (unspec:BLK [(reg:DI 21)
20973 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20974 (use (match_operand:DI 1 "register_operand" "r"))
20975 (use (match_operand:DI 2 "const_int_operand" "i"))
20976 (use (label_ref:DI (match_operand 3 "" "X")))]
20978 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20979 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20982 operands[0] = gen_rtx_MEM (Pmode,
20983 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20984 output_asm_insn ("jmp\t%A1", operands);
20985 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20987 operands[4] = adjust_address (operands[0], DImode, i*16);
20988 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20989 PUT_MODE (operands[4], TImode);
20990 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20991 output_asm_insn ("rex", operands);
20992 output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
20994 (*targetm.asm_out.internal_label) (asm_out_file, "L",
20995 CODE_LABEL_NUMBER (operands[3]));
20998 [(set_attr "type" "other")
20999 (set_attr "length_immediate" "0")
21000 (set_attr "length_address" "0")
21001 (set_attr "length" "135")
21002 (set_attr "memory" "store")
21003 (set_attr "modrm" "0")
21004 (set_attr "mode" "DI")])
21006 (define_expand "prefetch"
21007 [(prefetch (match_operand 0 "address_operand" "")
21008 (match_operand:SI 1 "const_int_operand" "")
21009 (match_operand:SI 2 "const_int_operand" ""))]
21010 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21012 int rw = INTVAL (operands[1]);
21013 int locality = INTVAL (operands[2]);
21015 gcc_assert (rw == 0 || rw == 1);
21016 gcc_assert (locality >= 0 && locality <= 3);
21017 gcc_assert (GET_MODE (operands[0]) == Pmode
21018 || GET_MODE (operands[0]) == VOIDmode);
21020 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21021 supported by SSE counterpart or the SSE prefetch is not available
21022 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21024 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21025 operands[2] = GEN_INT (3);
21027 operands[1] = const0_rtx;
21030 (define_insn "*prefetch_sse"
21031 [(prefetch (match_operand:SI 0 "address_operand" "p")
21033 (match_operand:SI 1 "const_int_operand" ""))]
21034 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21036 static const char * const patterns[4] = {
21037 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21040 int locality = INTVAL (operands[1]);
21041 gcc_assert (locality >= 0 && locality <= 3);
21043 return patterns[locality];
21045 [(set_attr "type" "sse")
21046 (set_attr "memory" "none")])
21048 (define_insn "*prefetch_sse_rex"
21049 [(prefetch (match_operand:DI 0 "address_operand" "p")
21051 (match_operand:SI 1 "const_int_operand" ""))]
21052 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21054 static const char * const patterns[4] = {
21055 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21058 int locality = INTVAL (operands[1]);
21059 gcc_assert (locality >= 0 && locality <= 3);
21061 return patterns[locality];
21063 [(set_attr "type" "sse")
21064 (set_attr "memory" "none")])
21066 (define_insn "*prefetch_3dnow"
21067 [(prefetch (match_operand:SI 0 "address_operand" "p")
21068 (match_operand:SI 1 "const_int_operand" "n")
21070 "TARGET_3DNOW && !TARGET_64BIT"
21072 if (INTVAL (operands[1]) == 0)
21073 return "prefetch\t%a0";
21075 return "prefetchw\t%a0";
21077 [(set_attr "type" "mmx")
21078 (set_attr "memory" "none")])
21080 (define_insn "*prefetch_3dnow_rex"
21081 [(prefetch (match_operand:DI 0 "address_operand" "p")
21082 (match_operand:SI 1 "const_int_operand" "n")
21084 "TARGET_3DNOW && TARGET_64BIT"
21086 if (INTVAL (operands[1]) == 0)
21087 return "prefetch\t%a0";
21089 return "prefetchw\t%a0";
21091 [(set_attr "type" "mmx")
21092 (set_attr "memory" "none")])
21094 (define_expand "stack_protect_set"
21095 [(match_operand 0 "memory_operand" "")
21096 (match_operand 1 "memory_operand" "")]
21099 #ifdef TARGET_THREAD_SSP_OFFSET
21101 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21102 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21104 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21105 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21108 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21110 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21115 (define_insn "stack_protect_set_si"
21116 [(set (match_operand:SI 0 "memory_operand" "=m")
21117 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21118 (set (match_scratch:SI 2 "=&r") (const_int 0))
21119 (clobber (reg:CC FLAGS_REG))]
21121 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21122 [(set_attr "type" "multi")])
21124 (define_insn "stack_protect_set_di"
21125 [(set (match_operand:DI 0 "memory_operand" "=m")
21126 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21127 (set (match_scratch:DI 2 "=&r") (const_int 0))
21128 (clobber (reg:CC FLAGS_REG))]
21130 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21131 [(set_attr "type" "multi")])
21133 (define_insn "stack_tls_protect_set_si"
21134 [(set (match_operand:SI 0 "memory_operand" "=m")
21135 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21136 (set (match_scratch:SI 2 "=&r") (const_int 0))
21137 (clobber (reg:CC FLAGS_REG))]
21139 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21140 [(set_attr "type" "multi")])
21142 (define_insn "stack_tls_protect_set_di"
21143 [(set (match_operand:DI 0 "memory_operand" "=m")
21144 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21145 (set (match_scratch:DI 2 "=&r") (const_int 0))
21146 (clobber (reg:CC FLAGS_REG))]
21149 /* The kernel uses a different segment register for performance reasons; a
21150 system call would not have to trash the userspace segment register,
21151 which would be expensive */
21152 if (ix86_cmodel != CM_KERNEL)
21153 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21155 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21157 [(set_attr "type" "multi")])
21159 (define_expand "stack_protect_test"
21160 [(match_operand 0 "memory_operand" "")
21161 (match_operand 1 "memory_operand" "")
21162 (match_operand 2 "" "")]
21165 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21166 ix86_compare_op0 = operands[0];
21167 ix86_compare_op1 = operands[1];
21168 ix86_compare_emitted = flags;
21170 #ifdef TARGET_THREAD_SSP_OFFSET
21172 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21173 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21175 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21176 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21179 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21181 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21183 emit_jump_insn (gen_beq (operands[2]));
21187 (define_insn "stack_protect_test_si"
21188 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21189 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21190 (match_operand:SI 2 "memory_operand" "m")]
21192 (clobber (match_scratch:SI 3 "=&r"))]
21194 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21195 [(set_attr "type" "multi")])
21197 (define_insn "stack_protect_test_di"
21198 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21199 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21200 (match_operand:DI 2 "memory_operand" "m")]
21202 (clobber (match_scratch:DI 3 "=&r"))]
21204 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21205 [(set_attr "type" "multi")])
21207 (define_insn "stack_tls_protect_test_si"
21208 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21209 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21210 (match_operand:SI 2 "const_int_operand" "i")]
21211 UNSPEC_SP_TLS_TEST))
21212 (clobber (match_scratch:SI 3 "=r"))]
21214 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21215 [(set_attr "type" "multi")])
21217 (define_insn "stack_tls_protect_test_di"
21218 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21219 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21220 (match_operand:DI 2 "const_int_operand" "i")]
21221 UNSPEC_SP_TLS_TEST))
21222 (clobber (match_scratch:DI 3 "=r"))]
21225 /* The kernel uses a different segment register for performance reasons; a
21226 system call would not have to trash the userspace segment register,
21227 which would be expensive */
21228 if (ix86_cmodel != CM_KERNEL)
21229 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21231 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21233 [(set_attr "type" "multi")])
21235 (define_mode_iterator CRC32MODE [QI HI SI])
21236 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21237 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21239 (define_insn "sse4_2_crc32<mode>"
21240 [(set (match_operand:SI 0 "register_operand" "=r")
21242 [(match_operand:SI 1 "register_operand" "0")
21243 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21246 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21247 [(set_attr "type" "sselog1")
21248 (set_attr "prefix_rep" "1")
21249 (set_attr "prefix_extra" "1")
21250 (set_attr "mode" "SI")])
21252 (define_insn "sse4_2_crc32di"
21253 [(set (match_operand:DI 0 "register_operand" "=r")
21255 [(match_operand:DI 1 "register_operand" "0")
21256 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21258 "TARGET_SSE4_2 && TARGET_64BIT"
21259 "crc32q\t{%2, %0|%0, %2}"
21260 [(set_attr "type" "sselog1")
21261 (set_attr "prefix_rep" "1")
21262 (set_attr "prefix_extra" "1")
21263 (set_attr "mode" "DI")])
21267 (include "sync.md")