1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, 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 COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 29)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 30)
99 (UNSPEC_NOP 38) ; prevents combiner cleverness
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
128 (UNSPEC_FRNDINT_FLOOR 70)
129 (UNSPEC_FRNDINT_CEIL 71)
130 (UNSPEC_FRNDINT_TRUNC 72)
131 (UNSPEC_FRNDINT_MASK_PM 73)
132 (UNSPEC_FIST_FLOOR 74)
133 (UNSPEC_FIST_CEIL 75)
135 ; x87 Double output FP
136 (UNSPEC_SINCOS_COS 80)
137 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
161 (UNSPEC_INSERTQI 132)
166 [(UNSPECV_BLOCKAGE 0)
167 (UNSPECV_STACK_PROBE 1)
176 (UNSPECV_CMPXCHG_1 10)
177 (UNSPECV_CMPXCHG_2 11)
182 ;; Registers by name.
193 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
196 ;; In C guard expressions, put expressions which may be compile-time
197 ;; constants first. This allows for better optimization. For
198 ;; example, write "TARGET_64BIT && reload_completed", not
199 ;; "reload_completed && TARGET_64BIT".
202 ;; Processor type. This attribute must exactly match the processor_type
203 ;; enumeration in i386.h.
204 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
205 nocona,core2,generic32,generic64,amdfam10"
206 (const (symbol_ref "ix86_tune")))
208 ;; A basic instruction type. Refinements due to arguments to be
209 ;; provided in other attributes.
212 alu,alu1,negnot,imov,imovx,lea,
213 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
214 icmp,test,ibr,setcc,icmov,
215 push,pop,call,callv,leave,
217 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
218 sselog,sselog1,sseiadd,sseishft,sseimul,
219 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
220 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
221 (const_string "other"))
223 ;; Main data type used by the insn
225 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
226 (const_string "unknown"))
228 ;; The CPU unit operations uses.
229 (define_attr "unit" "integer,i387,sse,mmx,unknown"
230 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
231 (const_string "i387")
232 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
233 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
235 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
237 (eq_attr "type" "other")
238 (const_string "unknown")]
239 (const_string "integer")))
241 ;; The (bounding maximum) length of an instruction immediate.
242 (define_attr "length_immediate" ""
243 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
246 (eq_attr "unit" "i387,sse,mmx")
248 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
250 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
251 (eq_attr "type" "imov,test")
252 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
253 (eq_attr "type" "call")
254 (if_then_else (match_operand 0 "constant_call_address_operand" "")
257 (eq_attr "type" "callv")
258 (if_then_else (match_operand 1 "constant_call_address_operand" "")
261 ;; We don't know the size before shorten_branches. Expect
262 ;; the instruction to fit for better scheduling.
263 (eq_attr "type" "ibr")
266 (symbol_ref "/* Update immediate_length and other attributes! */
267 gcc_unreachable (),1")))
269 ;; The (bounding maximum) length of an instruction address.
270 (define_attr "length_address" ""
271 (cond [(eq_attr "type" "str,other,multi,fxch")
273 (and (eq_attr "type" "call")
274 (match_operand 0 "constant_call_address_operand" ""))
276 (and (eq_attr "type" "callv")
277 (match_operand 1 "constant_call_address_operand" ""))
280 (symbol_ref "ix86_attr_length_address_default (insn)")))
282 ;; Set when length prefix is used.
283 (define_attr "prefix_data16" ""
284 (if_then_else (ior (eq_attr "mode" "HI")
285 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
289 ;; Set when string REP prefix is used.
290 (define_attr "prefix_rep" ""
291 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
295 ;; Set when 0f opcode prefix is used.
296 (define_attr "prefix_0f" ""
298 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
299 (eq_attr "unit" "sse,mmx"))
303 ;; Set when REX opcode prefix is used.
304 (define_attr "prefix_rex" ""
305 (cond [(and (eq_attr "mode" "DI")
306 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
308 (and (eq_attr "mode" "QI")
309 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
312 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
318 ;; Set when modrm byte is used.
319 (define_attr "modrm" ""
320 (cond [(eq_attr "type" "str,leave")
322 (eq_attr "unit" "i387")
324 (and (eq_attr "type" "incdec")
325 (ior (match_operand:SI 1 "register_operand" "")
326 (match_operand:HI 1 "register_operand" "")))
328 (and (eq_attr "type" "push")
329 (not (match_operand 1 "memory_operand" "")))
331 (and (eq_attr "type" "pop")
332 (not (match_operand 0 "memory_operand" "")))
334 (and (eq_attr "type" "imov")
335 (ior (and (match_operand 0 "register_operand" "")
336 (match_operand 1 "immediate_operand" ""))
337 (ior (and (match_operand 0 "ax_reg_operand" "")
338 (match_operand 1 "memory_displacement_only_operand" ""))
339 (and (match_operand 0 "memory_displacement_only_operand" "")
340 (match_operand 1 "ax_reg_operand" "")))))
342 (and (eq_attr "type" "call")
343 (match_operand 0 "constant_call_address_operand" ""))
345 (and (eq_attr "type" "callv")
346 (match_operand 1 "constant_call_address_operand" ""))
351 ;; The (bounding maximum) length of an instruction in bytes.
352 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
353 ;; Later we may want to split them and compute proper length as for
355 (define_attr "length" ""
356 (cond [(eq_attr "type" "other,multi,fistp,frndint")
358 (eq_attr "type" "fcmp")
360 (eq_attr "unit" "i387")
362 (plus (attr "prefix_data16")
363 (attr "length_address")))]
364 (plus (plus (attr "modrm")
365 (plus (attr "prefix_0f")
366 (plus (attr "prefix_rex")
368 (plus (attr "prefix_rep")
369 (plus (attr "prefix_data16")
370 (plus (attr "length_immediate")
371 (attr "length_address")))))))
373 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
374 ;; `store' if there is a simple memory reference therein, or `unknown'
375 ;; if the instruction is complex.
377 (define_attr "memory" "none,load,store,both,unknown"
378 (cond [(eq_attr "type" "other,multi,str")
379 (const_string "unknown")
380 (eq_attr "type" "lea,fcmov,fpspc")
381 (const_string "none")
382 (eq_attr "type" "fistp,leave")
383 (const_string "both")
384 (eq_attr "type" "frndint")
385 (const_string "load")
386 (eq_attr "type" "push")
387 (if_then_else (match_operand 1 "memory_operand" "")
388 (const_string "both")
389 (const_string "store"))
390 (eq_attr "type" "pop")
391 (if_then_else (match_operand 0 "memory_operand" "")
392 (const_string "both")
393 (const_string "load"))
394 (eq_attr "type" "setcc")
395 (if_then_else (match_operand 0 "memory_operand" "")
396 (const_string "store")
397 (const_string "none"))
398 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
399 (if_then_else (ior (match_operand 0 "memory_operand" "")
400 (match_operand 1 "memory_operand" ""))
401 (const_string "load")
402 (const_string "none"))
403 (eq_attr "type" "ibr")
404 (if_then_else (match_operand 0 "memory_operand" "")
405 (const_string "load")
406 (const_string "none"))
407 (eq_attr "type" "call")
408 (if_then_else (match_operand 0 "constant_call_address_operand" "")
409 (const_string "none")
410 (const_string "load"))
411 (eq_attr "type" "callv")
412 (if_then_else (match_operand 1 "constant_call_address_operand" "")
413 (const_string "none")
414 (const_string "load"))
415 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
416 (match_operand 1 "memory_operand" ""))
417 (const_string "both")
418 (and (match_operand 0 "memory_operand" "")
419 (match_operand 1 "memory_operand" ""))
420 (const_string "both")
421 (match_operand 0 "memory_operand" "")
422 (const_string "store")
423 (match_operand 1 "memory_operand" "")
424 (const_string "load")
426 "!alu1,negnot,ishift1,
427 imov,imovx,icmp,test,bitmanip,
429 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
430 mmx,mmxmov,mmxcmp,mmxcvt")
431 (match_operand 2 "memory_operand" ""))
432 (const_string "load")
433 (and (eq_attr "type" "icmov")
434 (match_operand 3 "memory_operand" ""))
435 (const_string "load")
437 (const_string "none")))
439 ;; Indicates if an instruction has both an immediate and a displacement.
441 (define_attr "imm_disp" "false,true,unknown"
442 (cond [(eq_attr "type" "other,multi")
443 (const_string "unknown")
444 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
445 (and (match_operand 0 "memory_displacement_operand" "")
446 (match_operand 1 "immediate_operand" "")))
447 (const_string "true")
448 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
449 (and (match_operand 0 "memory_displacement_operand" "")
450 (match_operand 2 "immediate_operand" "")))
451 (const_string "true")
453 (const_string "false")))
455 ;; Indicates if an FP operation has an integer source.
457 (define_attr "fp_int_src" "false,true"
458 (const_string "false"))
460 ;; Defines rounding mode of an FP operation.
462 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
463 (const_string "any"))
465 ;; Describe a user's asm statement.
466 (define_asm_attributes
467 [(set_attr "length" "128")
468 (set_attr "type" "multi")])
470 ;; All x87 floating point modes
471 (define_mode_macro X87MODEF [SF DF XF])
473 ;; x87 SFmode and DFMode floating point modes
474 (define_mode_macro X87MODEF12 [SF DF])
476 ;; All integer modes handled by x87 fisttp operator.
477 (define_mode_macro X87MODEI [HI SI DI])
479 ;; All integer modes handled by integer x87 operators.
480 (define_mode_macro X87MODEI12 [HI SI])
482 ;; All SSE floating point modes
483 (define_mode_macro SSEMODEF [SF DF])
485 ;; All integer modes handled by SSE cvtts?2si* operators.
486 (define_mode_macro SSEMODEI24 [SI DI])
488 ;; SSE asm suffix for floating point modes
489 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
491 ;; SSE vector mode corresponding to a scalar mode
492 (define_mode_attr ssevecmode
493 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
495 ;; Scheduling descriptions
497 (include "pentium.md")
500 (include "athlon.md")
504 ;; Operand and operator predicates and constraints
506 (include "predicates.md")
507 (include "constraints.md")
510 ;; Compare instructions.
512 ;; All compare insns have expanders that save the operands away without
513 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
514 ;; after the cmp) will actually emit the cmpM.
516 (define_expand "cmpti"
517 [(set (reg:CC FLAGS_REG)
518 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
519 (match_operand:TI 1 "x86_64_general_operand" "")))]
522 if (MEM_P (operands[0]) && MEM_P (operands[1]))
523 operands[0] = force_reg (TImode, operands[0]);
524 ix86_compare_op0 = operands[0];
525 ix86_compare_op1 = operands[1];
529 (define_expand "cmpdi"
530 [(set (reg:CC FLAGS_REG)
531 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
532 (match_operand:DI 1 "x86_64_general_operand" "")))]
535 if (MEM_P (operands[0]) && MEM_P (operands[1]))
536 operands[0] = force_reg (DImode, operands[0]);
537 ix86_compare_op0 = operands[0];
538 ix86_compare_op1 = operands[1];
542 (define_expand "cmpsi"
543 [(set (reg:CC FLAGS_REG)
544 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
545 (match_operand:SI 1 "general_operand" "")))]
548 if (MEM_P (operands[0]) && MEM_P (operands[1]))
549 operands[0] = force_reg (SImode, operands[0]);
550 ix86_compare_op0 = operands[0];
551 ix86_compare_op1 = operands[1];
555 (define_expand "cmphi"
556 [(set (reg:CC FLAGS_REG)
557 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
558 (match_operand:HI 1 "general_operand" "")))]
561 if (MEM_P (operands[0]) && MEM_P (operands[1]))
562 operands[0] = force_reg (HImode, operands[0]);
563 ix86_compare_op0 = operands[0];
564 ix86_compare_op1 = operands[1];
568 (define_expand "cmpqi"
569 [(set (reg:CC FLAGS_REG)
570 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
571 (match_operand:QI 1 "general_operand" "")))]
574 if (MEM_P (operands[0]) && MEM_P (operands[1]))
575 operands[0] = force_reg (QImode, operands[0]);
576 ix86_compare_op0 = operands[0];
577 ix86_compare_op1 = operands[1];
581 (define_insn "cmpdi_ccno_1_rex64"
582 [(set (reg FLAGS_REG)
583 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
584 (match_operand:DI 1 "const0_operand" "n,n")))]
585 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
588 cmp{q}\t{%1, %0|%0, %1}"
589 [(set_attr "type" "test,icmp")
590 (set_attr "length_immediate" "0,1")
591 (set_attr "mode" "DI")])
593 (define_insn "*cmpdi_minus_1_rex64"
594 [(set (reg FLAGS_REG)
595 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
596 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
598 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
599 "cmp{q}\t{%1, %0|%0, %1}"
600 [(set_attr "type" "icmp")
601 (set_attr "mode" "DI")])
603 (define_expand "cmpdi_1_rex64"
604 [(set (reg:CC FLAGS_REG)
605 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
606 (match_operand:DI 1 "general_operand" "")))]
610 (define_insn "cmpdi_1_insn_rex64"
611 [(set (reg FLAGS_REG)
612 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
613 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
614 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
615 "cmp{q}\t{%1, %0|%0, %1}"
616 [(set_attr "type" "icmp")
617 (set_attr "mode" "DI")])
620 (define_insn "*cmpsi_ccno_1"
621 [(set (reg FLAGS_REG)
622 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
623 (match_operand:SI 1 "const0_operand" "n,n")))]
624 "ix86_match_ccmode (insn, CCNOmode)"
627 cmp{l}\t{%1, %0|%0, %1}"
628 [(set_attr "type" "test,icmp")
629 (set_attr "length_immediate" "0,1")
630 (set_attr "mode" "SI")])
632 (define_insn "*cmpsi_minus_1"
633 [(set (reg FLAGS_REG)
634 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
635 (match_operand:SI 1 "general_operand" "ri,mr"))
637 "ix86_match_ccmode (insn, CCGOCmode)"
638 "cmp{l}\t{%1, %0|%0, %1}"
639 [(set_attr "type" "icmp")
640 (set_attr "mode" "SI")])
642 (define_expand "cmpsi_1"
643 [(set (reg:CC FLAGS_REG)
644 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
645 (match_operand:SI 1 "general_operand" "ri,mr")))]
649 (define_insn "*cmpsi_1_insn"
650 [(set (reg FLAGS_REG)
651 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
652 (match_operand:SI 1 "general_operand" "ri,mr")))]
653 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
654 && ix86_match_ccmode (insn, CCmode)"
655 "cmp{l}\t{%1, %0|%0, %1}"
656 [(set_attr "type" "icmp")
657 (set_attr "mode" "SI")])
659 (define_insn "*cmphi_ccno_1"
660 [(set (reg FLAGS_REG)
661 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
662 (match_operand:HI 1 "const0_operand" "n,n")))]
663 "ix86_match_ccmode (insn, CCNOmode)"
666 cmp{w}\t{%1, %0|%0, %1}"
667 [(set_attr "type" "test,icmp")
668 (set_attr "length_immediate" "0,1")
669 (set_attr "mode" "HI")])
671 (define_insn "*cmphi_minus_1"
672 [(set (reg FLAGS_REG)
673 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
674 (match_operand:HI 1 "general_operand" "ri,mr"))
676 "ix86_match_ccmode (insn, CCGOCmode)"
677 "cmp{w}\t{%1, %0|%0, %1}"
678 [(set_attr "type" "icmp")
679 (set_attr "mode" "HI")])
681 (define_insn "*cmphi_1"
682 [(set (reg FLAGS_REG)
683 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
684 (match_operand:HI 1 "general_operand" "ri,mr")))]
685 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
686 && ix86_match_ccmode (insn, CCmode)"
687 "cmp{w}\t{%1, %0|%0, %1}"
688 [(set_attr "type" "icmp")
689 (set_attr "mode" "HI")])
691 (define_insn "*cmpqi_ccno_1"
692 [(set (reg FLAGS_REG)
693 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
694 (match_operand:QI 1 "const0_operand" "n,n")))]
695 "ix86_match_ccmode (insn, CCNOmode)"
698 cmp{b}\t{$0, %0|%0, 0}"
699 [(set_attr "type" "test,icmp")
700 (set_attr "length_immediate" "0,1")
701 (set_attr "mode" "QI")])
703 (define_insn "*cmpqi_1"
704 [(set (reg FLAGS_REG)
705 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
706 (match_operand:QI 1 "general_operand" "qi,mq")))]
707 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
708 && ix86_match_ccmode (insn, CCmode)"
709 "cmp{b}\t{%1, %0|%0, %1}"
710 [(set_attr "type" "icmp")
711 (set_attr "mode" "QI")])
713 (define_insn "*cmpqi_minus_1"
714 [(set (reg FLAGS_REG)
715 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
716 (match_operand:QI 1 "general_operand" "qi,mq"))
718 "ix86_match_ccmode (insn, CCGOCmode)"
719 "cmp{b}\t{%1, %0|%0, %1}"
720 [(set_attr "type" "icmp")
721 (set_attr "mode" "QI")])
723 (define_insn "*cmpqi_ext_1"
724 [(set (reg FLAGS_REG)
726 (match_operand:QI 0 "general_operand" "Qm")
729 (match_operand 1 "ext_register_operand" "Q")
732 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
733 "cmp{b}\t{%h1, %0|%0, %h1}"
734 [(set_attr "type" "icmp")
735 (set_attr "mode" "QI")])
737 (define_insn "*cmpqi_ext_1_rex64"
738 [(set (reg FLAGS_REG)
740 (match_operand:QI 0 "register_operand" "Q")
743 (match_operand 1 "ext_register_operand" "Q")
746 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
747 "cmp{b}\t{%h1, %0|%0, %h1}"
748 [(set_attr "type" "icmp")
749 (set_attr "mode" "QI")])
751 (define_insn "*cmpqi_ext_2"
752 [(set (reg FLAGS_REG)
756 (match_operand 0 "ext_register_operand" "Q")
759 (match_operand:QI 1 "const0_operand" "n")))]
760 "ix86_match_ccmode (insn, CCNOmode)"
762 [(set_attr "type" "test")
763 (set_attr "length_immediate" "0")
764 (set_attr "mode" "QI")])
766 (define_expand "cmpqi_ext_3"
767 [(set (reg:CC FLAGS_REG)
771 (match_operand 0 "ext_register_operand" "")
774 (match_operand:QI 1 "general_operand" "")))]
778 (define_insn "cmpqi_ext_3_insn"
779 [(set (reg FLAGS_REG)
783 (match_operand 0 "ext_register_operand" "Q")
786 (match_operand:QI 1 "general_operand" "Qmn")))]
787 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
788 "cmp{b}\t{%1, %h0|%h0, %1}"
789 [(set_attr "type" "icmp")
790 (set_attr "mode" "QI")])
792 (define_insn "cmpqi_ext_3_insn_rex64"
793 [(set (reg FLAGS_REG)
797 (match_operand 0 "ext_register_operand" "Q")
800 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
801 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
802 "cmp{b}\t{%1, %h0|%h0, %1}"
803 [(set_attr "type" "icmp")
804 (set_attr "mode" "QI")])
806 (define_insn "*cmpqi_ext_4"
807 [(set (reg FLAGS_REG)
811 (match_operand 0 "ext_register_operand" "Q")
816 (match_operand 1 "ext_register_operand" "Q")
819 "ix86_match_ccmode (insn, CCmode)"
820 "cmp{b}\t{%h1, %h0|%h0, %h1}"
821 [(set_attr "type" "icmp")
822 (set_attr "mode" "QI")])
824 ;; These implement float point compares.
825 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
826 ;; which would allow mix and match FP modes on the compares. Which is what
827 ;; the old patterns did, but with many more of them.
829 (define_expand "cmpxf"
830 [(set (reg:CC FLAGS_REG)
831 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
832 (match_operand:XF 1 "nonmemory_operand" "")))]
835 ix86_compare_op0 = operands[0];
836 ix86_compare_op1 = operands[1];
840 (define_expand "cmpdf"
841 [(set (reg:CC FLAGS_REG)
842 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
843 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
844 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
846 ix86_compare_op0 = operands[0];
847 ix86_compare_op1 = operands[1];
851 (define_expand "cmpsf"
852 [(set (reg:CC FLAGS_REG)
853 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
854 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
855 "TARGET_80387 || TARGET_SSE_MATH"
857 ix86_compare_op0 = operands[0];
858 ix86_compare_op1 = operands[1];
862 ;; FP compares, step 1:
863 ;; Set the FP condition codes.
865 ;; CCFPmode compare with exceptions
866 ;; CCFPUmode compare with no exceptions
868 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
869 ;; used to manage the reg stack popping would not be preserved.
871 (define_insn "*cmpfp_0"
872 [(set (match_operand:HI 0 "register_operand" "=a")
875 (match_operand 1 "register_operand" "f")
876 (match_operand 2 "const0_operand" "X"))]
879 && FLOAT_MODE_P (GET_MODE (operands[1]))
880 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
881 "* return output_fp_compare (insn, operands, 0, 0);"
882 [(set_attr "type" "multi")
883 (set_attr "unit" "i387")
885 (cond [(match_operand:SF 1 "" "")
887 (match_operand:DF 1 "" "")
890 (const_string "XF")))])
892 (define_insn "*cmpfp_sf"
893 [(set (match_operand:HI 0 "register_operand" "=a")
896 (match_operand:SF 1 "register_operand" "f")
897 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
900 "* return output_fp_compare (insn, operands, 0, 0);"
901 [(set_attr "type" "multi")
902 (set_attr "unit" "i387")
903 (set_attr "mode" "SF")])
905 (define_insn "*cmpfp_df"
906 [(set (match_operand:HI 0 "register_operand" "=a")
909 (match_operand:DF 1 "register_operand" "f")
910 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
913 "* return output_fp_compare (insn, operands, 0, 0);"
914 [(set_attr "type" "multi")
915 (set_attr "unit" "i387")
916 (set_attr "mode" "DF")])
918 (define_insn "*cmpfp_xf"
919 [(set (match_operand:HI 0 "register_operand" "=a")
922 (match_operand:XF 1 "register_operand" "f")
923 (match_operand:XF 2 "register_operand" "f"))]
926 "* return output_fp_compare (insn, operands, 0, 0);"
927 [(set_attr "type" "multi")
928 (set_attr "unit" "i387")
929 (set_attr "mode" "XF")])
931 (define_insn "*cmpfp_u"
932 [(set (match_operand:HI 0 "register_operand" "=a")
935 (match_operand 1 "register_operand" "f")
936 (match_operand 2 "register_operand" "f"))]
939 && FLOAT_MODE_P (GET_MODE (operands[1]))
940 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
941 "* return output_fp_compare (insn, operands, 0, 1);"
942 [(set_attr "type" "multi")
943 (set_attr "unit" "i387")
945 (cond [(match_operand:SF 1 "" "")
947 (match_operand:DF 1 "" "")
950 (const_string "XF")))])
952 (define_insn "*cmpfp_<mode>"
953 [(set (match_operand:HI 0 "register_operand" "=a")
956 (match_operand 1 "register_operand" "f")
957 (match_operator 3 "float_operator"
958 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
960 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
961 && FLOAT_MODE_P (GET_MODE (operands[1]))
962 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
963 "* return output_fp_compare (insn, operands, 0, 0);"
964 [(set_attr "type" "multi")
965 (set_attr "unit" "i387")
966 (set_attr "fp_int_src" "true")
967 (set_attr "mode" "<MODE>")])
969 ;; FP compares, step 2
970 ;; Move the fpsw to ax.
972 (define_insn "x86_fnstsw_1"
973 [(set (match_operand:HI 0 "register_operand" "=a")
974 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
977 [(set_attr "length" "2")
978 (set_attr "mode" "SI")
979 (set_attr "unit" "i387")])
981 ;; FP compares, step 3
982 ;; Get ax into flags, general case.
984 (define_insn "x86_sahf_1"
985 [(set (reg:CC FLAGS_REG)
986 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
989 [(set_attr "length" "1")
990 (set_attr "athlon_decode" "vector")
991 (set_attr "amdfam10_decode" "direct")
992 (set_attr "mode" "SI")])
994 ;; Pentium Pro can do steps 1 through 3 in one go.
995 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
996 (define_insn "*cmpfp_i_mixed"
997 [(set (reg:CCFP FLAGS_REG)
998 (compare:CCFP (match_operand 0 "register_operand" "f,x")
999 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1000 "TARGET_MIX_SSE_I387
1001 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1003 "* return output_fp_compare (insn, operands, 1, 0);"
1004 [(set_attr "type" "fcmp,ssecomi")
1006 (if_then_else (match_operand:SF 1 "" "")
1008 (const_string "DF")))
1009 (set_attr "athlon_decode" "vector")
1010 (set_attr "amdfam10_decode" "direct")])
1012 (define_insn "*cmpfp_i_sse"
1013 [(set (reg:CCFP FLAGS_REG)
1014 (compare:CCFP (match_operand 0 "register_operand" "x")
1015 (match_operand 1 "nonimmediate_operand" "xm")))]
1017 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1018 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1019 "* return output_fp_compare (insn, operands, 1, 0);"
1020 [(set_attr "type" "ssecomi")
1022 (if_then_else (match_operand:SF 1 "" "")
1024 (const_string "DF")))
1025 (set_attr "athlon_decode" "vector")
1026 (set_attr "amdfam10_decode" "direct")])
1028 (define_insn "*cmpfp_i_i387"
1029 [(set (reg:CCFP FLAGS_REG)
1030 (compare:CCFP (match_operand 0 "register_operand" "f")
1031 (match_operand 1 "register_operand" "f")))]
1032 "TARGET_80387 && TARGET_CMOVE
1033 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1034 && FLOAT_MODE_P (GET_MODE (operands[0]))
1035 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1036 "* return output_fp_compare (insn, operands, 1, 0);"
1037 [(set_attr "type" "fcmp")
1039 (cond [(match_operand:SF 1 "" "")
1041 (match_operand:DF 1 "" "")
1044 (const_string "XF")))
1045 (set_attr "athlon_decode" "vector")
1046 (set_attr "amdfam10_decode" "direct")])
1048 (define_insn "*cmpfp_iu_mixed"
1049 [(set (reg:CCFPU FLAGS_REG)
1050 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1051 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1052 "TARGET_MIX_SSE_I387
1053 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1054 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055 "* return output_fp_compare (insn, operands, 1, 1);"
1056 [(set_attr "type" "fcmp,ssecomi")
1058 (if_then_else (match_operand:SF 1 "" "")
1060 (const_string "DF")))
1061 (set_attr "athlon_decode" "vector")
1062 (set_attr "amdfam10_decode" "direct")])
1064 (define_insn "*cmpfp_iu_sse"
1065 [(set (reg:CCFPU FLAGS_REG)
1066 (compare:CCFPU (match_operand 0 "register_operand" "x")
1067 (match_operand 1 "nonimmediate_operand" "xm")))]
1069 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1070 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1071 "* return output_fp_compare (insn, operands, 1, 1);"
1072 [(set_attr "type" "ssecomi")
1074 (if_then_else (match_operand:SF 1 "" "")
1076 (const_string "DF")))
1077 (set_attr "athlon_decode" "vector")
1078 (set_attr "amdfam10_decode" "direct")])
1080 (define_insn "*cmpfp_iu_387"
1081 [(set (reg:CCFPU FLAGS_REG)
1082 (compare:CCFPU (match_operand 0 "register_operand" "f")
1083 (match_operand 1 "register_operand" "f")))]
1084 "TARGET_80387 && TARGET_CMOVE
1085 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1086 && FLOAT_MODE_P (GET_MODE (operands[0]))
1087 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1088 "* return output_fp_compare (insn, operands, 1, 1);"
1089 [(set_attr "type" "fcmp")
1091 (cond [(match_operand:SF 1 "" "")
1093 (match_operand:DF 1 "" "")
1096 (const_string "XF")))
1097 (set_attr "athlon_decode" "vector")
1098 (set_attr "amdfam10_decode" "direct")])
1100 ;; Move instructions.
1102 ;; General case of fullword move.
1104 (define_expand "movsi"
1105 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1106 (match_operand:SI 1 "general_operand" ""))]
1108 "ix86_expand_move (SImode, operands); DONE;")
1110 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1113 ;; %%% We don't use a post-inc memory reference because x86 is not a
1114 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1115 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1116 ;; targets without our curiosities, and it is just as easy to represent
1117 ;; this differently.
1119 (define_insn "*pushsi2"
1120 [(set (match_operand:SI 0 "push_operand" "=<")
1121 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1124 [(set_attr "type" "push")
1125 (set_attr "mode" "SI")])
1127 ;; For 64BIT abi we always round up to 8 bytes.
1128 (define_insn "*pushsi2_rex64"
1129 [(set (match_operand:SI 0 "push_operand" "=X")
1130 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1133 [(set_attr "type" "push")
1134 (set_attr "mode" "SI")])
1136 (define_insn "*pushsi2_prologue"
1137 [(set (match_operand:SI 0 "push_operand" "=<")
1138 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1139 (clobber (mem:BLK (scratch)))]
1142 [(set_attr "type" "push")
1143 (set_attr "mode" "SI")])
1145 (define_insn "*popsi1_epilogue"
1146 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1147 (mem:SI (reg:SI SP_REG)))
1148 (set (reg:SI SP_REG)
1149 (plus:SI (reg:SI SP_REG) (const_int 4)))
1150 (clobber (mem:BLK (scratch)))]
1153 [(set_attr "type" "pop")
1154 (set_attr "mode" "SI")])
1156 (define_insn "popsi1"
1157 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1158 (mem:SI (reg:SI SP_REG)))
1159 (set (reg:SI SP_REG)
1160 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1163 [(set_attr "type" "pop")
1164 (set_attr "mode" "SI")])
1166 (define_insn "*movsi_xor"
1167 [(set (match_operand:SI 0 "register_operand" "=r")
1168 (match_operand:SI 1 "const0_operand" "i"))
1169 (clobber (reg:CC FLAGS_REG))]
1170 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1172 [(set_attr "type" "alu1")
1173 (set_attr "mode" "SI")
1174 (set_attr "length_immediate" "0")])
1176 (define_insn "*movsi_or"
1177 [(set (match_operand:SI 0 "register_operand" "=r")
1178 (match_operand:SI 1 "immediate_operand" "i"))
1179 (clobber (reg:CC FLAGS_REG))]
1181 && operands[1] == constm1_rtx
1182 && (TARGET_PENTIUM || optimize_size)"
1184 operands[1] = constm1_rtx;
1185 return "or{l}\t{%1, %0|%0, %1}";
1187 [(set_attr "type" "alu1")
1188 (set_attr "mode" "SI")
1189 (set_attr "length_immediate" "1")])
1191 (define_insn "*movsi_1"
1192 [(set (match_operand:SI 0 "nonimmediate_operand"
1193 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1194 (match_operand:SI 1 "general_operand"
1195 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1196 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1198 switch (get_attr_type (insn))
1201 if (get_attr_mode (insn) == MODE_TI)
1202 return "pxor\t%0, %0";
1203 return "xorps\t%0, %0";
1206 switch (get_attr_mode (insn))
1209 return "movdqa\t{%1, %0|%0, %1}";
1211 return "movaps\t{%1, %0|%0, %1}";
1213 return "movd\t{%1, %0|%0, %1}";
1215 return "movss\t{%1, %0|%0, %1}";
1221 return "pxor\t%0, %0";
1224 if (get_attr_mode (insn) == MODE_DI)
1225 return "movq\t{%1, %0|%0, %1}";
1226 return "movd\t{%1, %0|%0, %1}";
1229 return "lea{l}\t{%1, %0|%0, %1}";
1232 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1233 return "mov{l}\t{%1, %0|%0, %1}";
1237 (cond [(eq_attr "alternative" "2")
1238 (const_string "mmxadd")
1239 (eq_attr "alternative" "3,4,5")
1240 (const_string "mmxmov")
1241 (eq_attr "alternative" "6")
1242 (const_string "sselog1")
1243 (eq_attr "alternative" "7,8,9,10,11")
1244 (const_string "ssemov")
1245 (match_operand:DI 1 "pic_32bit_operand" "")
1246 (const_string "lea")
1248 (const_string "imov")))
1250 (cond [(eq_attr "alternative" "2,3")
1252 (eq_attr "alternative" "6,7")
1254 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1255 (const_string "V4SF")
1256 (const_string "TI"))
1257 (and (eq_attr "alternative" "8,9,10,11")
1258 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1261 (const_string "SI")))])
1263 ;; Stores and loads of ax to arbitrary constant address.
1264 ;; We fake an second form of instruction to force reload to load address
1265 ;; into register when rax is not available
1266 (define_insn "*movabssi_1_rex64"
1267 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1268 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1269 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1271 movabs{l}\t{%1, %P0|%P0, %1}
1272 mov{l}\t{%1, %a0|%a0, %1}"
1273 [(set_attr "type" "imov")
1274 (set_attr "modrm" "0,*")
1275 (set_attr "length_address" "8,0")
1276 (set_attr "length_immediate" "0,*")
1277 (set_attr "memory" "store")
1278 (set_attr "mode" "SI")])
1280 (define_insn "*movabssi_2_rex64"
1281 [(set (match_operand:SI 0 "register_operand" "=a,r")
1282 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1283 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1285 movabs{l}\t{%P1, %0|%0, %P1}
1286 mov{l}\t{%a1, %0|%0, %a1}"
1287 [(set_attr "type" "imov")
1288 (set_attr "modrm" "0,*")
1289 (set_attr "length_address" "8,0")
1290 (set_attr "length_immediate" "0")
1291 (set_attr "memory" "load")
1292 (set_attr "mode" "SI")])
1294 (define_insn "*swapsi"
1295 [(set (match_operand:SI 0 "register_operand" "+r")
1296 (match_operand:SI 1 "register_operand" "+r"))
1301 [(set_attr "type" "imov")
1302 (set_attr "mode" "SI")
1303 (set_attr "pent_pair" "np")
1304 (set_attr "athlon_decode" "vector")
1305 (set_attr "amdfam10_decode" "double")])
1307 (define_expand "movhi"
1308 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1309 (match_operand:HI 1 "general_operand" ""))]
1311 "ix86_expand_move (HImode, operands); DONE;")
1313 (define_insn "*pushhi2"
1314 [(set (match_operand:HI 0 "push_operand" "=X")
1315 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1318 [(set_attr "type" "push")
1319 (set_attr "mode" "SI")])
1321 ;; For 64BIT abi we always round up to 8 bytes.
1322 (define_insn "*pushhi2_rex64"
1323 [(set (match_operand:HI 0 "push_operand" "=X")
1324 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1327 [(set_attr "type" "push")
1328 (set_attr "mode" "DI")])
1330 (define_insn "*movhi_1"
1331 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1332 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1333 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1335 switch (get_attr_type (insn))
1338 /* movzwl is faster than movw on p2 due to partial word stalls,
1339 though not as fast as an aligned movl. */
1340 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1342 if (get_attr_mode (insn) == MODE_SI)
1343 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1345 return "mov{w}\t{%1, %0|%0, %1}";
1349 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1350 (const_string "imov")
1351 (and (eq_attr "alternative" "0")
1352 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1354 (eq (symbol_ref "TARGET_HIMODE_MATH")
1356 (const_string "imov")
1357 (and (eq_attr "alternative" "1,2")
1358 (match_operand:HI 1 "aligned_operand" ""))
1359 (const_string "imov")
1360 (and (ne (symbol_ref "TARGET_MOVX")
1362 (eq_attr "alternative" "0,2"))
1363 (const_string "imovx")
1365 (const_string "imov")))
1367 (cond [(eq_attr "type" "imovx")
1369 (and (eq_attr "alternative" "1,2")
1370 (match_operand:HI 1 "aligned_operand" ""))
1372 (and (eq_attr "alternative" "0")
1373 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1375 (eq (symbol_ref "TARGET_HIMODE_MATH")
1379 (const_string "HI")))])
1381 ;; Stores and loads of ax to arbitrary constant address.
1382 ;; We fake an second form of instruction to force reload to load address
1383 ;; into register when rax is not available
1384 (define_insn "*movabshi_1_rex64"
1385 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1386 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1387 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1389 movabs{w}\t{%1, %P0|%P0, %1}
1390 mov{w}\t{%1, %a0|%a0, %1}"
1391 [(set_attr "type" "imov")
1392 (set_attr "modrm" "0,*")
1393 (set_attr "length_address" "8,0")
1394 (set_attr "length_immediate" "0,*")
1395 (set_attr "memory" "store")
1396 (set_attr "mode" "HI")])
1398 (define_insn "*movabshi_2_rex64"
1399 [(set (match_operand:HI 0 "register_operand" "=a,r")
1400 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1401 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1403 movabs{w}\t{%P1, %0|%0, %P1}
1404 mov{w}\t{%a1, %0|%0, %a1}"
1405 [(set_attr "type" "imov")
1406 (set_attr "modrm" "0,*")
1407 (set_attr "length_address" "8,0")
1408 (set_attr "length_immediate" "0")
1409 (set_attr "memory" "load")
1410 (set_attr "mode" "HI")])
1412 (define_insn "*swaphi_1"
1413 [(set (match_operand:HI 0 "register_operand" "+r")
1414 (match_operand:HI 1 "register_operand" "+r"))
1417 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1419 [(set_attr "type" "imov")
1420 (set_attr "mode" "SI")
1421 (set_attr "pent_pair" "np")
1422 (set_attr "athlon_decode" "vector")
1423 (set_attr "amdfam10_decode" "double")])
1425 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1426 (define_insn "*swaphi_2"
1427 [(set (match_operand:HI 0 "register_operand" "+r")
1428 (match_operand:HI 1 "register_operand" "+r"))
1431 "TARGET_PARTIAL_REG_STALL"
1433 [(set_attr "type" "imov")
1434 (set_attr "mode" "HI")
1435 (set_attr "pent_pair" "np")
1436 (set_attr "athlon_decode" "vector")])
1438 (define_expand "movstricthi"
1439 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1440 (match_operand:HI 1 "general_operand" ""))]
1441 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1443 /* Don't generate memory->memory moves, go through a register */
1444 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1445 operands[1] = force_reg (HImode, operands[1]);
1448 (define_insn "*movstricthi_1"
1449 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1450 (match_operand:HI 1 "general_operand" "rn,m"))]
1451 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1452 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1453 "mov{w}\t{%1, %0|%0, %1}"
1454 [(set_attr "type" "imov")
1455 (set_attr "mode" "HI")])
1457 (define_insn "*movstricthi_xor"
1458 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1459 (match_operand:HI 1 "const0_operand" "i"))
1460 (clobber (reg:CC FLAGS_REG))]
1462 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1464 [(set_attr "type" "alu1")
1465 (set_attr "mode" "HI")
1466 (set_attr "length_immediate" "0")])
1468 (define_expand "movqi"
1469 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1470 (match_operand:QI 1 "general_operand" ""))]
1472 "ix86_expand_move (QImode, operands); DONE;")
1474 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1475 ;; "push a byte". But actually we use pushl, which has the effect
1476 ;; of rounding the amount pushed up to a word.
1478 (define_insn "*pushqi2"
1479 [(set (match_operand:QI 0 "push_operand" "=X")
1480 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1483 [(set_attr "type" "push")
1484 (set_attr "mode" "SI")])
1486 ;; For 64BIT abi we always round up to 8 bytes.
1487 (define_insn "*pushqi2_rex64"
1488 [(set (match_operand:QI 0 "push_operand" "=X")
1489 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1492 [(set_attr "type" "push")
1493 (set_attr "mode" "DI")])
1495 ;; Situation is quite tricky about when to choose full sized (SImode) move
1496 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1497 ;; partial register dependency machines (such as AMD Athlon), where QImode
1498 ;; moves issue extra dependency and for partial register stalls machines
1499 ;; that don't use QImode patterns (and QImode move cause stall on the next
1502 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1503 ;; register stall machines with, where we use QImode instructions, since
1504 ;; partial register stall can be caused there. Then we use movzx.
1505 (define_insn "*movqi_1"
1506 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1507 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1508 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1510 switch (get_attr_type (insn))
1513 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1514 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1516 if (get_attr_mode (insn) == MODE_SI)
1517 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1519 return "mov{b}\t{%1, %0|%0, %1}";
1523 (cond [(and (eq_attr "alternative" "5")
1524 (not (match_operand:QI 1 "aligned_operand" "")))
1525 (const_string "imovx")
1526 (ne (symbol_ref "optimize_size") (const_int 0))
1527 (const_string "imov")
1528 (and (eq_attr "alternative" "3")
1529 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1531 (eq (symbol_ref "TARGET_QIMODE_MATH")
1533 (const_string "imov")
1534 (eq_attr "alternative" "3,5")
1535 (const_string "imovx")
1536 (and (ne (symbol_ref "TARGET_MOVX")
1538 (eq_attr "alternative" "2"))
1539 (const_string "imovx")
1541 (const_string "imov")))
1543 (cond [(eq_attr "alternative" "3,4,5")
1545 (eq_attr "alternative" "6")
1547 (eq_attr "type" "imovx")
1549 (and (eq_attr "type" "imov")
1550 (and (eq_attr "alternative" "0,1")
1551 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1553 (and (eq (symbol_ref "optimize_size")
1555 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1558 ;; Avoid partial register stalls when not using QImode arithmetic
1559 (and (eq_attr "type" "imov")
1560 (and (eq_attr "alternative" "0,1")
1561 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1563 (eq (symbol_ref "TARGET_QIMODE_MATH")
1567 (const_string "QI")))])
1569 (define_expand "reload_outqi"
1570 [(parallel [(match_operand:QI 0 "" "=m")
1571 (match_operand:QI 1 "register_operand" "r")
1572 (match_operand:QI 2 "register_operand" "=&q")])]
1576 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1578 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1579 if (! q_regs_operand (op1, QImode))
1581 emit_insn (gen_movqi (op2, op1));
1584 emit_insn (gen_movqi (op0, op1));
1588 (define_insn "*swapqi_1"
1589 [(set (match_operand:QI 0 "register_operand" "+r")
1590 (match_operand:QI 1 "register_operand" "+r"))
1593 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1595 [(set_attr "type" "imov")
1596 (set_attr "mode" "SI")
1597 (set_attr "pent_pair" "np")
1598 (set_attr "athlon_decode" "vector")
1599 (set_attr "amdfam10_decode" "vector")])
1601 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1602 (define_insn "*swapqi_2"
1603 [(set (match_operand:QI 0 "register_operand" "+q")
1604 (match_operand:QI 1 "register_operand" "+q"))
1607 "TARGET_PARTIAL_REG_STALL"
1609 [(set_attr "type" "imov")
1610 (set_attr "mode" "QI")
1611 (set_attr "pent_pair" "np")
1612 (set_attr "athlon_decode" "vector")])
1614 (define_expand "movstrictqi"
1615 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1616 (match_operand:QI 1 "general_operand" ""))]
1617 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1619 /* Don't generate memory->memory moves, go through a register. */
1620 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1621 operands[1] = force_reg (QImode, operands[1]);
1624 (define_insn "*movstrictqi_1"
1625 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1626 (match_operand:QI 1 "general_operand" "*qn,m"))]
1627 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1628 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1629 "mov{b}\t{%1, %0|%0, %1}"
1630 [(set_attr "type" "imov")
1631 (set_attr "mode" "QI")])
1633 (define_insn "*movstrictqi_xor"
1634 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1635 (match_operand:QI 1 "const0_operand" "i"))
1636 (clobber (reg:CC FLAGS_REG))]
1637 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1639 [(set_attr "type" "alu1")
1640 (set_attr "mode" "QI")
1641 (set_attr "length_immediate" "0")])
1643 (define_insn "*movsi_extv_1"
1644 [(set (match_operand:SI 0 "register_operand" "=R")
1645 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1649 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1650 [(set_attr "type" "imovx")
1651 (set_attr "mode" "SI")])
1653 (define_insn "*movhi_extv_1"
1654 [(set (match_operand:HI 0 "register_operand" "=R")
1655 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1659 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1660 [(set_attr "type" "imovx")
1661 (set_attr "mode" "SI")])
1663 (define_insn "*movqi_extv_1"
1664 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1665 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1670 switch (get_attr_type (insn))
1673 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1675 return "mov{b}\t{%h1, %0|%0, %h1}";
1679 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1680 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1681 (ne (symbol_ref "TARGET_MOVX")
1683 (const_string "imovx")
1684 (const_string "imov")))
1686 (if_then_else (eq_attr "type" "imovx")
1688 (const_string "QI")))])
1690 (define_insn "*movqi_extv_1_rex64"
1691 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1692 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1697 switch (get_attr_type (insn))
1700 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1702 return "mov{b}\t{%h1, %0|%0, %h1}";
1706 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1707 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1708 (ne (symbol_ref "TARGET_MOVX")
1710 (const_string "imovx")
1711 (const_string "imov")))
1713 (if_then_else (eq_attr "type" "imovx")
1715 (const_string "QI")))])
1717 ;; Stores and loads of ax to arbitrary constant address.
1718 ;; We fake an second form of instruction to force reload to load address
1719 ;; into register when rax is not available
1720 (define_insn "*movabsqi_1_rex64"
1721 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1722 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1723 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1725 movabs{b}\t{%1, %P0|%P0, %1}
1726 mov{b}\t{%1, %a0|%a0, %1}"
1727 [(set_attr "type" "imov")
1728 (set_attr "modrm" "0,*")
1729 (set_attr "length_address" "8,0")
1730 (set_attr "length_immediate" "0,*")
1731 (set_attr "memory" "store")
1732 (set_attr "mode" "QI")])
1734 (define_insn "*movabsqi_2_rex64"
1735 [(set (match_operand:QI 0 "register_operand" "=a,r")
1736 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1737 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1739 movabs{b}\t{%P1, %0|%0, %P1}
1740 mov{b}\t{%a1, %0|%0, %a1}"
1741 [(set_attr "type" "imov")
1742 (set_attr "modrm" "0,*")
1743 (set_attr "length_address" "8,0")
1744 (set_attr "length_immediate" "0")
1745 (set_attr "memory" "load")
1746 (set_attr "mode" "QI")])
1748 (define_insn "*movdi_extzv_1"
1749 [(set (match_operand:DI 0 "register_operand" "=R")
1750 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1754 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1755 [(set_attr "type" "imovx")
1756 (set_attr "mode" "DI")])
1758 (define_insn "*movsi_extzv_1"
1759 [(set (match_operand:SI 0 "register_operand" "=R")
1760 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1764 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1765 [(set_attr "type" "imovx")
1766 (set_attr "mode" "SI")])
1768 (define_insn "*movqi_extzv_2"
1769 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1770 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1775 switch (get_attr_type (insn))
1778 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1780 return "mov{b}\t{%h1, %0|%0, %h1}";
1784 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1785 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1786 (ne (symbol_ref "TARGET_MOVX")
1788 (const_string "imovx")
1789 (const_string "imov")))
1791 (if_then_else (eq_attr "type" "imovx")
1793 (const_string "QI")))])
1795 (define_insn "*movqi_extzv_2_rex64"
1796 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1797 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1802 switch (get_attr_type (insn))
1805 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1807 return "mov{b}\t{%h1, %0|%0, %h1}";
1811 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1812 (ne (symbol_ref "TARGET_MOVX")
1814 (const_string "imovx")
1815 (const_string "imov")))
1817 (if_then_else (eq_attr "type" "imovx")
1819 (const_string "QI")))])
1821 (define_insn "movsi_insv_1"
1822 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1825 (match_operand:SI 1 "general_operand" "Qmn"))]
1827 "mov{b}\t{%b1, %h0|%h0, %b1}"
1828 [(set_attr "type" "imov")
1829 (set_attr "mode" "QI")])
1831 (define_insn "*movsi_insv_1_rex64"
1832 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1835 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1837 "mov{b}\t{%b1, %h0|%h0, %b1}"
1838 [(set_attr "type" "imov")
1839 (set_attr "mode" "QI")])
1841 (define_insn "movdi_insv_1_rex64"
1842 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1845 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1847 "mov{b}\t{%b1, %h0|%h0, %b1}"
1848 [(set_attr "type" "imov")
1849 (set_attr "mode" "QI")])
1851 (define_insn "*movqi_insv_2"
1852 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1855 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1858 "mov{b}\t{%h1, %h0|%h0, %h1}"
1859 [(set_attr "type" "imov")
1860 (set_attr "mode" "QI")])
1862 (define_expand "movdi"
1863 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1864 (match_operand:DI 1 "general_operand" ""))]
1866 "ix86_expand_move (DImode, operands); DONE;")
1868 (define_insn "*pushdi"
1869 [(set (match_operand:DI 0 "push_operand" "=<")
1870 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1874 (define_insn "*pushdi2_rex64"
1875 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1876 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1881 [(set_attr "type" "push,multi")
1882 (set_attr "mode" "DI")])
1884 ;; Convert impossible pushes of immediate to existing instructions.
1885 ;; First try to get scratch register and go through it. In case this
1886 ;; fails, push sign extended lower part first and then overwrite
1887 ;; upper part by 32bit move.
1889 [(match_scratch:DI 2 "r")
1890 (set (match_operand:DI 0 "push_operand" "")
1891 (match_operand:DI 1 "immediate_operand" ""))]
1892 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1893 && !x86_64_immediate_operand (operands[1], DImode)"
1894 [(set (match_dup 2) (match_dup 1))
1895 (set (match_dup 0) (match_dup 2))]
1898 ;; We need to define this as both peepholer and splitter for case
1899 ;; peephole2 pass is not run.
1900 ;; "&& 1" is needed to keep it from matching the previous pattern.
1902 [(set (match_operand:DI 0 "push_operand" "")
1903 (match_operand:DI 1 "immediate_operand" ""))]
1904 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1905 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1906 [(set (match_dup 0) (match_dup 1))
1907 (set (match_dup 2) (match_dup 3))]
1908 "split_di (operands + 1, 1, operands + 2, operands + 3);
1909 operands[1] = gen_lowpart (DImode, operands[2]);
1910 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1915 [(set (match_operand:DI 0 "push_operand" "")
1916 (match_operand:DI 1 "immediate_operand" ""))]
1917 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1918 ? flow2_completed : reload_completed)
1919 && !symbolic_operand (operands[1], DImode)
1920 && !x86_64_immediate_operand (operands[1], DImode)"
1921 [(set (match_dup 0) (match_dup 1))
1922 (set (match_dup 2) (match_dup 3))]
1923 "split_di (operands + 1, 1, operands + 2, operands + 3);
1924 operands[1] = gen_lowpart (DImode, operands[2]);
1925 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1929 (define_insn "*pushdi2_prologue_rex64"
1930 [(set (match_operand:DI 0 "push_operand" "=<")
1931 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1932 (clobber (mem:BLK (scratch)))]
1935 [(set_attr "type" "push")
1936 (set_attr "mode" "DI")])
1938 (define_insn "*popdi1_epilogue_rex64"
1939 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1940 (mem:DI (reg:DI SP_REG)))
1941 (set (reg:DI SP_REG)
1942 (plus:DI (reg:DI SP_REG) (const_int 8)))
1943 (clobber (mem:BLK (scratch)))]
1946 [(set_attr "type" "pop")
1947 (set_attr "mode" "DI")])
1949 (define_insn "popdi1"
1950 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1951 (mem:DI (reg:DI SP_REG)))
1952 (set (reg:DI SP_REG)
1953 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1956 [(set_attr "type" "pop")
1957 (set_attr "mode" "DI")])
1959 (define_insn "*movdi_xor_rex64"
1960 [(set (match_operand:DI 0 "register_operand" "=r")
1961 (match_operand:DI 1 "const0_operand" "i"))
1962 (clobber (reg:CC FLAGS_REG))]
1963 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1964 && reload_completed"
1966 [(set_attr "type" "alu1")
1967 (set_attr "mode" "SI")
1968 (set_attr "length_immediate" "0")])
1970 (define_insn "*movdi_or_rex64"
1971 [(set (match_operand:DI 0 "register_operand" "=r")
1972 (match_operand:DI 1 "const_int_operand" "i"))
1973 (clobber (reg:CC FLAGS_REG))]
1974 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1976 && operands[1] == constm1_rtx"
1978 operands[1] = constm1_rtx;
1979 return "or{q}\t{%1, %0|%0, %1}";
1981 [(set_attr "type" "alu1")
1982 (set_attr "mode" "DI")
1983 (set_attr "length_immediate" "1")])
1985 (define_insn "*movdi_2"
1986 [(set (match_operand:DI 0 "nonimmediate_operand"
1987 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
1988 (match_operand:DI 1 "general_operand"
1989 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
1990 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1995 movq\t{%1, %0|%0, %1}
1996 movq\t{%1, %0|%0, %1}
1998 movq\t{%1, %0|%0, %1}
1999 movdqa\t{%1, %0|%0, %1}
2000 movq\t{%1, %0|%0, %1}
2002 movlps\t{%1, %0|%0, %1}
2003 movaps\t{%1, %0|%0, %1}
2004 movlps\t{%1, %0|%0, %1}"
2005 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2006 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2009 [(set (match_operand:DI 0 "push_operand" "")
2010 (match_operand:DI 1 "general_operand" ""))]
2011 "!TARGET_64BIT && reload_completed
2012 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2014 "ix86_split_long_move (operands); DONE;")
2016 ;; %%% This multiword shite has got to go.
2018 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2019 (match_operand:DI 1 "general_operand" ""))]
2020 "!TARGET_64BIT && reload_completed
2021 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2022 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2024 "ix86_split_long_move (operands); DONE;")
2026 (define_insn "*movdi_1_rex64"
2027 [(set (match_operand:DI 0 "nonimmediate_operand"
2028 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2029 (match_operand:DI 1 "general_operand"
2030 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2031 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2033 switch (get_attr_type (insn))
2036 if (SSE_REG_P (operands[0]))
2037 return "movq2dq\t{%1, %0|%0, %1}";
2039 return "movdq2q\t{%1, %0|%0, %1}";
2042 if (get_attr_mode (insn) == MODE_TI)
2043 return "movdqa\t{%1, %0|%0, %1}";
2047 /* Moves from and into integer register is done using movd
2048 opcode with REX prefix. */
2049 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2050 return "movd\t{%1, %0|%0, %1}";
2051 return "movq\t{%1, %0|%0, %1}";
2055 return "pxor\t%0, %0";
2061 return "lea{q}\t{%a1, %0|%0, %a1}";
2064 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2065 if (get_attr_mode (insn) == MODE_SI)
2066 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2067 else if (which_alternative == 2)
2068 return "movabs{q}\t{%1, %0|%0, %1}";
2070 return "mov{q}\t{%1, %0|%0, %1}";
2074 (cond [(eq_attr "alternative" "5")
2075 (const_string "mmxadd")
2076 (eq_attr "alternative" "6,7,8,9,10")
2077 (const_string "mmxmov")
2078 (eq_attr "alternative" "11")
2079 (const_string "sselog1")
2080 (eq_attr "alternative" "12,13,14,15,16")
2081 (const_string "ssemov")
2082 (eq_attr "alternative" "17,18")
2083 (const_string "ssecvt")
2084 (eq_attr "alternative" "4")
2085 (const_string "multi")
2086 (match_operand:DI 1 "pic_32bit_operand" "")
2087 (const_string "lea")
2089 (const_string "imov")))
2090 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2091 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2092 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2094 ;; Stores and loads of ax to arbitrary constant address.
2095 ;; We fake an second form of instruction to force reload to load address
2096 ;; into register when rax is not available
2097 (define_insn "*movabsdi_1_rex64"
2098 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2099 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2100 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2102 movabs{q}\t{%1, %P0|%P0, %1}
2103 mov{q}\t{%1, %a0|%a0, %1}"
2104 [(set_attr "type" "imov")
2105 (set_attr "modrm" "0,*")
2106 (set_attr "length_address" "8,0")
2107 (set_attr "length_immediate" "0,*")
2108 (set_attr "memory" "store")
2109 (set_attr "mode" "DI")])
2111 (define_insn "*movabsdi_2_rex64"
2112 [(set (match_operand:DI 0 "register_operand" "=a,r")
2113 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2114 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2116 movabs{q}\t{%P1, %0|%0, %P1}
2117 mov{q}\t{%a1, %0|%0, %a1}"
2118 [(set_attr "type" "imov")
2119 (set_attr "modrm" "0,*")
2120 (set_attr "length_address" "8,0")
2121 (set_attr "length_immediate" "0")
2122 (set_attr "memory" "load")
2123 (set_attr "mode" "DI")])
2125 ;; Convert impossible stores of immediate to existing instructions.
2126 ;; First try to get scratch register and go through it. In case this
2127 ;; fails, move by 32bit parts.
2129 [(match_scratch:DI 2 "r")
2130 (set (match_operand:DI 0 "memory_operand" "")
2131 (match_operand:DI 1 "immediate_operand" ""))]
2132 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2133 && !x86_64_immediate_operand (operands[1], DImode)"
2134 [(set (match_dup 2) (match_dup 1))
2135 (set (match_dup 0) (match_dup 2))]
2138 ;; We need to define this as both peepholer and splitter for case
2139 ;; peephole2 pass is not run.
2140 ;; "&& 1" is needed to keep it from matching the previous pattern.
2142 [(set (match_operand:DI 0 "memory_operand" "")
2143 (match_operand:DI 1 "immediate_operand" ""))]
2144 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2145 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2146 [(set (match_dup 2) (match_dup 3))
2147 (set (match_dup 4) (match_dup 5))]
2148 "split_di (operands, 2, operands + 2, operands + 4);")
2151 [(set (match_operand:DI 0 "memory_operand" "")
2152 (match_operand:DI 1 "immediate_operand" ""))]
2153 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2154 ? flow2_completed : reload_completed)
2155 && !symbolic_operand (operands[1], DImode)
2156 && !x86_64_immediate_operand (operands[1], DImode)"
2157 [(set (match_dup 2) (match_dup 3))
2158 (set (match_dup 4) (match_dup 5))]
2159 "split_di (operands, 2, operands + 2, operands + 4);")
2161 (define_insn "*swapdi_rex64"
2162 [(set (match_operand:DI 0 "register_operand" "+r")
2163 (match_operand:DI 1 "register_operand" "+r"))
2168 [(set_attr "type" "imov")
2169 (set_attr "mode" "DI")
2170 (set_attr "pent_pair" "np")
2171 (set_attr "athlon_decode" "vector")
2172 (set_attr "amdfam10_decode" "double")])
2174 (define_expand "movti"
2175 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2176 (match_operand:TI 1 "nonimmediate_operand" ""))]
2177 "TARGET_SSE || TARGET_64BIT"
2180 ix86_expand_move (TImode, operands);
2182 ix86_expand_vector_move (TImode, operands);
2186 (define_insn "*movti_internal"
2187 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2188 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2189 "TARGET_SSE && !TARGET_64BIT
2190 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2192 switch (which_alternative)
2195 if (get_attr_mode (insn) == MODE_V4SF)
2196 return "xorps\t%0, %0";
2198 return "pxor\t%0, %0";
2201 if (get_attr_mode (insn) == MODE_V4SF)
2202 return "movaps\t{%1, %0|%0, %1}";
2204 return "movdqa\t{%1, %0|%0, %1}";
2209 [(set_attr "type" "sselog1,ssemov,ssemov")
2211 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2212 (ne (symbol_ref "optimize_size") (const_int 0)))
2213 (const_string "V4SF")
2214 (and (eq_attr "alternative" "2")
2215 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2217 (const_string "V4SF")]
2218 (const_string "TI")))])
2220 (define_insn "*movti_rex64"
2221 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2222 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2224 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2226 switch (which_alternative)
2232 if (get_attr_mode (insn) == MODE_V4SF)
2233 return "xorps\t%0, %0";
2235 return "pxor\t%0, %0";
2238 if (get_attr_mode (insn) == MODE_V4SF)
2239 return "movaps\t{%1, %0|%0, %1}";
2241 return "movdqa\t{%1, %0|%0, %1}";
2246 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2248 (cond [(eq_attr "alternative" "2,3")
2250 (ne (symbol_ref "optimize_size")
2252 (const_string "V4SF")
2253 (const_string "TI"))
2254 (eq_attr "alternative" "4")
2256 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2258 (ne (symbol_ref "optimize_size")
2260 (const_string "V4SF")
2261 (const_string "TI"))]
2262 (const_string "DI")))])
2265 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2266 (match_operand:TI 1 "general_operand" ""))]
2267 "reload_completed && !SSE_REG_P (operands[0])
2268 && !SSE_REG_P (operands[1])"
2270 "ix86_split_long_move (operands); DONE;")
2272 (define_expand "movsf"
2273 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2274 (match_operand:SF 1 "general_operand" ""))]
2276 "ix86_expand_move (SFmode, operands); DONE;")
2278 (define_insn "*pushsf"
2279 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2280 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2283 /* Anything else should be already split before reg-stack. */
2284 gcc_assert (which_alternative == 1);
2285 return "push{l}\t%1";
2287 [(set_attr "type" "multi,push,multi")
2288 (set_attr "unit" "i387,*,*")
2289 (set_attr "mode" "SF,SI,SF")])
2291 (define_insn "*pushsf_rex64"
2292 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2293 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2296 /* Anything else should be already split before reg-stack. */
2297 gcc_assert (which_alternative == 1);
2298 return "push{q}\t%q1";
2300 [(set_attr "type" "multi,push,multi")
2301 (set_attr "unit" "i387,*,*")
2302 (set_attr "mode" "SF,DI,SF")])
2305 [(set (match_operand:SF 0 "push_operand" "")
2306 (match_operand:SF 1 "memory_operand" ""))]
2308 && MEM_P (operands[1])
2309 && constant_pool_reference_p (operands[1])"
2312 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2315 ;; %%% Kill this when call knows how to work this out.
2317 [(set (match_operand:SF 0 "push_operand" "")
2318 (match_operand:SF 1 "any_fp_register_operand" ""))]
2320 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2321 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2324 [(set (match_operand:SF 0 "push_operand" "")
2325 (match_operand:SF 1 "any_fp_register_operand" ""))]
2327 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2328 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2330 (define_insn "*movsf_1"
2331 [(set (match_operand:SF 0 "nonimmediate_operand"
2332 "=f,m,f,r ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r ")
2333 (match_operand:SF 1 "general_operand"
2334 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r ,*Ym"))]
2335 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2336 && (reload_in_progress || reload_completed
2337 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2338 || (!TARGET_SSE_MATH && optimize_size
2339 && standard_80387_constant_p (operands[1]))
2340 || GET_CODE (operands[1]) != CONST_DOUBLE
2341 || memory_operand (operands[0], SFmode))"
2343 switch (which_alternative)
2346 return output_387_reg_move (insn, operands);
2349 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2350 return "fstp%z0\t%y0";
2352 return "fst%z0\t%y0";
2355 return standard_80387_constant_opcode (operands[1]);
2359 return "mov{l}\t{%1, %0|%0, %1}";
2361 if (get_attr_mode (insn) == MODE_TI)
2362 return "pxor\t%0, %0";
2364 return "xorps\t%0, %0";
2366 if (get_attr_mode (insn) == MODE_V4SF)
2367 return "movaps\t{%1, %0|%0, %1}";
2369 return "movss\t{%1, %0|%0, %1}";
2371 return "movss\t{%1, %0|%0, %1}";
2374 case 12: case 13: case 14: case 15:
2375 return "movd\t{%1, %0|%0, %1}";
2378 return "movq\t{%1, %0|%0, %1}";
2384 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2386 (cond [(eq_attr "alternative" "3,4,9,10")
2388 (eq_attr "alternative" "5")
2390 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2392 (ne (symbol_ref "TARGET_SSE2")
2394 (eq (symbol_ref "optimize_size")
2397 (const_string "V4SF"))
2398 /* For architectures resolving dependencies on
2399 whole SSE registers use APS move to break dependency
2400 chains, otherwise use short move to avoid extra work.
2402 Do the same for architectures resolving dependencies on
2403 the parts. While in DF mode it is better to always handle
2404 just register parts, the SF mode is different due to lack
2405 of instructions to load just part of the register. It is
2406 better to maintain the whole registers in single format
2407 to avoid problems on using packed logical operations. */
2408 (eq_attr "alternative" "6")
2410 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2412 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2414 (const_string "V4SF")
2415 (const_string "SF"))
2416 (eq_attr "alternative" "11")
2417 (const_string "DI")]
2418 (const_string "SF")))])
2420 (define_insn "*swapsf"
2421 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2422 (match_operand:SF 1 "fp_register_operand" "+f"))
2425 "reload_completed || TARGET_80387"
2427 if (STACK_TOP_P (operands[0]))
2432 [(set_attr "type" "fxch")
2433 (set_attr "mode" "SF")])
2435 (define_expand "movdf"
2436 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2437 (match_operand:DF 1 "general_operand" ""))]
2439 "ix86_expand_move (DFmode, operands); DONE;")
2441 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2442 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2443 ;; On the average, pushdf using integers can be still shorter. Allow this
2444 ;; pattern for optimize_size too.
2446 (define_insn "*pushdf_nointeger"
2447 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2448 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2449 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2451 /* This insn should be already split before reg-stack. */
2454 [(set_attr "type" "multi")
2455 (set_attr "unit" "i387,*,*,*")
2456 (set_attr "mode" "DF,SI,SI,DF")])
2458 (define_insn "*pushdf_integer"
2459 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2460 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2461 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2463 /* This insn should be already split before reg-stack. */
2466 [(set_attr "type" "multi")
2467 (set_attr "unit" "i387,*,*")
2468 (set_attr "mode" "DF,SI,DF")])
2470 ;; %%% Kill this when call knows how to work this out.
2472 [(set (match_operand:DF 0 "push_operand" "")
2473 (match_operand:DF 1 "any_fp_register_operand" ""))]
2474 "!TARGET_64BIT && reload_completed"
2475 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2476 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2480 [(set (match_operand:DF 0 "push_operand" "")
2481 (match_operand:DF 1 "any_fp_register_operand" ""))]
2482 "TARGET_64BIT && reload_completed"
2483 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2484 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2488 [(set (match_operand:DF 0 "push_operand" "")
2489 (match_operand:DF 1 "general_operand" ""))]
2492 "ix86_split_long_move (operands); DONE;")
2494 ;; Moving is usually shorter when only FP registers are used. This separate
2495 ;; movdf pattern avoids the use of integer registers for FP operations
2496 ;; when optimizing for size.
2498 (define_insn "*movdf_nointeger"
2499 [(set (match_operand:DF 0 "nonimmediate_operand"
2500 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2501 (match_operand:DF 1 "general_operand"
2502 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2503 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2504 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2505 && (reload_in_progress || reload_completed
2506 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2507 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2508 && standard_80387_constant_p (operands[1]))
2509 || GET_CODE (operands[1]) != CONST_DOUBLE
2510 || memory_operand (operands[0], DFmode))"
2512 switch (which_alternative)
2515 return output_387_reg_move (insn, operands);
2518 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2519 return "fstp%z0\t%y0";
2521 return "fst%z0\t%y0";
2524 return standard_80387_constant_opcode (operands[1]);
2530 switch (get_attr_mode (insn))
2533 return "xorps\t%0, %0";
2535 return "xorpd\t%0, %0";
2537 return "pxor\t%0, %0";
2544 switch (get_attr_mode (insn))
2547 return "movaps\t{%1, %0|%0, %1}";
2549 return "movapd\t{%1, %0|%0, %1}";
2551 return "movdqa\t{%1, %0|%0, %1}";
2553 return "movq\t{%1, %0|%0, %1}";
2555 return "movsd\t{%1, %0|%0, %1}";
2557 return "movlpd\t{%1, %0|%0, %1}";
2559 return "movlps\t{%1, %0|%0, %1}";
2568 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2570 (cond [(eq_attr "alternative" "0,1,2")
2572 (eq_attr "alternative" "3,4")
2575 /* For SSE1, we have many fewer alternatives. */
2576 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2577 (cond [(eq_attr "alternative" "5,6")
2578 (const_string "V4SF")
2580 (const_string "V2SF"))
2582 /* xorps is one byte shorter. */
2583 (eq_attr "alternative" "5")
2584 (cond [(ne (symbol_ref "optimize_size")
2586 (const_string "V4SF")
2587 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2591 (const_string "V2DF"))
2593 /* For architectures resolving dependencies on
2594 whole SSE registers use APD move to break dependency
2595 chains, otherwise use short move to avoid extra work.
2597 movaps encodes one byte shorter. */
2598 (eq_attr "alternative" "6")
2600 [(ne (symbol_ref "optimize_size")
2602 (const_string "V4SF")
2603 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2605 (const_string "V2DF")
2607 (const_string "DF"))
2608 /* For architectures resolving dependencies on register
2609 parts we may avoid extra work to zero out upper part
2611 (eq_attr "alternative" "7")
2613 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2615 (const_string "V1DF")
2616 (const_string "DF"))
2618 (const_string "DF")))])
2620 (define_insn "*movdf_integer_rex64"
2621 [(set (match_operand:DF 0 "nonimmediate_operand"
2622 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2623 (match_operand:DF 1 "general_operand"
2624 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2625 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2626 && (reload_in_progress || reload_completed
2627 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2628 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2629 && standard_80387_constant_p (operands[1]))
2630 || GET_CODE (operands[1]) != CONST_DOUBLE
2631 || memory_operand (operands[0], DFmode))"
2633 switch (which_alternative)
2636 return output_387_reg_move (insn, operands);
2639 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2640 return "fstp%z0\t%y0";
2642 return "fst%z0\t%y0";
2645 return standard_80387_constant_opcode (operands[1]);
2652 switch (get_attr_mode (insn))
2655 return "xorps\t%0, %0";
2657 return "xorpd\t%0, %0";
2659 return "pxor\t%0, %0";
2666 switch (get_attr_mode (insn))
2669 return "movaps\t{%1, %0|%0, %1}";
2671 return "movapd\t{%1, %0|%0, %1}";
2673 return "movdqa\t{%1, %0|%0, %1}";
2675 return "movq\t{%1, %0|%0, %1}";
2677 return "movsd\t{%1, %0|%0, %1}";
2679 return "movlpd\t{%1, %0|%0, %1}";
2681 return "movlps\t{%1, %0|%0, %1}";
2688 return "movd\t{%1, %0|%0, %1}";
2694 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2696 (cond [(eq_attr "alternative" "0,1,2")
2698 (eq_attr "alternative" "3,4,9,10")
2701 /* For SSE1, we have many fewer alternatives. */
2702 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2703 (cond [(eq_attr "alternative" "5,6")
2704 (const_string "V4SF")
2706 (const_string "V2SF"))
2708 /* xorps is one byte shorter. */
2709 (eq_attr "alternative" "5")
2710 (cond [(ne (symbol_ref "optimize_size")
2712 (const_string "V4SF")
2713 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2717 (const_string "V2DF"))
2719 /* For architectures resolving dependencies on
2720 whole SSE registers use APD move to break dependency
2721 chains, otherwise use short move to avoid extra work.
2723 movaps encodes one byte shorter. */
2724 (eq_attr "alternative" "6")
2726 [(ne (symbol_ref "optimize_size")
2728 (const_string "V4SF")
2729 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2731 (const_string "V2DF")
2733 (const_string "DF"))
2734 /* For architectures resolving dependencies on register
2735 parts we may avoid extra work to zero out upper part
2737 (eq_attr "alternative" "7")
2739 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2741 (const_string "V1DF")
2742 (const_string "DF"))
2744 (const_string "DF")))])
2746 (define_insn "*movdf_integer"
2747 [(set (match_operand:DF 0 "nonimmediate_operand"
2748 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2749 (match_operand:DF 1 "general_operand"
2750 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2751 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2752 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2753 && (reload_in_progress || reload_completed
2754 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2755 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2756 && standard_80387_constant_p (operands[1]))
2757 || GET_CODE (operands[1]) != CONST_DOUBLE
2758 || memory_operand (operands[0], DFmode))"
2760 switch (which_alternative)
2763 return output_387_reg_move (insn, operands);
2766 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2767 return "fstp%z0\t%y0";
2769 return "fst%z0\t%y0";
2772 return standard_80387_constant_opcode (operands[1]);
2779 switch (get_attr_mode (insn))
2782 return "xorps\t%0, %0";
2784 return "xorpd\t%0, %0";
2786 return "pxor\t%0, %0";
2793 switch (get_attr_mode (insn))
2796 return "movaps\t{%1, %0|%0, %1}";
2798 return "movapd\t{%1, %0|%0, %1}";
2800 return "movdqa\t{%1, %0|%0, %1}";
2802 return "movq\t{%1, %0|%0, %1}";
2804 return "movsd\t{%1, %0|%0, %1}";
2806 return "movlpd\t{%1, %0|%0, %1}";
2808 return "movlps\t{%1, %0|%0, %1}";
2817 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2819 (cond [(eq_attr "alternative" "0,1,2")
2821 (eq_attr "alternative" "3,4")
2824 /* For SSE1, we have many fewer alternatives. */
2825 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2826 (cond [(eq_attr "alternative" "5,6")
2827 (const_string "V4SF")
2829 (const_string "V2SF"))
2831 /* xorps is one byte shorter. */
2832 (eq_attr "alternative" "5")
2833 (cond [(ne (symbol_ref "optimize_size")
2835 (const_string "V4SF")
2836 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2840 (const_string "V2DF"))
2842 /* For architectures resolving dependencies on
2843 whole SSE registers use APD move to break dependency
2844 chains, otherwise use short move to avoid extra work.
2846 movaps encodes one byte shorter. */
2847 (eq_attr "alternative" "6")
2849 [(ne (symbol_ref "optimize_size")
2851 (const_string "V4SF")
2852 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2854 (const_string "V2DF")
2856 (const_string "DF"))
2857 /* For architectures resolving dependencies on register
2858 parts we may avoid extra work to zero out upper part
2860 (eq_attr "alternative" "7")
2862 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2864 (const_string "V1DF")
2865 (const_string "DF"))
2867 (const_string "DF")))])
2870 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2871 (match_operand:DF 1 "general_operand" ""))]
2873 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2874 && ! (ANY_FP_REG_P (operands[0]) ||
2875 (GET_CODE (operands[0]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2877 && ! (ANY_FP_REG_P (operands[1]) ||
2878 (GET_CODE (operands[1]) == SUBREG
2879 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2881 "ix86_split_long_move (operands); DONE;")
2883 (define_insn "*swapdf"
2884 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2885 (match_operand:DF 1 "fp_register_operand" "+f"))
2888 "reload_completed || TARGET_80387"
2890 if (STACK_TOP_P (operands[0]))
2895 [(set_attr "type" "fxch")
2896 (set_attr "mode" "DF")])
2898 (define_expand "movxf"
2899 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2900 (match_operand:XF 1 "general_operand" ""))]
2902 "ix86_expand_move (XFmode, operands); DONE;")
2904 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2905 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2906 ;; Pushing using integer instructions is longer except for constants
2907 ;; and direct memory references.
2908 ;; (assuming that any given constant is pushed only once, but this ought to be
2909 ;; handled elsewhere).
2911 (define_insn "*pushxf_nointeger"
2912 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2913 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2916 /* This insn should be already split before reg-stack. */
2919 [(set_attr "type" "multi")
2920 (set_attr "unit" "i387,*,*")
2921 (set_attr "mode" "XF,SI,SI")])
2923 (define_insn "*pushxf_integer"
2924 [(set (match_operand:XF 0 "push_operand" "=<,<")
2925 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2928 /* This insn should be already split before reg-stack. */
2931 [(set_attr "type" "multi")
2932 (set_attr "unit" "i387,*")
2933 (set_attr "mode" "XF,SI")])
2936 [(set (match_operand 0 "push_operand" "")
2937 (match_operand 1 "general_operand" ""))]
2939 && (GET_MODE (operands[0]) == XFmode
2940 || GET_MODE (operands[0]) == DFmode)
2941 && !ANY_FP_REG_P (operands[1])"
2943 "ix86_split_long_move (operands); DONE;")
2946 [(set (match_operand:XF 0 "push_operand" "")
2947 (match_operand:XF 1 "any_fp_register_operand" ""))]
2949 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2950 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2951 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2954 [(set (match_operand:XF 0 "push_operand" "")
2955 (match_operand:XF 1 "any_fp_register_operand" ""))]
2957 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2958 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2959 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2961 ;; Do not use integer registers when optimizing for size
2962 (define_insn "*movxf_nointeger"
2963 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2964 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2966 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2967 && (reload_in_progress || reload_completed
2968 || (optimize_size && standard_80387_constant_p (operands[1]))
2969 || GET_CODE (operands[1]) != CONST_DOUBLE
2970 || memory_operand (operands[0], XFmode))"
2972 switch (which_alternative)
2975 return output_387_reg_move (insn, operands);
2978 /* There is no non-popping store to memory for XFmode. So if
2979 we need one, follow the store with a load. */
2980 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2981 return "fstp%z0\t%y0\;fld%z0\t%y0";
2983 return "fstp%z0\t%y0";
2986 return standard_80387_constant_opcode (operands[1]);
2994 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2995 (set_attr "mode" "XF,XF,XF,SI,SI")])
2997 (define_insn "*movxf_integer"
2998 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2999 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3001 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3002 && (reload_in_progress || reload_completed
3003 || (optimize_size && standard_80387_constant_p (operands[1]))
3004 || GET_CODE (operands[1]) != CONST_DOUBLE
3005 || memory_operand (operands[0], XFmode))"
3007 switch (which_alternative)
3010 return output_387_reg_move (insn, operands);
3013 /* There is no non-popping store to memory for XFmode. So if
3014 we need one, follow the store with a load. */
3015 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3016 return "fstp%z0\t%y0\;fld%z0\t%y0";
3018 return "fstp%z0\t%y0";
3021 return standard_80387_constant_opcode (operands[1]);
3030 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3031 (set_attr "mode" "XF,XF,XF,SI,SI")])
3034 [(set (match_operand 0 "nonimmediate_operand" "")
3035 (match_operand 1 "general_operand" ""))]
3037 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3038 && GET_MODE (operands[0]) == XFmode
3039 && ! (ANY_FP_REG_P (operands[0]) ||
3040 (GET_CODE (operands[0]) == SUBREG
3041 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3042 && ! (ANY_FP_REG_P (operands[1]) ||
3043 (GET_CODE (operands[1]) == SUBREG
3044 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3046 "ix86_split_long_move (operands); DONE;")
3049 [(set (match_operand 0 "register_operand" "")
3050 (match_operand 1 "memory_operand" ""))]
3052 && MEM_P (operands[1])
3053 && (GET_MODE (operands[0]) == XFmode
3054 || GET_MODE (operands[0]) == SFmode
3055 || GET_MODE (operands[0]) == DFmode)
3056 && constant_pool_reference_p (operands[1])"
3057 [(set (match_dup 0) (match_dup 1))]
3059 rtx c = avoid_constant_pool_reference (operands[1]);
3060 rtx r = operands[0];
3062 if (GET_CODE (r) == SUBREG)
3067 if (!standard_sse_constant_p (c))
3070 else if (FP_REG_P (r))
3072 if (!standard_80387_constant_p (c))
3075 else if (MMX_REG_P (r))
3082 [(set (match_operand 0 "register_operand" "")
3083 (float_extend (match_operand 1 "memory_operand" "")))]
3085 && MEM_P (operands[1])
3086 && (GET_MODE (operands[0]) == XFmode
3087 || GET_MODE (operands[0]) == SFmode
3088 || GET_MODE (operands[0]) == DFmode)
3089 && constant_pool_reference_p (operands[1])"
3090 [(set (match_dup 0) (match_dup 1))]
3092 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3093 rtx r = operands[0];
3095 if (GET_CODE (r) == SUBREG)
3100 if (!standard_sse_constant_p (c))
3103 else if (FP_REG_P (r))
3105 if (!standard_80387_constant_p (c))
3108 else if (MMX_REG_P (r))
3114 (define_insn "swapxf"
3115 [(set (match_operand:XF 0 "register_operand" "+f")
3116 (match_operand:XF 1 "register_operand" "+f"))
3121 if (STACK_TOP_P (operands[0]))
3126 [(set_attr "type" "fxch")
3127 (set_attr "mode" "XF")])
3129 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3131 [(set (match_operand:X87MODEF 0 "register_operand" "")
3132 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3133 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3134 && (standard_80387_constant_p (operands[1]) == 8
3135 || standard_80387_constant_p (operands[1]) == 9)"
3136 [(set (match_dup 0)(match_dup 1))
3138 (neg:X87MODEF (match_dup 0)))]
3142 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3143 if (real_isnegzero (&r))
3144 operands[1] = CONST0_RTX (<MODE>mode);
3146 operands[1] = CONST1_RTX (<MODE>mode);
3149 (define_expand "movtf"
3150 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3151 (match_operand:TF 1 "nonimmediate_operand" ""))]
3154 ix86_expand_move (TFmode, operands);
3158 (define_insn "*movtf_internal"
3159 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3160 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3162 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3164 switch (which_alternative)
3170 if (get_attr_mode (insn) == MODE_V4SF)
3171 return "xorps\t%0, %0";
3173 return "pxor\t%0, %0";
3176 if (get_attr_mode (insn) == MODE_V4SF)
3177 return "movaps\t{%1, %0|%0, %1}";
3179 return "movdqa\t{%1, %0|%0, %1}";
3184 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3186 (cond [(eq_attr "alternative" "2,3")
3188 (ne (symbol_ref "optimize_size")
3190 (const_string "V4SF")
3191 (const_string "TI"))
3192 (eq_attr "alternative" "4")
3194 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3196 (ne (symbol_ref "optimize_size")
3198 (const_string "V4SF")
3199 (const_string "TI"))]
3200 (const_string "DI")))])
3203 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3204 (match_operand:TF 1 "general_operand" ""))]
3205 "reload_completed && !SSE_REG_P (operands[0])
3206 && !SSE_REG_P (operands[1])"
3208 "ix86_split_long_move (operands); DONE;")
3210 ;; Zero extension instructions
3212 (define_expand "zero_extendhisi2"
3213 [(set (match_operand:SI 0 "register_operand" "")
3214 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3217 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3219 operands[1] = force_reg (HImode, operands[1]);
3220 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3225 (define_insn "zero_extendhisi2_and"
3226 [(set (match_operand:SI 0 "register_operand" "=r")
3227 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3228 (clobber (reg:CC FLAGS_REG))]
3229 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3231 [(set_attr "type" "alu1")
3232 (set_attr "mode" "SI")])
3235 [(set (match_operand:SI 0 "register_operand" "")
3236 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3237 (clobber (reg:CC FLAGS_REG))]
3238 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3239 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3240 (clobber (reg:CC FLAGS_REG))])]
3243 (define_insn "*zero_extendhisi2_movzwl"
3244 [(set (match_operand:SI 0 "register_operand" "=r")
3245 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3246 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3247 "movz{wl|x}\t{%1, %0|%0, %1}"
3248 [(set_attr "type" "imovx")
3249 (set_attr "mode" "SI")])
3251 (define_expand "zero_extendqihi2"
3253 [(set (match_operand:HI 0 "register_operand" "")
3254 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3255 (clobber (reg:CC FLAGS_REG))])]
3259 (define_insn "*zero_extendqihi2_and"
3260 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3261 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3262 (clobber (reg:CC FLAGS_REG))]
3263 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3265 [(set_attr "type" "alu1")
3266 (set_attr "mode" "HI")])
3268 (define_insn "*zero_extendqihi2_movzbw_and"
3269 [(set (match_operand:HI 0 "register_operand" "=r,r")
3270 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3271 (clobber (reg:CC FLAGS_REG))]
3272 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3274 [(set_attr "type" "imovx,alu1")
3275 (set_attr "mode" "HI")])
3277 ; zero extend to SImode here to avoid partial register stalls
3278 (define_insn "*zero_extendqihi2_movzbl"
3279 [(set (match_operand:HI 0 "register_operand" "=r")
3280 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3281 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3282 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3283 [(set_attr "type" "imovx")
3284 (set_attr "mode" "SI")])
3286 ;; For the movzbw case strip only the clobber
3288 [(set (match_operand:HI 0 "register_operand" "")
3289 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3290 (clobber (reg:CC FLAGS_REG))]
3292 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3293 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3294 [(set (match_operand:HI 0 "register_operand" "")
3295 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3297 ;; When source and destination does not overlap, clear destination
3298 ;; first and then do the movb
3300 [(set (match_operand:HI 0 "register_operand" "")
3301 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3302 (clobber (reg:CC FLAGS_REG))]
3304 && ANY_QI_REG_P (operands[0])
3305 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3306 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3307 [(set (match_dup 0) (const_int 0))
3308 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3309 "operands[2] = gen_lowpart (QImode, operands[0]);")
3311 ;; Rest is handled by single and.
3313 [(set (match_operand:HI 0 "register_operand" "")
3314 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3315 (clobber (reg:CC FLAGS_REG))]
3317 && true_regnum (operands[0]) == true_regnum (operands[1])"
3318 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3319 (clobber (reg:CC FLAGS_REG))])]
3322 (define_expand "zero_extendqisi2"
3324 [(set (match_operand:SI 0 "register_operand" "")
3325 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3326 (clobber (reg:CC FLAGS_REG))])]
3330 (define_insn "*zero_extendqisi2_and"
3331 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3332 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3333 (clobber (reg:CC FLAGS_REG))]
3334 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3336 [(set_attr "type" "alu1")
3337 (set_attr "mode" "SI")])
3339 (define_insn "*zero_extendqisi2_movzbw_and"
3340 [(set (match_operand:SI 0 "register_operand" "=r,r")
3341 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3342 (clobber (reg:CC FLAGS_REG))]
3343 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3345 [(set_attr "type" "imovx,alu1")
3346 (set_attr "mode" "SI")])
3348 (define_insn "*zero_extendqisi2_movzbw"
3349 [(set (match_operand:SI 0 "register_operand" "=r")
3350 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3351 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3352 "movz{bl|x}\t{%1, %0|%0, %1}"
3353 [(set_attr "type" "imovx")
3354 (set_attr "mode" "SI")])
3356 ;; For the movzbl case strip only the clobber
3358 [(set (match_operand:SI 0 "register_operand" "")
3359 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3360 (clobber (reg:CC FLAGS_REG))]
3362 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3363 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3365 (zero_extend:SI (match_dup 1)))])
3367 ;; When source and destination does not overlap, clear destination
3368 ;; first and then do the movb
3370 [(set (match_operand:SI 0 "register_operand" "")
3371 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3372 (clobber (reg:CC FLAGS_REG))]
3374 && ANY_QI_REG_P (operands[0])
3375 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3376 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3377 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3378 [(set (match_dup 0) (const_int 0))
3379 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3380 "operands[2] = gen_lowpart (QImode, operands[0]);")
3382 ;; Rest is handled by single and.
3384 [(set (match_operand:SI 0 "register_operand" "")
3385 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3386 (clobber (reg:CC FLAGS_REG))]
3388 && true_regnum (operands[0]) == true_regnum (operands[1])"
3389 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3390 (clobber (reg:CC FLAGS_REG))])]
3393 ;; %%% Kill me once multi-word ops are sane.
3394 (define_expand "zero_extendsidi2"
3395 [(set (match_operand:DI 0 "register_operand" "=r")
3396 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3401 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3406 (define_insn "zero_extendsidi2_32"
3407 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3409 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3410 (clobber (reg:CC FLAGS_REG))]
3416 movd\t{%1, %0|%0, %1}
3417 movd\t{%1, %0|%0, %1}
3418 movd\t{%1, %0|%0, %1}
3419 movd\t{%1, %0|%0, %1}"
3420 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3421 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3423 (define_insn "zero_extendsidi2_rex64"
3424 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3426 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3429 mov\t{%k1, %k0|%k0, %k1}
3431 movd\t{%1, %0|%0, %1}
3432 movd\t{%1, %0|%0, %1}
3433 movd\t{%1, %0|%0, %1}
3434 movd\t{%1, %0|%0, %1}"
3435 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3436 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3439 [(set (match_operand:DI 0 "memory_operand" "")
3440 (zero_extend:DI (match_dup 0)))]
3442 [(set (match_dup 4) (const_int 0))]
3443 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3446 [(set (match_operand:DI 0 "register_operand" "")
3447 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3448 (clobber (reg:CC FLAGS_REG))]
3449 "!TARGET_64BIT && reload_completed
3450 && true_regnum (operands[0]) == true_regnum (operands[1])"
3451 [(set (match_dup 4) (const_int 0))]
3452 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3455 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3456 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3457 (clobber (reg:CC FLAGS_REG))]
3458 "!TARGET_64BIT && reload_completed
3459 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3460 [(set (match_dup 3) (match_dup 1))
3461 (set (match_dup 4) (const_int 0))]
3462 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3464 (define_insn "zero_extendhidi2"
3465 [(set (match_operand:DI 0 "register_operand" "=r")
3466 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3468 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3469 [(set_attr "type" "imovx")
3470 (set_attr "mode" "DI")])
3472 (define_insn "zero_extendqidi2"
3473 [(set (match_operand:DI 0 "register_operand" "=r")
3474 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3476 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3477 [(set_attr "type" "imovx")
3478 (set_attr "mode" "DI")])
3480 ;; Sign extension instructions
3482 (define_expand "extendsidi2"
3483 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3484 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3485 (clobber (reg:CC FLAGS_REG))
3486 (clobber (match_scratch:SI 2 ""))])]
3491 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3496 (define_insn "*extendsidi2_1"
3497 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3498 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3499 (clobber (reg:CC FLAGS_REG))
3500 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3504 (define_insn "extendsidi2_rex64"
3505 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3506 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3510 movs{lq|x}\t{%1,%0|%0, %1}"
3511 [(set_attr "type" "imovx")
3512 (set_attr "mode" "DI")
3513 (set_attr "prefix_0f" "0")
3514 (set_attr "modrm" "0,1")])
3516 (define_insn "extendhidi2"
3517 [(set (match_operand:DI 0 "register_operand" "=r")
3518 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3520 "movs{wq|x}\t{%1,%0|%0, %1}"
3521 [(set_attr "type" "imovx")
3522 (set_attr "mode" "DI")])
3524 (define_insn "extendqidi2"
3525 [(set (match_operand:DI 0 "register_operand" "=r")
3526 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3528 "movs{bq|x}\t{%1,%0|%0, %1}"
3529 [(set_attr "type" "imovx")
3530 (set_attr "mode" "DI")])
3532 ;; Extend to memory case when source register does die.
3534 [(set (match_operand:DI 0 "memory_operand" "")
3535 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3536 (clobber (reg:CC FLAGS_REG))
3537 (clobber (match_operand:SI 2 "register_operand" ""))]
3539 && dead_or_set_p (insn, operands[1])
3540 && !reg_mentioned_p (operands[1], operands[0]))"
3541 [(set (match_dup 3) (match_dup 1))
3542 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3543 (clobber (reg:CC FLAGS_REG))])
3544 (set (match_dup 4) (match_dup 1))]
3545 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3547 ;; Extend to memory case when source register does not die.
3549 [(set (match_operand:DI 0 "memory_operand" "")
3550 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3551 (clobber (reg:CC FLAGS_REG))
3552 (clobber (match_operand:SI 2 "register_operand" ""))]
3556 split_di (&operands[0], 1, &operands[3], &operands[4]);
3558 emit_move_insn (operands[3], operands[1]);
3560 /* Generate a cltd if possible and doing so it profitable. */
3561 if (true_regnum (operands[1]) == 0
3562 && true_regnum (operands[2]) == 1
3563 && (optimize_size || TARGET_USE_CLTD))
3565 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3569 emit_move_insn (operands[2], operands[1]);
3570 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3572 emit_move_insn (operands[4], operands[2]);
3576 ;; Extend to register case. Optimize case where source and destination
3577 ;; registers match and cases where we can use cltd.
3579 [(set (match_operand:DI 0 "register_operand" "")
3580 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3581 (clobber (reg:CC FLAGS_REG))
3582 (clobber (match_scratch:SI 2 ""))]
3586 split_di (&operands[0], 1, &operands[3], &operands[4]);
3588 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3589 emit_move_insn (operands[3], operands[1]);
3591 /* Generate a cltd if possible and doing so it profitable. */
3592 if (true_regnum (operands[3]) == 0
3593 && (optimize_size || TARGET_USE_CLTD))
3595 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3599 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3600 emit_move_insn (operands[4], operands[1]);
3602 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3606 (define_insn "extendhisi2"
3607 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3608 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3611 switch (get_attr_prefix_0f (insn))
3614 return "{cwtl|cwde}";
3616 return "movs{wl|x}\t{%1,%0|%0, %1}";
3619 [(set_attr "type" "imovx")
3620 (set_attr "mode" "SI")
3621 (set (attr "prefix_0f")
3622 ;; movsx is short decodable while cwtl is vector decoded.
3623 (if_then_else (and (eq_attr "cpu" "!k6")
3624 (eq_attr "alternative" "0"))
3626 (const_string "1")))
3628 (if_then_else (eq_attr "prefix_0f" "0")
3630 (const_string "1")))])
3632 (define_insn "*extendhisi2_zext"
3633 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3635 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3638 switch (get_attr_prefix_0f (insn))
3641 return "{cwtl|cwde}";
3643 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3646 [(set_attr "type" "imovx")
3647 (set_attr "mode" "SI")
3648 (set (attr "prefix_0f")
3649 ;; movsx is short decodable while cwtl is vector decoded.
3650 (if_then_else (and (eq_attr "cpu" "!k6")
3651 (eq_attr "alternative" "0"))
3653 (const_string "1")))
3655 (if_then_else (eq_attr "prefix_0f" "0")
3657 (const_string "1")))])
3659 (define_insn "extendqihi2"
3660 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3661 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3664 switch (get_attr_prefix_0f (insn))
3667 return "{cbtw|cbw}";
3669 return "movs{bw|x}\t{%1,%0|%0, %1}";
3672 [(set_attr "type" "imovx")
3673 (set_attr "mode" "HI")
3674 (set (attr "prefix_0f")
3675 ;; movsx is short decodable while cwtl is vector decoded.
3676 (if_then_else (and (eq_attr "cpu" "!k6")
3677 (eq_attr "alternative" "0"))
3679 (const_string "1")))
3681 (if_then_else (eq_attr "prefix_0f" "0")
3683 (const_string "1")))])
3685 (define_insn "extendqisi2"
3686 [(set (match_operand:SI 0 "register_operand" "=r")
3687 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3689 "movs{bl|x}\t{%1,%0|%0, %1}"
3690 [(set_attr "type" "imovx")
3691 (set_attr "mode" "SI")])
3693 (define_insn "*extendqisi2_zext"
3694 [(set (match_operand:DI 0 "register_operand" "=r")
3696 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3698 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3699 [(set_attr "type" "imovx")
3700 (set_attr "mode" "SI")])
3702 ;; Conversions between float and double.
3704 ;; These are all no-ops in the model used for the 80387. So just
3707 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3708 (define_insn "*dummy_extendsfdf2"
3709 [(set (match_operand:DF 0 "push_operand" "=<")
3710 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3715 [(set (match_operand:DF 0 "push_operand" "")
3716 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3718 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3719 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3722 [(set (match_operand:DF 0 "push_operand" "")
3723 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3725 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3726 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3728 (define_insn "*dummy_extendsfxf2"
3729 [(set (match_operand:XF 0 "push_operand" "=<")
3730 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3735 [(set (match_operand:XF 0 "push_operand" "")
3736 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3738 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3739 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3740 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3743 [(set (match_operand:XF 0 "push_operand" "")
3744 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3746 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3747 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3748 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3751 [(set (match_operand:XF 0 "push_operand" "")
3752 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3754 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3755 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3756 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3759 [(set (match_operand:XF 0 "push_operand" "")
3760 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3762 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3763 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3764 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3766 (define_expand "extendsfdf2"
3767 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3768 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3769 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3771 /* ??? Needed for compress_float_constant since all fp constants
3772 are LEGITIMATE_CONSTANT_P. */
3773 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3775 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3776 && standard_80387_constant_p (operands[1]) > 0)
3778 operands[1] = simplify_const_unary_operation
3779 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3780 emit_move_insn_1 (operands[0], operands[1]);
3783 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3787 (define_insn "*extendsfdf2_mixed"
3788 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3790 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3791 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3793 switch (which_alternative)
3796 return output_387_reg_move (insn, operands);
3799 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3800 return "fstp%z0\t%y0";
3802 return "fst%z0\t%y0";
3805 return "cvtss2sd\t{%1, %0|%0, %1}";
3811 [(set_attr "type" "fmov,fmov,ssecvt")
3812 (set_attr "mode" "SF,XF,DF")])
3814 (define_insn "*extendsfdf2_sse"
3815 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3816 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3817 "TARGET_SSE2 && TARGET_SSE_MATH"
3818 "cvtss2sd\t{%1, %0|%0, %1}"
3819 [(set_attr "type" "ssecvt")
3820 (set_attr "mode" "DF")])
3822 (define_insn "*extendsfdf2_i387"
3823 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3824 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3827 switch (which_alternative)
3830 return output_387_reg_move (insn, operands);
3833 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834 return "fstp%z0\t%y0";
3836 return "fst%z0\t%y0";
3842 [(set_attr "type" "fmov")
3843 (set_attr "mode" "SF,XF")])
3845 (define_expand "extendsfxf2"
3846 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3847 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3850 /* ??? Needed for compress_float_constant since all fp constants
3851 are LEGITIMATE_CONSTANT_P. */
3852 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3854 if (standard_80387_constant_p (operands[1]) > 0)
3856 operands[1] = simplify_const_unary_operation
3857 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3858 emit_move_insn_1 (operands[0], operands[1]);
3861 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3865 (define_insn "*extendsfxf2_i387"
3866 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3867 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3870 switch (which_alternative)
3873 return output_387_reg_move (insn, operands);
3876 /* There is no non-popping store to memory for XFmode. So if
3877 we need one, follow the store with a load. */
3878 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3879 return "fstp%z0\t%y0";
3881 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3887 [(set_attr "type" "fmov")
3888 (set_attr "mode" "SF,XF")])
3890 (define_expand "extenddfxf2"
3891 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3892 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3895 /* ??? Needed for compress_float_constant since all fp constants
3896 are LEGITIMATE_CONSTANT_P. */
3897 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3899 if (standard_80387_constant_p (operands[1]) > 0)
3901 operands[1] = simplify_const_unary_operation
3902 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3903 emit_move_insn_1 (operands[0], operands[1]);
3906 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3910 (define_insn "*extenddfxf2_i387"
3911 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3912 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3915 switch (which_alternative)
3918 return output_387_reg_move (insn, operands);
3921 /* There is no non-popping store to memory for XFmode. So if
3922 we need one, follow the store with a load. */
3923 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3924 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3926 return "fstp%z0\t%y0";
3932 [(set_attr "type" "fmov")
3933 (set_attr "mode" "DF,XF")])
3935 ;; %%% This seems bad bad news.
3936 ;; This cannot output into an f-reg because there is no way to be sure
3937 ;; of truncating in that case. Otherwise this is just like a simple move
3938 ;; insn. So we pretend we can output to a reg in order to get better
3939 ;; register preferencing, but we really use a stack slot.
3941 ;; Conversion from DFmode to SFmode.
3943 (define_expand "truncdfsf2"
3944 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3946 (match_operand:DF 1 "nonimmediate_operand" "")))]
3947 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3949 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3951 else if (flag_unsafe_math_optimizations)
3955 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3956 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3961 (define_expand "truncdfsf2_with_temp"
3962 [(parallel [(set (match_operand:SF 0 "" "")
3963 (float_truncate:SF (match_operand:DF 1 "" "")))
3964 (clobber (match_operand:SF 2 "" ""))])]
3967 (define_insn "*truncdfsf_fast_mixed"
3968 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3970 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3971 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3973 switch (which_alternative)
3976 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977 return "fstp%z0\t%y0";
3979 return "fst%z0\t%y0";
3981 return output_387_reg_move (insn, operands);
3983 return "cvtsd2ss\t{%1, %0|%0, %1}";
3988 [(set_attr "type" "fmov,fmov,ssecvt")
3989 (set_attr "mode" "SF")])
3991 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3992 ;; because nothing we do here is unsafe.
3993 (define_insn "*truncdfsf_fast_sse"
3994 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3996 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3997 "TARGET_SSE2 && TARGET_SSE_MATH"
3998 "cvtsd2ss\t{%1, %0|%0, %1}"
3999 [(set_attr "type" "ssecvt")
4000 (set_attr "mode" "SF")])
4002 (define_insn "*truncdfsf_fast_i387"
4003 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4005 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4006 "TARGET_80387 && flag_unsafe_math_optimizations"
4007 "* return output_387_reg_move (insn, operands);"
4008 [(set_attr "type" "fmov")
4009 (set_attr "mode" "SF")])
4011 (define_insn "*truncdfsf_mixed"
4012 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4014 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4015 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4016 "TARGET_MIX_SSE_I387"
4018 switch (which_alternative)
4021 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4022 return "fstp%z0\t%y0";
4024 return "fst%z0\t%y0";
4028 return "cvtsd2ss\t{%1, %0|%0, %1}";
4033 [(set_attr "type" "fmov,multi,ssecvt")
4034 (set_attr "unit" "*,i387,*")
4035 (set_attr "mode" "SF")])
4037 (define_insn "*truncdfsf_i387"
4038 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4040 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4041 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4044 switch (which_alternative)
4047 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4048 return "fstp%z0\t%y0";
4050 return "fst%z0\t%y0";
4057 [(set_attr "type" "fmov,multi")
4058 (set_attr "unit" "*,i387")
4059 (set_attr "mode" "SF")])
4061 (define_insn "*truncdfsf2_i387_1"
4062 [(set (match_operand:SF 0 "memory_operand" "=m")
4064 (match_operand:DF 1 "register_operand" "f")))]
4066 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4067 && !TARGET_MIX_SSE_I387"
4069 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4070 return "fstp%z0\t%y0";
4072 return "fst%z0\t%y0";
4074 [(set_attr "type" "fmov")
4075 (set_attr "mode" "SF")])
4078 [(set (match_operand:SF 0 "register_operand" "")
4080 (match_operand:DF 1 "fp_register_operand" "")))
4081 (clobber (match_operand 2 "" ""))]
4083 [(set (match_dup 2) (match_dup 1))
4084 (set (match_dup 0) (match_dup 2))]
4086 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4089 ;; Conversion from XFmode to SFmode.
4091 (define_expand "truncxfsf2"
4092 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4094 (match_operand:XF 1 "register_operand" "")))
4095 (clobber (match_dup 2))])]
4098 if (flag_unsafe_math_optimizations)
4100 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4101 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4102 if (reg != operands[0])
4103 emit_move_insn (operands[0], reg);
4107 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4110 (define_insn "*truncxfsf2_mixed"
4111 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4113 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4114 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4117 gcc_assert (!which_alternative);
4118 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4119 return "fstp%z0\t%y0";
4121 return "fst%z0\t%y0";
4123 [(set_attr "type" "fmov,multi,multi,multi")
4124 (set_attr "unit" "*,i387,i387,i387")
4125 (set_attr "mode" "SF")])
4127 (define_insn "truncxfsf2_i387_noop"
4128 [(set (match_operand:SF 0 "register_operand" "=f")
4129 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4130 "TARGET_80387 && flag_unsafe_math_optimizations"
4131 "* return output_387_reg_move (insn, operands);"
4132 [(set_attr "type" "fmov")
4133 (set_attr "mode" "SF")])
4135 (define_insn "*truncxfsf2_i387"
4136 [(set (match_operand:SF 0 "memory_operand" "=m")
4138 (match_operand:XF 1 "register_operand" "f")))]
4141 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4142 return "fstp%z0\t%y0";
4144 return "fst%z0\t%y0";
4146 [(set_attr "type" "fmov")
4147 (set_attr "mode" "SF")])
4150 [(set (match_operand:SF 0 "register_operand" "")
4152 (match_operand:XF 1 "register_operand" "")))
4153 (clobber (match_operand:SF 2 "memory_operand" ""))]
4154 "TARGET_80387 && reload_completed"
4155 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4156 (set (match_dup 0) (match_dup 2))]
4160 [(set (match_operand:SF 0 "memory_operand" "")
4162 (match_operand:XF 1 "register_operand" "")))
4163 (clobber (match_operand:SF 2 "memory_operand" ""))]
4165 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4168 ;; Conversion from XFmode to DFmode.
4170 (define_expand "truncxfdf2"
4171 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4173 (match_operand:XF 1 "register_operand" "")))
4174 (clobber (match_dup 2))])]
4177 if (flag_unsafe_math_optimizations)
4179 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4180 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4181 if (reg != operands[0])
4182 emit_move_insn (operands[0], reg);
4186 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4189 (define_insn "*truncxfdf2_mixed"
4190 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4192 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4193 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4196 gcc_assert (!which_alternative);
4197 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4198 return "fstp%z0\t%y0";
4200 return "fst%z0\t%y0";
4202 [(set_attr "type" "fmov,multi,multi,multi")
4203 (set_attr "unit" "*,i387,i387,i387")
4204 (set_attr "mode" "DF")])
4206 (define_insn "truncxfdf2_i387_noop"
4207 [(set (match_operand:DF 0 "register_operand" "=f")
4208 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4209 "TARGET_80387 && flag_unsafe_math_optimizations"
4210 "* return output_387_reg_move (insn, operands);"
4211 [(set_attr "type" "fmov")
4212 (set_attr "mode" "DF")])
4214 (define_insn "*truncxfdf2_i387"
4215 [(set (match_operand:DF 0 "memory_operand" "=m")
4217 (match_operand:XF 1 "register_operand" "f")))]
4220 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4221 return "fstp%z0\t%y0";
4223 return "fst%z0\t%y0";
4225 [(set_attr "type" "fmov")
4226 (set_attr "mode" "DF")])
4229 [(set (match_operand:DF 0 "register_operand" "")
4231 (match_operand:XF 1 "register_operand" "")))
4232 (clobber (match_operand:DF 2 "memory_operand" ""))]
4233 "TARGET_80387 && reload_completed"
4234 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4235 (set (match_dup 0) (match_dup 2))]
4239 [(set (match_operand:DF 0 "memory_operand" "")
4241 (match_operand:XF 1 "register_operand" "")))
4242 (clobber (match_operand:DF 2 "memory_operand" ""))]
4244 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4247 ;; Signed conversion to DImode.
4249 (define_expand "fix_truncxfdi2"
4250 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4251 (fix:DI (match_operand:XF 1 "register_operand" "")))
4252 (clobber (reg:CC FLAGS_REG))])]
4257 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4262 (define_expand "fix_trunc<mode>di2"
4263 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4264 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4265 (clobber (reg:CC FLAGS_REG))])]
4266 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4269 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4271 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4274 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4276 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4277 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4278 if (out != operands[0])
4279 emit_move_insn (operands[0], out);
4284 ;; Signed conversion to SImode.
4286 (define_expand "fix_truncxfsi2"
4287 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4288 (fix:SI (match_operand:XF 1 "register_operand" "")))
4289 (clobber (reg:CC FLAGS_REG))])]
4294 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4299 (define_expand "fix_trunc<mode>si2"
4300 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4301 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4302 (clobber (reg:CC FLAGS_REG))])]
4303 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4306 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4308 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4311 if (SSE_FLOAT_MODE_P (<MODE>mode))
4313 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4314 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4315 if (out != operands[0])
4316 emit_move_insn (operands[0], out);
4321 ;; Signed conversion to HImode.
4323 (define_expand "fix_trunc<mode>hi2"
4324 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4325 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4326 (clobber (reg:CC FLAGS_REG))])]
4328 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4332 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4337 ;; Unsigned conversion to SImode.
4339 (define_expand "fixuns_trunc<mode>si2"
4341 [(set (match_operand:SI 0 "register_operand" "")
4343 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4345 (clobber (match_scratch:<ssevecmode> 3 ""))
4346 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4347 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4349 enum machine_mode mode = <MODE>mode;
4350 enum machine_mode vecmode = <ssevecmode>mode;
4351 REAL_VALUE_TYPE TWO31r;
4354 real_ldexp (&TWO31r, &dconst1, 31);
4355 two31 = const_double_from_real_value (TWO31r, mode);
4356 two31 = ix86_build_const_vector (mode, true, two31);
4357 operands[2] = force_reg (vecmode, two31);
4360 (define_insn_and_split "*fixuns_trunc<mode>_1"
4361 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4363 (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4364 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4365 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4366 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4367 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4369 "&& reload_completed"
4372 ix86_split_convert_uns_si_sse (operands);
4376 ;; Unsigned conversion to HImode.
4377 ;; Without these patterns, we'll try the unsigned SI conversion which
4378 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4380 (define_expand "fixuns_truncsfhi2"
4382 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4383 (set (match_operand:HI 0 "nonimmediate_operand" "")
4384 (subreg:HI (match_dup 2) 0))]
4386 "operands[2] = gen_reg_rtx (SImode);")
4388 (define_expand "fixuns_truncdfhi2"
4390 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4391 (set (match_operand:HI 0 "nonimmediate_operand" "")
4392 (subreg:HI (match_dup 2) 0))]
4394 "operands[2] = gen_reg_rtx (SImode);")
4396 ;; When SSE is available, it is always faster to use it!
4397 (define_insn "fix_truncsfdi_sse"
4398 [(set (match_operand:DI 0 "register_operand" "=r,r")
4399 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4400 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4401 "cvttss2si{q}\t{%1, %0|%0, %1}"
4402 [(set_attr "type" "sseicvt")
4403 (set_attr "mode" "SF")
4404 (set_attr "athlon_decode" "double,vector")
4405 (set_attr "amdfam10_decode" "double,double")])
4407 (define_insn "fix_truncdfdi_sse"
4408 [(set (match_operand:DI 0 "register_operand" "=r,r")
4409 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4410 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4411 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4412 [(set_attr "type" "sseicvt")
4413 (set_attr "mode" "DF")
4414 (set_attr "athlon_decode" "double,vector")
4415 (set_attr "amdfam10_decode" "double,double")])
4417 (define_insn "fix_truncsfsi_sse"
4418 [(set (match_operand:SI 0 "register_operand" "=r,r")
4419 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4420 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4421 "cvttss2si\t{%1, %0|%0, %1}"
4422 [(set_attr "type" "sseicvt")
4423 (set_attr "mode" "DF")
4424 (set_attr "athlon_decode" "double,vector")
4425 (set_attr "amdfam10_decode" "double,double")])
4427 (define_insn "fix_truncdfsi_sse"
4428 [(set (match_operand:SI 0 "register_operand" "=r,r")
4429 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4430 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4431 "cvttsd2si\t{%1, %0|%0, %1}"
4432 [(set_attr "type" "sseicvt")
4433 (set_attr "mode" "DF")
4434 (set_attr "athlon_decode" "double,vector")
4435 (set_attr "amdfam10_decode" "double,double")])
4437 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4439 [(set (match_operand:DF 0 "register_operand" "")
4440 (match_operand:DF 1 "memory_operand" ""))
4441 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4442 (fix:SSEMODEI24 (match_dup 0)))]
4444 && peep2_reg_dead_p (2, operands[0])"
4445 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4449 [(set (match_operand:SF 0 "register_operand" "")
4450 (match_operand:SF 1 "memory_operand" ""))
4451 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4452 (fix:SSEMODEI24 (match_dup 0)))]
4454 && peep2_reg_dead_p (2, operands[0])"
4455 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4458 ;; Avoid vector decoded forms of the instruction.
4460 [(match_scratch:DF 2 "Y")
4461 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4462 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4463 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4464 [(set (match_dup 2) (match_dup 1))
4465 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4469 [(match_scratch:SF 2 "x")
4470 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4471 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4472 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4473 [(set (match_dup 2) (match_dup 1))
4474 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4477 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4478 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4479 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4481 && FLOAT_MODE_P (GET_MODE (operands[1]))
4482 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4483 && (TARGET_64BIT || <MODE>mode != DImode))
4485 && !(reload_completed || reload_in_progress)"
4490 if (memory_operand (operands[0], VOIDmode))
4491 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4494 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4495 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4501 [(set_attr "type" "fisttp")
4502 (set_attr "mode" "<MODE>")])
4504 (define_insn "fix_trunc<mode>_i387_fisttp"
4505 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4506 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4507 (clobber (match_scratch:XF 2 "=&1f"))]
4509 && FLOAT_MODE_P (GET_MODE (operands[1]))
4510 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4511 && (TARGET_64BIT || <MODE>mode != DImode))
4512 && TARGET_SSE_MATH)"
4513 "* return output_fix_trunc (insn, operands, 1);"
4514 [(set_attr "type" "fisttp")
4515 (set_attr "mode" "<MODE>")])
4517 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4518 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4519 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4520 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4521 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4523 && FLOAT_MODE_P (GET_MODE (operands[1]))
4524 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4525 && (TARGET_64BIT || <MODE>mode != DImode))
4526 && TARGET_SSE_MATH)"
4528 [(set_attr "type" "fisttp")
4529 (set_attr "mode" "<MODE>")])
4532 [(set (match_operand:X87MODEI 0 "register_operand" "")
4533 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4534 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4535 (clobber (match_scratch 3 ""))]
4537 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4538 (clobber (match_dup 3))])
4539 (set (match_dup 0) (match_dup 2))]
4543 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4544 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4545 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4546 (clobber (match_scratch 3 ""))]
4548 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4549 (clobber (match_dup 3))])]
4552 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4553 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4554 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4555 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4556 ;; function in i386.c.
4557 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4558 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4559 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4560 (clobber (reg:CC FLAGS_REG))]
4561 "TARGET_80387 && !TARGET_FISTTP
4562 && FLOAT_MODE_P (GET_MODE (operands[1]))
4563 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && (TARGET_64BIT || <MODE>mode != DImode))
4565 && !(reload_completed || reload_in_progress)"
4570 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4572 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4573 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4574 if (memory_operand (operands[0], VOIDmode))
4575 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4576 operands[2], operands[3]));
4579 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4580 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4581 operands[2], operands[3],
4586 [(set_attr "type" "fistp")
4587 (set_attr "i387_cw" "trunc")
4588 (set_attr "mode" "<MODE>")])
4590 (define_insn "fix_truncdi_i387"
4591 [(set (match_operand:DI 0 "memory_operand" "=m")
4592 (fix:DI (match_operand 1 "register_operand" "f")))
4593 (use (match_operand:HI 2 "memory_operand" "m"))
4594 (use (match_operand:HI 3 "memory_operand" "m"))
4595 (clobber (match_scratch:XF 4 "=&1f"))]
4596 "TARGET_80387 && !TARGET_FISTTP
4597 && FLOAT_MODE_P (GET_MODE (operands[1]))
4598 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4599 "* return output_fix_trunc (insn, operands, 0);"
4600 [(set_attr "type" "fistp")
4601 (set_attr "i387_cw" "trunc")
4602 (set_attr "mode" "DI")])
4604 (define_insn "fix_truncdi_i387_with_temp"
4605 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4606 (fix:DI (match_operand 1 "register_operand" "f,f")))
4607 (use (match_operand:HI 2 "memory_operand" "m,m"))
4608 (use (match_operand:HI 3 "memory_operand" "m,m"))
4609 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4610 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4611 "TARGET_80387 && !TARGET_FISTTP
4612 && FLOAT_MODE_P (GET_MODE (operands[1]))
4613 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4615 [(set_attr "type" "fistp")
4616 (set_attr "i387_cw" "trunc")
4617 (set_attr "mode" "DI")])
4620 [(set (match_operand:DI 0 "register_operand" "")
4621 (fix:DI (match_operand 1 "register_operand" "")))
4622 (use (match_operand:HI 2 "memory_operand" ""))
4623 (use (match_operand:HI 3 "memory_operand" ""))
4624 (clobber (match_operand:DI 4 "memory_operand" ""))
4625 (clobber (match_scratch 5 ""))]
4627 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4630 (clobber (match_dup 5))])
4631 (set (match_dup 0) (match_dup 4))]
4635 [(set (match_operand:DI 0 "memory_operand" "")
4636 (fix:DI (match_operand 1 "register_operand" "")))
4637 (use (match_operand:HI 2 "memory_operand" ""))
4638 (use (match_operand:HI 3 "memory_operand" ""))
4639 (clobber (match_operand:DI 4 "memory_operand" ""))
4640 (clobber (match_scratch 5 ""))]
4642 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4645 (clobber (match_dup 5))])]
4648 (define_insn "fix_trunc<mode>_i387"
4649 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4650 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4651 (use (match_operand:HI 2 "memory_operand" "m"))
4652 (use (match_operand:HI 3 "memory_operand" "m"))]
4653 "TARGET_80387 && !TARGET_FISTTP
4654 && FLOAT_MODE_P (GET_MODE (operands[1]))
4655 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4656 "* return output_fix_trunc (insn, operands, 0);"
4657 [(set_attr "type" "fistp")
4658 (set_attr "i387_cw" "trunc")
4659 (set_attr "mode" "<MODE>")])
4661 (define_insn "fix_trunc<mode>_i387_with_temp"
4662 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4663 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4664 (use (match_operand:HI 2 "memory_operand" "m,m"))
4665 (use (match_operand:HI 3 "memory_operand" "m,m"))
4666 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4667 "TARGET_80387 && !TARGET_FISTTP
4668 && FLOAT_MODE_P (GET_MODE (operands[1]))
4669 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4671 [(set_attr "type" "fistp")
4672 (set_attr "i387_cw" "trunc")
4673 (set_attr "mode" "<MODE>")])
4676 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4677 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4678 (use (match_operand:HI 2 "memory_operand" ""))
4679 (use (match_operand:HI 3 "memory_operand" ""))
4680 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4682 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4684 (use (match_dup 3))])
4685 (set (match_dup 0) (match_dup 4))]
4689 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4690 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4691 (use (match_operand:HI 2 "memory_operand" ""))
4692 (use (match_operand:HI 3 "memory_operand" ""))
4693 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4695 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4697 (use (match_dup 3))])]
4700 (define_insn "x86_fnstcw_1"
4701 [(set (match_operand:HI 0 "memory_operand" "=m")
4702 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4705 [(set_attr "length" "2")
4706 (set_attr "mode" "HI")
4707 (set_attr "unit" "i387")])
4709 (define_insn "x86_fldcw_1"
4710 [(set (reg:HI FPCR_REG)
4711 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4714 [(set_attr "length" "2")
4715 (set_attr "mode" "HI")
4716 (set_attr "unit" "i387")
4717 (set_attr "athlon_decode" "vector")
4718 (set_attr "amdfam10_decode" "vector")])
4720 ;; Conversion between fixed point and floating point.
4722 ;; Even though we only accept memory inputs, the backend _really_
4723 ;; wants to be able to do this between registers.
4725 (define_expand "floathisf2"
4726 [(set (match_operand:SF 0 "register_operand" "")
4727 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4728 "TARGET_80387 || TARGET_SSE_MATH"
4730 if (TARGET_SSE_MATH)
4732 emit_insn (gen_floatsisf2 (operands[0],
4733 convert_to_mode (SImode, operands[1], 0)));
4738 (define_insn "*floathisf2_i387"
4739 [(set (match_operand:SF 0 "register_operand" "=f,f")
4740 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4741 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4745 [(set_attr "type" "fmov,multi")
4746 (set_attr "mode" "SF")
4747 (set_attr "unit" "*,i387")
4748 (set_attr "fp_int_src" "true")])
4750 (define_expand "floatsisf2"
4751 [(set (match_operand:SF 0 "register_operand" "")
4752 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4753 "TARGET_80387 || TARGET_SSE_MATH"
4756 (define_insn "*floatsisf2_mixed"
4757 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4758 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4759 "TARGET_MIX_SSE_I387"
4763 cvtsi2ss\t{%1, %0|%0, %1}
4764 cvtsi2ss\t{%1, %0|%0, %1}"
4765 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4766 (set_attr "mode" "SF")
4767 (set_attr "unit" "*,i387,*,*")
4768 (set_attr "athlon_decode" "*,*,vector,double")
4769 (set_attr "amdfam10_decode" "*,*,vector,double")
4770 (set_attr "fp_int_src" "true")])
4772 (define_insn "*floatsisf2_sse"
4773 [(set (match_operand:SF 0 "register_operand" "=x,x")
4774 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4776 "cvtsi2ss\t{%1, %0|%0, %1}"
4777 [(set_attr "type" "sseicvt")
4778 (set_attr "mode" "SF")
4779 (set_attr "athlon_decode" "vector,double")
4780 (set_attr "amdfam10_decode" "vector,double")
4781 (set_attr "fp_int_src" "true")])
4783 (define_insn "*floatsisf2_i387"
4784 [(set (match_operand:SF 0 "register_operand" "=f,f")
4785 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4790 [(set_attr "type" "fmov,multi")
4791 (set_attr "mode" "SF")
4792 (set_attr "unit" "*,i387")
4793 (set_attr "fp_int_src" "true")])
4795 (define_expand "floatdisf2"
4796 [(set (match_operand:SF 0 "register_operand" "")
4797 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4798 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4801 (define_insn "*floatdisf2_mixed"
4802 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4803 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4804 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4808 cvtsi2ss{q}\t{%1, %0|%0, %1}
4809 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4810 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4811 (set_attr "mode" "SF")
4812 (set_attr "unit" "*,i387,*,*")
4813 (set_attr "athlon_decode" "*,*,vector,double")
4814 (set_attr "amdfam10_decode" "*,*,vector,double")
4815 (set_attr "fp_int_src" "true")])
4817 (define_insn "*floatdisf2_sse"
4818 [(set (match_operand:SF 0 "register_operand" "=x,x")
4819 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4820 "TARGET_64BIT && TARGET_SSE_MATH"
4821 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4822 [(set_attr "type" "sseicvt")
4823 (set_attr "mode" "SF")
4824 (set_attr "athlon_decode" "vector,double")
4825 (set_attr "amdfam10_decode" "vector,double")
4826 (set_attr "fp_int_src" "true")])
4828 (define_insn "*floatdisf2_i387"
4829 [(set (match_operand:SF 0 "register_operand" "=f,f")
4830 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4835 [(set_attr "type" "fmov,multi")
4836 (set_attr "mode" "SF")
4837 (set_attr "unit" "*,i387")
4838 (set_attr "fp_int_src" "true")])
4840 (define_expand "floathidf2"
4841 [(set (match_operand:DF 0 "register_operand" "")
4842 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4843 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4845 if (TARGET_SSE2 && TARGET_SSE_MATH)
4847 emit_insn (gen_floatsidf2 (operands[0],
4848 convert_to_mode (SImode, operands[1], 0)));
4853 (define_insn "*floathidf2_i387"
4854 [(set (match_operand:DF 0 "register_operand" "=f,f")
4855 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4856 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4860 [(set_attr "type" "fmov,multi")
4861 (set_attr "mode" "DF")
4862 (set_attr "unit" "*,i387")
4863 (set_attr "fp_int_src" "true")])
4865 (define_expand "floatsidf2"
4866 [(set (match_operand:DF 0 "register_operand" "")
4867 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4868 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4871 (define_insn "*floatsidf2_mixed"
4872 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4873 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4874 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4878 cvtsi2sd\t{%1, %0|%0, %1}
4879 cvtsi2sd\t{%1, %0|%0, %1}"
4880 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4881 (set_attr "mode" "DF")
4882 (set_attr "unit" "*,i387,*,*")
4883 (set_attr "athlon_decode" "*,*,double,direct")
4884 (set_attr "amdfam10_decode" "*,*,vector,double")
4885 (set_attr "fp_int_src" "true")])
4887 (define_insn "*floatsidf2_sse"
4888 [(set (match_operand:DF 0 "register_operand" "=x,x")
4889 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4890 "TARGET_SSE2 && TARGET_SSE_MATH"
4891 "cvtsi2sd\t{%1, %0|%0, %1}"
4892 [(set_attr "type" "sseicvt")
4893 (set_attr "mode" "DF")
4894 (set_attr "athlon_decode" "double,direct")
4895 (set_attr "amdfam10_decode" "vector,double")
4896 (set_attr "fp_int_src" "true")])
4898 (define_insn "*floatsidf2_i387"
4899 [(set (match_operand:DF 0 "register_operand" "=f,f")
4900 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4905 [(set_attr "type" "fmov,multi")
4906 (set_attr "mode" "DF")
4907 (set_attr "unit" "*,i387")
4908 (set_attr "fp_int_src" "true")])
4910 (define_expand "floatdidf2"
4911 [(set (match_operand:DF 0 "register_operand" "")
4912 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4913 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4915 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4917 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4922 (define_insn "*floatdidf2_mixed"
4923 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4924 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4925 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4929 cvtsi2sd{q}\t{%1, %0|%0, %1}
4930 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4931 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4932 (set_attr "mode" "DF")
4933 (set_attr "unit" "*,i387,*,*")
4934 (set_attr "athlon_decode" "*,*,double,direct")
4935 (set_attr "amdfam10_decode" "*,*,vector,double")
4936 (set_attr "fp_int_src" "true")])
4938 (define_insn "*floatdidf2_sse"
4939 [(set (match_operand:DF 0 "register_operand" "=x,x")
4940 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4941 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4942 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4943 [(set_attr "type" "sseicvt")
4944 (set_attr "mode" "DF")
4945 (set_attr "athlon_decode" "double,direct")
4946 (set_attr "amdfam10_decode" "vector,double")
4947 (set_attr "fp_int_src" "true")])
4949 (define_insn "*floatdidf2_i387"
4950 [(set (match_operand:DF 0 "register_operand" "=f,f")
4951 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4956 [(set_attr "type" "fmov,multi")
4957 (set_attr "mode" "DF")
4958 (set_attr "unit" "*,i387")
4959 (set_attr "fp_int_src" "true")])
4961 (define_insn "floathixf2"
4962 [(set (match_operand:XF 0 "register_operand" "=f,f")
4963 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4968 [(set_attr "type" "fmov,multi")
4969 (set_attr "mode" "XF")
4970 (set_attr "unit" "*,i387")
4971 (set_attr "fp_int_src" "true")])
4973 (define_insn "floatsixf2"
4974 [(set (match_operand:XF 0 "register_operand" "=f,f")
4975 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4980 [(set_attr "type" "fmov,multi")
4981 (set_attr "mode" "XF")
4982 (set_attr "unit" "*,i387")
4983 (set_attr "fp_int_src" "true")])
4985 (define_insn "floatdixf2"
4986 [(set (match_operand:XF 0 "register_operand" "=f,f")
4987 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4992 [(set_attr "type" "fmov,multi")
4993 (set_attr "mode" "XF")
4994 (set_attr "unit" "*,i387")
4995 (set_attr "fp_int_src" "true")])
4997 ;; %%% Kill these when reload knows how to do it.
4999 [(set (match_operand 0 "fp_register_operand" "")
5000 (float (match_operand 1 "register_operand" "")))]
5003 && FLOAT_MODE_P (GET_MODE (operands[0]))"
5006 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5007 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5008 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5009 ix86_free_from_memory (GET_MODE (operands[1]));
5013 (define_expand "floatunssisf2"
5014 [(use (match_operand:SF 0 "register_operand" ""))
5015 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5018 if (TARGET_SSE_MATH && TARGET_SSE2)
5019 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5021 x86_emit_floatuns (operands);
5025 (define_expand "floatunssidf2"
5026 [(use (match_operand:DF 0 "register_operand" ""))
5027 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5028 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5029 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5031 (define_expand "floatunsdisf2"
5032 [(use (match_operand:SF 0 "register_operand" ""))
5033 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5034 "TARGET_64BIT && TARGET_SSE_MATH"
5035 "x86_emit_floatuns (operands); DONE;")
5037 (define_expand "floatunsdidf2"
5038 [(use (match_operand:DF 0 "register_operand" ""))
5039 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5040 "TARGET_SSE_MATH && TARGET_SSE2
5041 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5044 x86_emit_floatuns (operands);
5046 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5050 ;; SSE extract/set expanders
5055 ;; %%% splits for addditi3
5057 (define_expand "addti3"
5058 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5059 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5060 (match_operand:TI 2 "x86_64_general_operand" "")))
5061 (clobber (reg:CC FLAGS_REG))]
5063 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5065 (define_insn "*addti3_1"
5066 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5067 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5068 (match_operand:TI 2 "general_operand" "roiF,riF")))
5069 (clobber (reg:CC FLAGS_REG))]
5070 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5074 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5075 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5076 (match_operand:TI 2 "general_operand" "")))
5077 (clobber (reg:CC FLAGS_REG))]
5078 "TARGET_64BIT && reload_completed"
5079 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5081 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5082 (parallel [(set (match_dup 3)
5083 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5086 (clobber (reg:CC FLAGS_REG))])]
5087 "split_ti (operands+0, 1, operands+0, operands+3);
5088 split_ti (operands+1, 1, operands+1, operands+4);
5089 split_ti (operands+2, 1, operands+2, operands+5);")
5091 ;; %%% splits for addsidi3
5092 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5093 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5094 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5096 (define_expand "adddi3"
5097 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5098 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5099 (match_operand:DI 2 "x86_64_general_operand" "")))
5100 (clobber (reg:CC FLAGS_REG))]
5102 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5104 (define_insn "*adddi3_1"
5105 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5106 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5107 (match_operand:DI 2 "general_operand" "roiF,riF")))
5108 (clobber (reg:CC FLAGS_REG))]
5109 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5113 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5114 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5115 (match_operand:DI 2 "general_operand" "")))
5116 (clobber (reg:CC FLAGS_REG))]
5117 "!TARGET_64BIT && reload_completed"
5118 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5120 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5121 (parallel [(set (match_dup 3)
5122 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5125 (clobber (reg:CC FLAGS_REG))])]
5126 "split_di (operands+0, 1, operands+0, operands+3);
5127 split_di (operands+1, 1, operands+1, operands+4);
5128 split_di (operands+2, 1, operands+2, operands+5);")
5130 (define_insn "adddi3_carry_rex64"
5131 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5132 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5133 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5134 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5135 (clobber (reg:CC FLAGS_REG))]
5136 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5137 "adc{q}\t{%2, %0|%0, %2}"
5138 [(set_attr "type" "alu")
5139 (set_attr "pent_pair" "pu")
5140 (set_attr "mode" "DI")])
5142 (define_insn "*adddi3_cc_rex64"
5143 [(set (reg:CC FLAGS_REG)
5144 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5145 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5147 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5148 (plus:DI (match_dup 1) (match_dup 2)))]
5149 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5150 "add{q}\t{%2, %0|%0, %2}"
5151 [(set_attr "type" "alu")
5152 (set_attr "mode" "DI")])
5154 (define_insn "addqi3_carry"
5155 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5156 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5157 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5158 (match_operand:QI 2 "general_operand" "qi,qm")))
5159 (clobber (reg:CC FLAGS_REG))]
5160 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5161 "adc{b}\t{%2, %0|%0, %2}"
5162 [(set_attr "type" "alu")
5163 (set_attr "pent_pair" "pu")
5164 (set_attr "mode" "QI")])
5166 (define_insn "addhi3_carry"
5167 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5168 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5169 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5170 (match_operand:HI 2 "general_operand" "ri,rm")))
5171 (clobber (reg:CC FLAGS_REG))]
5172 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5173 "adc{w}\t{%2, %0|%0, %2}"
5174 [(set_attr "type" "alu")
5175 (set_attr "pent_pair" "pu")
5176 (set_attr "mode" "HI")])
5178 (define_insn "addsi3_carry"
5179 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5180 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5181 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5182 (match_operand:SI 2 "general_operand" "ri,rm")))
5183 (clobber (reg:CC FLAGS_REG))]
5184 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5185 "adc{l}\t{%2, %0|%0, %2}"
5186 [(set_attr "type" "alu")
5187 (set_attr "pent_pair" "pu")
5188 (set_attr "mode" "SI")])
5190 (define_insn "*addsi3_carry_zext"
5191 [(set (match_operand:DI 0 "register_operand" "=r")
5193 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5194 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5195 (match_operand:SI 2 "general_operand" "rim"))))
5196 (clobber (reg:CC FLAGS_REG))]
5197 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5198 "adc{l}\t{%2, %k0|%k0, %2}"
5199 [(set_attr "type" "alu")
5200 (set_attr "pent_pair" "pu")
5201 (set_attr "mode" "SI")])
5203 (define_insn "*addsi3_cc"
5204 [(set (reg:CC FLAGS_REG)
5205 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5206 (match_operand:SI 2 "general_operand" "ri,rm")]
5208 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5209 (plus:SI (match_dup 1) (match_dup 2)))]
5210 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5211 "add{l}\t{%2, %0|%0, %2}"
5212 [(set_attr "type" "alu")
5213 (set_attr "mode" "SI")])
5215 (define_insn "addqi3_cc"
5216 [(set (reg:CC FLAGS_REG)
5217 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5218 (match_operand:QI 2 "general_operand" "qi,qm")]
5220 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5221 (plus:QI (match_dup 1) (match_dup 2)))]
5222 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5223 "add{b}\t{%2, %0|%0, %2}"
5224 [(set_attr "type" "alu")
5225 (set_attr "mode" "QI")])
5227 (define_expand "addsi3"
5228 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5229 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5230 (match_operand:SI 2 "general_operand" "")))
5231 (clobber (reg:CC FLAGS_REG))])]
5233 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5235 (define_insn "*lea_1"
5236 [(set (match_operand:SI 0 "register_operand" "=r")
5237 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5239 "lea{l}\t{%a1, %0|%0, %a1}"
5240 [(set_attr "type" "lea")
5241 (set_attr "mode" "SI")])
5243 (define_insn "*lea_1_rex64"
5244 [(set (match_operand:SI 0 "register_operand" "=r")
5245 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5247 "lea{l}\t{%a1, %0|%0, %a1}"
5248 [(set_attr "type" "lea")
5249 (set_attr "mode" "SI")])
5251 (define_insn "*lea_1_zext"
5252 [(set (match_operand:DI 0 "register_operand" "=r")
5254 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5256 "lea{l}\t{%a1, %k0|%k0, %a1}"
5257 [(set_attr "type" "lea")
5258 (set_attr "mode" "SI")])
5260 (define_insn "*lea_2_rex64"
5261 [(set (match_operand:DI 0 "register_operand" "=r")
5262 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5264 "lea{q}\t{%a1, %0|%0, %a1}"
5265 [(set_attr "type" "lea")
5266 (set_attr "mode" "DI")])
5268 ;; The lea patterns for non-Pmodes needs to be matched by several
5269 ;; insns converted to real lea by splitters.
5271 (define_insn_and_split "*lea_general_1"
5272 [(set (match_operand 0 "register_operand" "=r")
5273 (plus (plus (match_operand 1 "index_register_operand" "l")
5274 (match_operand 2 "register_operand" "r"))
5275 (match_operand 3 "immediate_operand" "i")))]
5276 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5277 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5278 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5279 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5280 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5281 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5282 || GET_MODE (operands[3]) == VOIDmode)"
5284 "&& reload_completed"
5288 operands[0] = gen_lowpart (SImode, operands[0]);
5289 operands[1] = gen_lowpart (Pmode, operands[1]);
5290 operands[2] = gen_lowpart (Pmode, operands[2]);
5291 operands[3] = gen_lowpart (Pmode, operands[3]);
5292 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5294 if (Pmode != SImode)
5295 pat = gen_rtx_SUBREG (SImode, pat, 0);
5296 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5299 [(set_attr "type" "lea")
5300 (set_attr "mode" "SI")])
5302 (define_insn_and_split "*lea_general_1_zext"
5303 [(set (match_operand:DI 0 "register_operand" "=r")
5305 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5306 (match_operand:SI 2 "register_operand" "r"))
5307 (match_operand:SI 3 "immediate_operand" "i"))))]
5310 "&& reload_completed"
5312 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5314 (match_dup 3)) 0)))]
5316 operands[1] = gen_lowpart (Pmode, operands[1]);
5317 operands[2] = gen_lowpart (Pmode, operands[2]);
5318 operands[3] = gen_lowpart (Pmode, operands[3]);
5320 [(set_attr "type" "lea")
5321 (set_attr "mode" "SI")])
5323 (define_insn_and_split "*lea_general_2"
5324 [(set (match_operand 0 "register_operand" "=r")
5325 (plus (mult (match_operand 1 "index_register_operand" "l")
5326 (match_operand 2 "const248_operand" "i"))
5327 (match_operand 3 "nonmemory_operand" "ri")))]
5328 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5329 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5330 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5331 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5332 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5333 || GET_MODE (operands[3]) == VOIDmode)"
5335 "&& reload_completed"
5339 operands[0] = gen_lowpart (SImode, operands[0]);
5340 operands[1] = gen_lowpart (Pmode, operands[1]);
5341 operands[3] = gen_lowpart (Pmode, operands[3]);
5342 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5344 if (Pmode != SImode)
5345 pat = gen_rtx_SUBREG (SImode, pat, 0);
5346 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5349 [(set_attr "type" "lea")
5350 (set_attr "mode" "SI")])
5352 (define_insn_and_split "*lea_general_2_zext"
5353 [(set (match_operand:DI 0 "register_operand" "=r")
5355 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5356 (match_operand:SI 2 "const248_operand" "n"))
5357 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5360 "&& reload_completed"
5362 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5364 (match_dup 3)) 0)))]
5366 operands[1] = gen_lowpart (Pmode, operands[1]);
5367 operands[3] = gen_lowpart (Pmode, operands[3]);
5369 [(set_attr "type" "lea")
5370 (set_attr "mode" "SI")])
5372 (define_insn_and_split "*lea_general_3"
5373 [(set (match_operand 0 "register_operand" "=r")
5374 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5375 (match_operand 2 "const248_operand" "i"))
5376 (match_operand 3 "register_operand" "r"))
5377 (match_operand 4 "immediate_operand" "i")))]
5378 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5379 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5380 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5381 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5382 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5384 "&& reload_completed"
5388 operands[0] = gen_lowpart (SImode, operands[0]);
5389 operands[1] = gen_lowpart (Pmode, operands[1]);
5390 operands[3] = gen_lowpart (Pmode, operands[3]);
5391 operands[4] = gen_lowpart (Pmode, operands[4]);
5392 pat = gen_rtx_PLUS (Pmode,
5393 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5397 if (Pmode != SImode)
5398 pat = gen_rtx_SUBREG (SImode, pat, 0);
5399 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5402 [(set_attr "type" "lea")
5403 (set_attr "mode" "SI")])
5405 (define_insn_and_split "*lea_general_3_zext"
5406 [(set (match_operand:DI 0 "register_operand" "=r")
5408 (plus:SI (plus:SI (mult:SI
5409 (match_operand:SI 1 "index_register_operand" "l")
5410 (match_operand:SI 2 "const248_operand" "n"))
5411 (match_operand:SI 3 "register_operand" "r"))
5412 (match_operand:SI 4 "immediate_operand" "i"))))]
5415 "&& reload_completed"
5417 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5420 (match_dup 4)) 0)))]
5422 operands[1] = gen_lowpart (Pmode, operands[1]);
5423 operands[3] = gen_lowpart (Pmode, operands[3]);
5424 operands[4] = gen_lowpart (Pmode, operands[4]);
5426 [(set_attr "type" "lea")
5427 (set_attr "mode" "SI")])
5429 (define_insn "*adddi_1_rex64"
5430 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5431 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5432 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5433 (clobber (reg:CC FLAGS_REG))]
5434 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5436 switch (get_attr_type (insn))
5439 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5440 return "lea{q}\t{%a2, %0|%0, %a2}";
5443 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5444 if (operands[2] == const1_rtx)
5445 return "inc{q}\t%0";
5448 gcc_assert (operands[2] == constm1_rtx);
5449 return "dec{q}\t%0";
5453 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5455 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5456 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5457 if (CONST_INT_P (operands[2])
5458 /* Avoid overflows. */
5459 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5460 && (INTVAL (operands[2]) == 128
5461 || (INTVAL (operands[2]) < 0
5462 && INTVAL (operands[2]) != -128)))
5464 operands[2] = GEN_INT (-INTVAL (operands[2]));
5465 return "sub{q}\t{%2, %0|%0, %2}";
5467 return "add{q}\t{%2, %0|%0, %2}";
5471 (cond [(eq_attr "alternative" "2")
5472 (const_string "lea")
5473 ; Current assemblers are broken and do not allow @GOTOFF in
5474 ; ought but a memory context.
5475 (match_operand:DI 2 "pic_symbolic_operand" "")
5476 (const_string "lea")
5477 (match_operand:DI 2 "incdec_operand" "")
5478 (const_string "incdec")
5480 (const_string "alu")))
5481 (set_attr "mode" "DI")])
5483 ;; Convert lea to the lea pattern to avoid flags dependency.
5485 [(set (match_operand:DI 0 "register_operand" "")
5486 (plus:DI (match_operand:DI 1 "register_operand" "")
5487 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5488 (clobber (reg:CC FLAGS_REG))]
5489 "TARGET_64BIT && reload_completed
5490 && true_regnum (operands[0]) != true_regnum (operands[1])"
5492 (plus:DI (match_dup 1)
5496 (define_insn "*adddi_2_rex64"
5497 [(set (reg FLAGS_REG)
5499 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5500 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5502 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5503 (plus:DI (match_dup 1) (match_dup 2)))]
5504 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5505 && ix86_binary_operator_ok (PLUS, DImode, operands)
5506 /* Current assemblers are broken and do not allow @GOTOFF in
5507 ought but a memory context. */
5508 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5510 switch (get_attr_type (insn))
5513 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5514 if (operands[2] == const1_rtx)
5515 return "inc{q}\t%0";
5518 gcc_assert (operands[2] == constm1_rtx);
5519 return "dec{q}\t%0";
5523 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5524 /* ???? We ought to handle there the 32bit case too
5525 - do we need new constraint? */
5526 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5527 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5528 if (CONST_INT_P (operands[2])
5529 /* Avoid overflows. */
5530 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5531 && (INTVAL (operands[2]) == 128
5532 || (INTVAL (operands[2]) < 0
5533 && INTVAL (operands[2]) != -128)))
5535 operands[2] = GEN_INT (-INTVAL (operands[2]));
5536 return "sub{q}\t{%2, %0|%0, %2}";
5538 return "add{q}\t{%2, %0|%0, %2}";
5542 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5543 (const_string "incdec")
5544 (const_string "alu")))
5545 (set_attr "mode" "DI")])
5547 (define_insn "*adddi_3_rex64"
5548 [(set (reg FLAGS_REG)
5549 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5550 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5551 (clobber (match_scratch:DI 0 "=r"))]
5553 && ix86_match_ccmode (insn, CCZmode)
5554 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5555 /* Current assemblers are broken and do not allow @GOTOFF in
5556 ought but a memory context. */
5557 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5559 switch (get_attr_type (insn))
5562 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5563 if (operands[2] == const1_rtx)
5564 return "inc{q}\t%0";
5567 gcc_assert (operands[2] == constm1_rtx);
5568 return "dec{q}\t%0";
5572 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5573 /* ???? We ought to handle there the 32bit case too
5574 - do we need new constraint? */
5575 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5576 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5577 if (CONST_INT_P (operands[2])
5578 /* Avoid overflows. */
5579 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5580 && (INTVAL (operands[2]) == 128
5581 || (INTVAL (operands[2]) < 0
5582 && INTVAL (operands[2]) != -128)))
5584 operands[2] = GEN_INT (-INTVAL (operands[2]));
5585 return "sub{q}\t{%2, %0|%0, %2}";
5587 return "add{q}\t{%2, %0|%0, %2}";
5591 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5592 (const_string "incdec")
5593 (const_string "alu")))
5594 (set_attr "mode" "DI")])
5596 ; For comparisons against 1, -1 and 128, we may generate better code
5597 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5598 ; is matched then. We can't accept general immediate, because for
5599 ; case of overflows, the result is messed up.
5600 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5602 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5603 ; only for comparisons not depending on it.
5604 (define_insn "*adddi_4_rex64"
5605 [(set (reg FLAGS_REG)
5606 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5607 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5608 (clobber (match_scratch:DI 0 "=rm"))]
5610 && ix86_match_ccmode (insn, CCGCmode)"
5612 switch (get_attr_type (insn))
5615 if (operands[2] == constm1_rtx)
5616 return "inc{q}\t%0";
5619 gcc_assert (operands[2] == const1_rtx);
5620 return "dec{q}\t%0";
5624 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5625 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5626 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5627 if ((INTVAL (operands[2]) == -128
5628 || (INTVAL (operands[2]) > 0
5629 && INTVAL (operands[2]) != 128))
5630 /* Avoid overflows. */
5631 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5632 return "sub{q}\t{%2, %0|%0, %2}";
5633 operands[2] = GEN_INT (-INTVAL (operands[2]));
5634 return "add{q}\t{%2, %0|%0, %2}";
5638 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5639 (const_string "incdec")
5640 (const_string "alu")))
5641 (set_attr "mode" "DI")])
5643 (define_insn "*adddi_5_rex64"
5644 [(set (reg FLAGS_REG)
5646 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5647 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5649 (clobber (match_scratch:DI 0 "=r"))]
5651 && ix86_match_ccmode (insn, CCGOCmode)
5652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5653 /* Current assemblers are broken and do not allow @GOTOFF in
5654 ought but a memory context. */
5655 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5657 switch (get_attr_type (insn))
5660 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5661 if (operands[2] == const1_rtx)
5662 return "inc{q}\t%0";
5665 gcc_assert (operands[2] == constm1_rtx);
5666 return "dec{q}\t%0";
5670 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5671 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5672 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5673 if (CONST_INT_P (operands[2])
5674 /* Avoid overflows. */
5675 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5676 && (INTVAL (operands[2]) == 128
5677 || (INTVAL (operands[2]) < 0
5678 && INTVAL (operands[2]) != -128)))
5680 operands[2] = GEN_INT (-INTVAL (operands[2]));
5681 return "sub{q}\t{%2, %0|%0, %2}";
5683 return "add{q}\t{%2, %0|%0, %2}";
5687 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5688 (const_string "incdec")
5689 (const_string "alu")))
5690 (set_attr "mode" "DI")])
5693 (define_insn "*addsi_1"
5694 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5695 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5696 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5697 (clobber (reg:CC FLAGS_REG))]
5698 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5700 switch (get_attr_type (insn))
5703 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5704 return "lea{l}\t{%a2, %0|%0, %a2}";
5707 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5708 if (operands[2] == const1_rtx)
5709 return "inc{l}\t%0";
5712 gcc_assert (operands[2] == constm1_rtx);
5713 return "dec{l}\t%0";
5717 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5719 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5720 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5721 if (CONST_INT_P (operands[2])
5722 && (INTVAL (operands[2]) == 128
5723 || (INTVAL (operands[2]) < 0
5724 && INTVAL (operands[2]) != -128)))
5726 operands[2] = GEN_INT (-INTVAL (operands[2]));
5727 return "sub{l}\t{%2, %0|%0, %2}";
5729 return "add{l}\t{%2, %0|%0, %2}";
5733 (cond [(eq_attr "alternative" "2")
5734 (const_string "lea")
5735 ; Current assemblers are broken and do not allow @GOTOFF in
5736 ; ought but a memory context.
5737 (match_operand:SI 2 "pic_symbolic_operand" "")
5738 (const_string "lea")
5739 (match_operand:SI 2 "incdec_operand" "")
5740 (const_string "incdec")
5742 (const_string "alu")))
5743 (set_attr "mode" "SI")])
5745 ;; Convert lea to the lea pattern to avoid flags dependency.
5747 [(set (match_operand 0 "register_operand" "")
5748 (plus (match_operand 1 "register_operand" "")
5749 (match_operand 2 "nonmemory_operand" "")))
5750 (clobber (reg:CC FLAGS_REG))]
5752 && true_regnum (operands[0]) != true_regnum (operands[1])"
5756 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5757 may confuse gen_lowpart. */
5758 if (GET_MODE (operands[0]) != Pmode)
5760 operands[1] = gen_lowpart (Pmode, operands[1]);
5761 operands[2] = gen_lowpart (Pmode, operands[2]);
5763 operands[0] = gen_lowpart (SImode, operands[0]);
5764 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5765 if (Pmode != SImode)
5766 pat = gen_rtx_SUBREG (SImode, pat, 0);
5767 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5771 ;; It may seem that nonimmediate operand is proper one for operand 1.
5772 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5773 ;; we take care in ix86_binary_operator_ok to not allow two memory
5774 ;; operands so proper swapping will be done in reload. This allow
5775 ;; patterns constructed from addsi_1 to match.
5776 (define_insn "addsi_1_zext"
5777 [(set (match_operand:DI 0 "register_operand" "=r,r")
5779 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5780 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5781 (clobber (reg:CC FLAGS_REG))]
5782 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5784 switch (get_attr_type (insn))
5787 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5788 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5791 if (operands[2] == const1_rtx)
5792 return "inc{l}\t%k0";
5795 gcc_assert (operands[2] == constm1_rtx);
5796 return "dec{l}\t%k0";
5800 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5801 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5802 if (CONST_INT_P (operands[2])
5803 && (INTVAL (operands[2]) == 128
5804 || (INTVAL (operands[2]) < 0
5805 && INTVAL (operands[2]) != -128)))
5807 operands[2] = GEN_INT (-INTVAL (operands[2]));
5808 return "sub{l}\t{%2, %k0|%k0, %2}";
5810 return "add{l}\t{%2, %k0|%k0, %2}";
5814 (cond [(eq_attr "alternative" "1")
5815 (const_string "lea")
5816 ; Current assemblers are broken and do not allow @GOTOFF in
5817 ; ought but a memory context.
5818 (match_operand:SI 2 "pic_symbolic_operand" "")
5819 (const_string "lea")
5820 (match_operand:SI 2 "incdec_operand" "")
5821 (const_string "incdec")
5823 (const_string "alu")))
5824 (set_attr "mode" "SI")])
5826 ;; Convert lea to the lea pattern to avoid flags dependency.
5828 [(set (match_operand:DI 0 "register_operand" "")
5830 (plus:SI (match_operand:SI 1 "register_operand" "")
5831 (match_operand:SI 2 "nonmemory_operand" ""))))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "TARGET_64BIT && reload_completed
5834 && true_regnum (operands[0]) != true_regnum (operands[1])"
5836 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5838 operands[1] = gen_lowpart (Pmode, operands[1]);
5839 operands[2] = gen_lowpart (Pmode, operands[2]);
5842 (define_insn "*addsi_2"
5843 [(set (reg FLAGS_REG)
5845 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5846 (match_operand:SI 2 "general_operand" "rmni,rni"))
5848 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5849 (plus:SI (match_dup 1) (match_dup 2)))]
5850 "ix86_match_ccmode (insn, CCGOCmode)
5851 && ix86_binary_operator_ok (PLUS, SImode, operands)
5852 /* Current assemblers are broken and do not allow @GOTOFF in
5853 ought but a memory context. */
5854 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5856 switch (get_attr_type (insn))
5859 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5860 if (operands[2] == const1_rtx)
5861 return "inc{l}\t%0";
5864 gcc_assert (operands[2] == constm1_rtx);
5865 return "dec{l}\t%0";
5869 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5870 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5871 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5872 if (CONST_INT_P (operands[2])
5873 && (INTVAL (operands[2]) == 128
5874 || (INTVAL (operands[2]) < 0
5875 && INTVAL (operands[2]) != -128)))
5877 operands[2] = GEN_INT (-INTVAL (operands[2]));
5878 return "sub{l}\t{%2, %0|%0, %2}";
5880 return "add{l}\t{%2, %0|%0, %2}";
5884 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5885 (const_string "incdec")
5886 (const_string "alu")))
5887 (set_attr "mode" "SI")])
5889 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5890 (define_insn "*addsi_2_zext"
5891 [(set (reg FLAGS_REG)
5893 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5894 (match_operand:SI 2 "general_operand" "rmni"))
5896 (set (match_operand:DI 0 "register_operand" "=r")
5897 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5898 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5899 && ix86_binary_operator_ok (PLUS, SImode, operands)
5900 /* Current assemblers are broken and do not allow @GOTOFF in
5901 ought but a memory context. */
5902 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5904 switch (get_attr_type (insn))
5907 if (operands[2] == const1_rtx)
5908 return "inc{l}\t%k0";
5911 gcc_assert (operands[2] == constm1_rtx);
5912 return "dec{l}\t%k0";
5916 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5917 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5918 if (CONST_INT_P (operands[2])
5919 && (INTVAL (operands[2]) == 128
5920 || (INTVAL (operands[2]) < 0
5921 && INTVAL (operands[2]) != -128)))
5923 operands[2] = GEN_INT (-INTVAL (operands[2]));
5924 return "sub{l}\t{%2, %k0|%k0, %2}";
5926 return "add{l}\t{%2, %k0|%k0, %2}";
5930 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5931 (const_string "incdec")
5932 (const_string "alu")))
5933 (set_attr "mode" "SI")])
5935 (define_insn "*addsi_3"
5936 [(set (reg FLAGS_REG)
5937 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5938 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5939 (clobber (match_scratch:SI 0 "=r"))]
5940 "ix86_match_ccmode (insn, CCZmode)
5941 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5942 /* Current assemblers are broken and do not allow @GOTOFF in
5943 ought but a memory context. */
5944 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5946 switch (get_attr_type (insn))
5949 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5950 if (operands[2] == const1_rtx)
5951 return "inc{l}\t%0";
5954 gcc_assert (operands[2] == constm1_rtx);
5955 return "dec{l}\t%0";
5959 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5960 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5962 if (CONST_INT_P (operands[2])
5963 && (INTVAL (operands[2]) == 128
5964 || (INTVAL (operands[2]) < 0
5965 && INTVAL (operands[2]) != -128)))
5967 operands[2] = GEN_INT (-INTVAL (operands[2]));
5968 return "sub{l}\t{%2, %0|%0, %2}";
5970 return "add{l}\t{%2, %0|%0, %2}";
5974 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5975 (const_string "incdec")
5976 (const_string "alu")))
5977 (set_attr "mode" "SI")])
5979 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5980 (define_insn "*addsi_3_zext"
5981 [(set (reg FLAGS_REG)
5982 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5983 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5984 (set (match_operand:DI 0 "register_operand" "=r")
5985 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5986 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5987 && ix86_binary_operator_ok (PLUS, SImode, operands)
5988 /* Current assemblers are broken and do not allow @GOTOFF in
5989 ought but a memory context. */
5990 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5992 switch (get_attr_type (insn))
5995 if (operands[2] == const1_rtx)
5996 return "inc{l}\t%k0";
5999 gcc_assert (operands[2] == constm1_rtx);
6000 return "dec{l}\t%k0";
6004 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6005 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6006 if (CONST_INT_P (operands[2])
6007 && (INTVAL (operands[2]) == 128
6008 || (INTVAL (operands[2]) < 0
6009 && INTVAL (operands[2]) != -128)))
6011 operands[2] = GEN_INT (-INTVAL (operands[2]));
6012 return "sub{l}\t{%2, %k0|%k0, %2}";
6014 return "add{l}\t{%2, %k0|%k0, %2}";
6018 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6019 (const_string "incdec")
6020 (const_string "alu")))
6021 (set_attr "mode" "SI")])
6023 ; For comparisons against 1, -1 and 128, we may generate better code
6024 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6025 ; is matched then. We can't accept general immediate, because for
6026 ; case of overflows, the result is messed up.
6027 ; This pattern also don't hold of 0x80000000, since the value overflows
6029 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6030 ; only for comparisons not depending on it.
6031 (define_insn "*addsi_4"
6032 [(set (reg FLAGS_REG)
6033 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6034 (match_operand:SI 2 "const_int_operand" "n")))
6035 (clobber (match_scratch:SI 0 "=rm"))]
6036 "ix86_match_ccmode (insn, CCGCmode)
6037 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6039 switch (get_attr_type (insn))
6042 if (operands[2] == constm1_rtx)
6043 return "inc{l}\t%0";
6046 gcc_assert (operands[2] == const1_rtx);
6047 return "dec{l}\t%0";
6051 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6052 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6053 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6054 if ((INTVAL (operands[2]) == -128
6055 || (INTVAL (operands[2]) > 0
6056 && INTVAL (operands[2]) != 128)))
6057 return "sub{l}\t{%2, %0|%0, %2}";
6058 operands[2] = GEN_INT (-INTVAL (operands[2]));
6059 return "add{l}\t{%2, %0|%0, %2}";
6063 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6064 (const_string "incdec")
6065 (const_string "alu")))
6066 (set_attr "mode" "SI")])
6068 (define_insn "*addsi_5"
6069 [(set (reg FLAGS_REG)
6071 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6072 (match_operand:SI 2 "general_operand" "rmni"))
6074 (clobber (match_scratch:SI 0 "=r"))]
6075 "ix86_match_ccmode (insn, CCGOCmode)
6076 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6077 /* Current assemblers are broken and do not allow @GOTOFF in
6078 ought but a memory context. */
6079 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6081 switch (get_attr_type (insn))
6084 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6085 if (operands[2] == const1_rtx)
6086 return "inc{l}\t%0";
6089 gcc_assert (operands[2] == constm1_rtx);
6090 return "dec{l}\t%0";
6094 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6095 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6096 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6097 if (CONST_INT_P (operands[2])
6098 && (INTVAL (operands[2]) == 128
6099 || (INTVAL (operands[2]) < 0
6100 && INTVAL (operands[2]) != -128)))
6102 operands[2] = GEN_INT (-INTVAL (operands[2]));
6103 return "sub{l}\t{%2, %0|%0, %2}";
6105 return "add{l}\t{%2, %0|%0, %2}";
6109 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6110 (const_string "incdec")
6111 (const_string "alu")))
6112 (set_attr "mode" "SI")])
6114 (define_expand "addhi3"
6115 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6116 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6117 (match_operand:HI 2 "general_operand" "")))
6118 (clobber (reg:CC FLAGS_REG))])]
6119 "TARGET_HIMODE_MATH"
6120 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6122 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6123 ;; type optimizations enabled by define-splits. This is not important
6124 ;; for PII, and in fact harmful because of partial register stalls.
6126 (define_insn "*addhi_1_lea"
6127 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6128 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6129 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6130 (clobber (reg:CC FLAGS_REG))]
6131 "!TARGET_PARTIAL_REG_STALL
6132 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6134 switch (get_attr_type (insn))
6139 if (operands[2] == const1_rtx)
6140 return "inc{w}\t%0";
6143 gcc_assert (operands[2] == constm1_rtx);
6144 return "dec{w}\t%0";
6148 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6149 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6150 if (CONST_INT_P (operands[2])
6151 && (INTVAL (operands[2]) == 128
6152 || (INTVAL (operands[2]) < 0
6153 && INTVAL (operands[2]) != -128)))
6155 operands[2] = GEN_INT (-INTVAL (operands[2]));
6156 return "sub{w}\t{%2, %0|%0, %2}";
6158 return "add{w}\t{%2, %0|%0, %2}";
6162 (if_then_else (eq_attr "alternative" "2")
6163 (const_string "lea")
6164 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6165 (const_string "incdec")
6166 (const_string "alu"))))
6167 (set_attr "mode" "HI,HI,SI")])
6169 (define_insn "*addhi_1"
6170 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6171 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6172 (match_operand:HI 2 "general_operand" "ri,rm")))
6173 (clobber (reg:CC FLAGS_REG))]
6174 "TARGET_PARTIAL_REG_STALL
6175 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6177 switch (get_attr_type (insn))
6180 if (operands[2] == const1_rtx)
6181 return "inc{w}\t%0";
6184 gcc_assert (operands[2] == constm1_rtx);
6185 return "dec{w}\t%0";
6189 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6190 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6191 if (CONST_INT_P (operands[2])
6192 && (INTVAL (operands[2]) == 128
6193 || (INTVAL (operands[2]) < 0
6194 && INTVAL (operands[2]) != -128)))
6196 operands[2] = GEN_INT (-INTVAL (operands[2]));
6197 return "sub{w}\t{%2, %0|%0, %2}";
6199 return "add{w}\t{%2, %0|%0, %2}";
6203 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6204 (const_string "incdec")
6205 (const_string "alu")))
6206 (set_attr "mode" "HI")])
6208 (define_insn "*addhi_2"
6209 [(set (reg FLAGS_REG)
6211 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6212 (match_operand:HI 2 "general_operand" "rmni,rni"))
6214 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6215 (plus:HI (match_dup 1) (match_dup 2)))]
6216 "ix86_match_ccmode (insn, CCGOCmode)
6217 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6219 switch (get_attr_type (insn))
6222 if (operands[2] == const1_rtx)
6223 return "inc{w}\t%0";
6226 gcc_assert (operands[2] == constm1_rtx);
6227 return "dec{w}\t%0";
6231 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6232 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6233 if (CONST_INT_P (operands[2])
6234 && (INTVAL (operands[2]) == 128
6235 || (INTVAL (operands[2]) < 0
6236 && INTVAL (operands[2]) != -128)))
6238 operands[2] = GEN_INT (-INTVAL (operands[2]));
6239 return "sub{w}\t{%2, %0|%0, %2}";
6241 return "add{w}\t{%2, %0|%0, %2}";
6245 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6246 (const_string "incdec")
6247 (const_string "alu")))
6248 (set_attr "mode" "HI")])
6250 (define_insn "*addhi_3"
6251 [(set (reg FLAGS_REG)
6252 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6253 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6254 (clobber (match_scratch:HI 0 "=r"))]
6255 "ix86_match_ccmode (insn, CCZmode)
6256 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6258 switch (get_attr_type (insn))
6261 if (operands[2] == const1_rtx)
6262 return "inc{w}\t%0";
6265 gcc_assert (operands[2] == constm1_rtx);
6266 return "dec{w}\t%0";
6270 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6271 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6272 if (CONST_INT_P (operands[2])
6273 && (INTVAL (operands[2]) == 128
6274 || (INTVAL (operands[2]) < 0
6275 && INTVAL (operands[2]) != -128)))
6277 operands[2] = GEN_INT (-INTVAL (operands[2]));
6278 return "sub{w}\t{%2, %0|%0, %2}";
6280 return "add{w}\t{%2, %0|%0, %2}";
6284 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6285 (const_string "incdec")
6286 (const_string "alu")))
6287 (set_attr "mode" "HI")])
6289 ; See comments above addsi_4 for details.
6290 (define_insn "*addhi_4"
6291 [(set (reg FLAGS_REG)
6292 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6293 (match_operand:HI 2 "const_int_operand" "n")))
6294 (clobber (match_scratch:HI 0 "=rm"))]
6295 "ix86_match_ccmode (insn, CCGCmode)
6296 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6298 switch (get_attr_type (insn))
6301 if (operands[2] == constm1_rtx)
6302 return "inc{w}\t%0";
6305 gcc_assert (operands[2] == const1_rtx);
6306 return "dec{w}\t%0";
6310 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6311 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6312 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6313 if ((INTVAL (operands[2]) == -128
6314 || (INTVAL (operands[2]) > 0
6315 && INTVAL (operands[2]) != 128)))
6316 return "sub{w}\t{%2, %0|%0, %2}";
6317 operands[2] = GEN_INT (-INTVAL (operands[2]));
6318 return "add{w}\t{%2, %0|%0, %2}";
6322 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6323 (const_string "incdec")
6324 (const_string "alu")))
6325 (set_attr "mode" "SI")])
6328 (define_insn "*addhi_5"
6329 [(set (reg FLAGS_REG)
6331 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6332 (match_operand:HI 2 "general_operand" "rmni"))
6334 (clobber (match_scratch:HI 0 "=r"))]
6335 "ix86_match_ccmode (insn, CCGOCmode)
6336 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6338 switch (get_attr_type (insn))
6341 if (operands[2] == const1_rtx)
6342 return "inc{w}\t%0";
6345 gcc_assert (operands[2] == constm1_rtx);
6346 return "dec{w}\t%0";
6350 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6351 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6352 if (CONST_INT_P (operands[2])
6353 && (INTVAL (operands[2]) == 128
6354 || (INTVAL (operands[2]) < 0
6355 && INTVAL (operands[2]) != -128)))
6357 operands[2] = GEN_INT (-INTVAL (operands[2]));
6358 return "sub{w}\t{%2, %0|%0, %2}";
6360 return "add{w}\t{%2, %0|%0, %2}";
6364 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6365 (const_string "incdec")
6366 (const_string "alu")))
6367 (set_attr "mode" "HI")])
6369 (define_expand "addqi3"
6370 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6371 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6372 (match_operand:QI 2 "general_operand" "")))
6373 (clobber (reg:CC FLAGS_REG))])]
6374 "TARGET_QIMODE_MATH"
6375 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6377 ;; %%% Potential partial reg stall on alternative 2. What to do?
6378 (define_insn "*addqi_1_lea"
6379 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6380 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6381 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6382 (clobber (reg:CC FLAGS_REG))]
6383 "!TARGET_PARTIAL_REG_STALL
6384 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6386 int widen = (which_alternative == 2);
6387 switch (get_attr_type (insn))
6392 if (operands[2] == const1_rtx)
6393 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6396 gcc_assert (operands[2] == constm1_rtx);
6397 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6401 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6402 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6403 if (CONST_INT_P (operands[2])
6404 && (INTVAL (operands[2]) == 128
6405 || (INTVAL (operands[2]) < 0
6406 && INTVAL (operands[2]) != -128)))
6408 operands[2] = GEN_INT (-INTVAL (operands[2]));
6410 return "sub{l}\t{%2, %k0|%k0, %2}";
6412 return "sub{b}\t{%2, %0|%0, %2}";
6415 return "add{l}\t{%k2, %k0|%k0, %k2}";
6417 return "add{b}\t{%2, %0|%0, %2}";
6421 (if_then_else (eq_attr "alternative" "3")
6422 (const_string "lea")
6423 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6424 (const_string "incdec")
6425 (const_string "alu"))))
6426 (set_attr "mode" "QI,QI,SI,SI")])
6428 (define_insn "*addqi_1"
6429 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6430 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6431 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6432 (clobber (reg:CC FLAGS_REG))]
6433 "TARGET_PARTIAL_REG_STALL
6434 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6436 int widen = (which_alternative == 2);
6437 switch (get_attr_type (insn))
6440 if (operands[2] == const1_rtx)
6441 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6444 gcc_assert (operands[2] == constm1_rtx);
6445 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6449 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6450 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6451 if (CONST_INT_P (operands[2])
6452 && (INTVAL (operands[2]) == 128
6453 || (INTVAL (operands[2]) < 0
6454 && INTVAL (operands[2]) != -128)))
6456 operands[2] = GEN_INT (-INTVAL (operands[2]));
6458 return "sub{l}\t{%2, %k0|%k0, %2}";
6460 return "sub{b}\t{%2, %0|%0, %2}";
6463 return "add{l}\t{%k2, %k0|%k0, %k2}";
6465 return "add{b}\t{%2, %0|%0, %2}";
6469 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6470 (const_string "incdec")
6471 (const_string "alu")))
6472 (set_attr "mode" "QI,QI,SI")])
6474 (define_insn "*addqi_1_slp"
6475 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6476 (plus:QI (match_dup 0)
6477 (match_operand:QI 1 "general_operand" "qn,qnm")))
6478 (clobber (reg:CC FLAGS_REG))]
6479 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6480 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6482 switch (get_attr_type (insn))
6485 if (operands[1] == const1_rtx)
6486 return "inc{b}\t%0";
6489 gcc_assert (operands[1] == constm1_rtx);
6490 return "dec{b}\t%0";
6494 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6495 if (CONST_INT_P (operands[1])
6496 && INTVAL (operands[1]) < 0)
6498 operands[1] = GEN_INT (-INTVAL (operands[1]));
6499 return "sub{b}\t{%1, %0|%0, %1}";
6501 return "add{b}\t{%1, %0|%0, %1}";
6505 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6506 (const_string "incdec")
6507 (const_string "alu1")))
6508 (set (attr "memory")
6509 (if_then_else (match_operand 1 "memory_operand" "")
6510 (const_string "load")
6511 (const_string "none")))
6512 (set_attr "mode" "QI")])
6514 (define_insn "*addqi_2"
6515 [(set (reg FLAGS_REG)
6517 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6518 (match_operand:QI 2 "general_operand" "qmni,qni"))
6520 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6521 (plus:QI (match_dup 1) (match_dup 2)))]
6522 "ix86_match_ccmode (insn, CCGOCmode)
6523 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6525 switch (get_attr_type (insn))
6528 if (operands[2] == const1_rtx)
6529 return "inc{b}\t%0";
6532 gcc_assert (operands[2] == constm1_rtx
6533 || (CONST_INT_P (operands[2])
6534 && INTVAL (operands[2]) == 255));
6535 return "dec{b}\t%0";
6539 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6540 if (CONST_INT_P (operands[2])
6541 && INTVAL (operands[2]) < 0)
6543 operands[2] = GEN_INT (-INTVAL (operands[2]));
6544 return "sub{b}\t{%2, %0|%0, %2}";
6546 return "add{b}\t{%2, %0|%0, %2}";
6550 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6551 (const_string "incdec")
6552 (const_string "alu")))
6553 (set_attr "mode" "QI")])
6555 (define_insn "*addqi_3"
6556 [(set (reg FLAGS_REG)
6557 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6558 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6559 (clobber (match_scratch:QI 0 "=q"))]
6560 "ix86_match_ccmode (insn, CCZmode)
6561 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6563 switch (get_attr_type (insn))
6566 if (operands[2] == const1_rtx)
6567 return "inc{b}\t%0";
6570 gcc_assert (operands[2] == constm1_rtx
6571 || (CONST_INT_P (operands[2])
6572 && INTVAL (operands[2]) == 255));
6573 return "dec{b}\t%0";
6577 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6578 if (CONST_INT_P (operands[2])
6579 && INTVAL (operands[2]) < 0)
6581 operands[2] = GEN_INT (-INTVAL (operands[2]));
6582 return "sub{b}\t{%2, %0|%0, %2}";
6584 return "add{b}\t{%2, %0|%0, %2}";
6588 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6589 (const_string "incdec")
6590 (const_string "alu")))
6591 (set_attr "mode" "QI")])
6593 ; See comments above addsi_4 for details.
6594 (define_insn "*addqi_4"
6595 [(set (reg FLAGS_REG)
6596 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6597 (match_operand:QI 2 "const_int_operand" "n")))
6598 (clobber (match_scratch:QI 0 "=qm"))]
6599 "ix86_match_ccmode (insn, CCGCmode)
6600 && (INTVAL (operands[2]) & 0xff) != 0x80"
6602 switch (get_attr_type (insn))
6605 if (operands[2] == constm1_rtx
6606 || (CONST_INT_P (operands[2])
6607 && INTVAL (operands[2]) == 255))
6608 return "inc{b}\t%0";
6611 gcc_assert (operands[2] == const1_rtx);
6612 return "dec{b}\t%0";
6616 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6617 if (INTVAL (operands[2]) < 0)
6619 operands[2] = GEN_INT (-INTVAL (operands[2]));
6620 return "add{b}\t{%2, %0|%0, %2}";
6622 return "sub{b}\t{%2, %0|%0, %2}";
6626 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6627 (const_string "incdec")
6628 (const_string "alu")))
6629 (set_attr "mode" "QI")])
6632 (define_insn "*addqi_5"
6633 [(set (reg FLAGS_REG)
6635 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6636 (match_operand:QI 2 "general_operand" "qmni"))
6638 (clobber (match_scratch:QI 0 "=q"))]
6639 "ix86_match_ccmode (insn, CCGOCmode)
6640 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6642 switch (get_attr_type (insn))
6645 if (operands[2] == const1_rtx)
6646 return "inc{b}\t%0";
6649 gcc_assert (operands[2] == constm1_rtx
6650 || (CONST_INT_P (operands[2])
6651 && INTVAL (operands[2]) == 255));
6652 return "dec{b}\t%0";
6656 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6657 if (CONST_INT_P (operands[2])
6658 && INTVAL (operands[2]) < 0)
6660 operands[2] = GEN_INT (-INTVAL (operands[2]));
6661 return "sub{b}\t{%2, %0|%0, %2}";
6663 return "add{b}\t{%2, %0|%0, %2}";
6667 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6668 (const_string "incdec")
6669 (const_string "alu")))
6670 (set_attr "mode" "QI")])
6673 (define_insn "addqi_ext_1"
6674 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6679 (match_operand 1 "ext_register_operand" "0")
6682 (match_operand:QI 2 "general_operand" "Qmn")))
6683 (clobber (reg:CC FLAGS_REG))]
6686 switch (get_attr_type (insn))
6689 if (operands[2] == const1_rtx)
6690 return "inc{b}\t%h0";
6693 gcc_assert (operands[2] == constm1_rtx
6694 || (CONST_INT_P (operands[2])
6695 && INTVAL (operands[2]) == 255));
6696 return "dec{b}\t%h0";
6700 return "add{b}\t{%2, %h0|%h0, %2}";
6704 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6705 (const_string "incdec")
6706 (const_string "alu")))
6707 (set_attr "mode" "QI")])
6709 (define_insn "*addqi_ext_1_rex64"
6710 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6715 (match_operand 1 "ext_register_operand" "0")
6718 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6719 (clobber (reg:CC FLAGS_REG))]
6722 switch (get_attr_type (insn))
6725 if (operands[2] == const1_rtx)
6726 return "inc{b}\t%h0";
6729 gcc_assert (operands[2] == constm1_rtx
6730 || (CONST_INT_P (operands[2])
6731 && INTVAL (operands[2]) == 255));
6732 return "dec{b}\t%h0";
6736 return "add{b}\t{%2, %h0|%h0, %2}";
6740 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6741 (const_string "incdec")
6742 (const_string "alu")))
6743 (set_attr "mode" "QI")])
6745 (define_insn "*addqi_ext_2"
6746 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6751 (match_operand 1 "ext_register_operand" "%0")
6755 (match_operand 2 "ext_register_operand" "Q")
6758 (clobber (reg:CC FLAGS_REG))]
6760 "add{b}\t{%h2, %h0|%h0, %h2}"
6761 [(set_attr "type" "alu")
6762 (set_attr "mode" "QI")])
6764 ;; The patterns that match these are at the end of this file.
6766 (define_expand "addxf3"
6767 [(set (match_operand:XF 0 "register_operand" "")
6768 (plus:XF (match_operand:XF 1 "register_operand" "")
6769 (match_operand:XF 2 "register_operand" "")))]
6773 (define_expand "adddf3"
6774 [(set (match_operand:DF 0 "register_operand" "")
6775 (plus:DF (match_operand:DF 1 "register_operand" "")
6776 (match_operand:DF 2 "nonimmediate_operand" "")))]
6777 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6780 (define_expand "addsf3"
6781 [(set (match_operand:SF 0 "register_operand" "")
6782 (plus:SF (match_operand:SF 1 "register_operand" "")
6783 (match_operand:SF 2 "nonimmediate_operand" "")))]
6784 "TARGET_80387 || TARGET_SSE_MATH"
6787 ;; Subtract instructions
6789 ;; %%% splits for subditi3
6791 (define_expand "subti3"
6792 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6793 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6794 (match_operand:TI 2 "x86_64_general_operand" "")))
6795 (clobber (reg:CC FLAGS_REG))])]
6797 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6799 (define_insn "*subti3_1"
6800 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6801 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6802 (match_operand:TI 2 "general_operand" "roiF,riF")))
6803 (clobber (reg:CC FLAGS_REG))]
6804 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6808 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6809 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6810 (match_operand:TI 2 "general_operand" "")))
6811 (clobber (reg:CC FLAGS_REG))]
6812 "TARGET_64BIT && reload_completed"
6813 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6814 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6815 (parallel [(set (match_dup 3)
6816 (minus:DI (match_dup 4)
6817 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6819 (clobber (reg:CC FLAGS_REG))])]
6820 "split_ti (operands+0, 1, operands+0, operands+3);
6821 split_ti (operands+1, 1, operands+1, operands+4);
6822 split_ti (operands+2, 1, operands+2, operands+5);")
6824 ;; %%% splits for subsidi3
6826 (define_expand "subdi3"
6827 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6828 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6829 (match_operand:DI 2 "x86_64_general_operand" "")))
6830 (clobber (reg:CC FLAGS_REG))])]
6832 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6834 (define_insn "*subdi3_1"
6835 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6836 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6837 (match_operand:DI 2 "general_operand" "roiF,riF")))
6838 (clobber (reg:CC FLAGS_REG))]
6839 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6843 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6844 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6845 (match_operand:DI 2 "general_operand" "")))
6846 (clobber (reg:CC FLAGS_REG))]
6847 "!TARGET_64BIT && reload_completed"
6848 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6849 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6850 (parallel [(set (match_dup 3)
6851 (minus:SI (match_dup 4)
6852 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6854 (clobber (reg:CC FLAGS_REG))])]
6855 "split_di (operands+0, 1, operands+0, operands+3);
6856 split_di (operands+1, 1, operands+1, operands+4);
6857 split_di (operands+2, 1, operands+2, operands+5);")
6859 (define_insn "subdi3_carry_rex64"
6860 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6861 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6862 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6863 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6864 (clobber (reg:CC FLAGS_REG))]
6865 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6866 "sbb{q}\t{%2, %0|%0, %2}"
6867 [(set_attr "type" "alu")
6868 (set_attr "pent_pair" "pu")
6869 (set_attr "mode" "DI")])
6871 (define_insn "*subdi_1_rex64"
6872 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6873 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6874 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6875 (clobber (reg:CC FLAGS_REG))]
6876 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6877 "sub{q}\t{%2, %0|%0, %2}"
6878 [(set_attr "type" "alu")
6879 (set_attr "mode" "DI")])
6881 (define_insn "*subdi_2_rex64"
6882 [(set (reg FLAGS_REG)
6884 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6885 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6887 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6888 (minus:DI (match_dup 1) (match_dup 2)))]
6889 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6890 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6891 "sub{q}\t{%2, %0|%0, %2}"
6892 [(set_attr "type" "alu")
6893 (set_attr "mode" "DI")])
6895 (define_insn "*subdi_3_rex63"
6896 [(set (reg FLAGS_REG)
6897 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6898 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6899 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6900 (minus:DI (match_dup 1) (match_dup 2)))]
6901 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6902 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6903 "sub{q}\t{%2, %0|%0, %2}"
6904 [(set_attr "type" "alu")
6905 (set_attr "mode" "DI")])
6907 (define_insn "subqi3_carry"
6908 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6909 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6910 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6911 (match_operand:QI 2 "general_operand" "qi,qm"))))
6912 (clobber (reg:CC FLAGS_REG))]
6913 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6914 "sbb{b}\t{%2, %0|%0, %2}"
6915 [(set_attr "type" "alu")
6916 (set_attr "pent_pair" "pu")
6917 (set_attr "mode" "QI")])
6919 (define_insn "subhi3_carry"
6920 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6921 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6922 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6923 (match_operand:HI 2 "general_operand" "ri,rm"))))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6926 "sbb{w}\t{%2, %0|%0, %2}"
6927 [(set_attr "type" "alu")
6928 (set_attr "pent_pair" "pu")
6929 (set_attr "mode" "HI")])
6931 (define_insn "subsi3_carry"
6932 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6933 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6934 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6935 (match_operand:SI 2 "general_operand" "ri,rm"))))
6936 (clobber (reg:CC FLAGS_REG))]
6937 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6938 "sbb{l}\t{%2, %0|%0, %2}"
6939 [(set_attr "type" "alu")
6940 (set_attr "pent_pair" "pu")
6941 (set_attr "mode" "SI")])
6943 (define_insn "subsi3_carry_zext"
6944 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6946 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6947 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6948 (match_operand:SI 2 "general_operand" "ri,rm")))))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6951 "sbb{l}\t{%2, %k0|%k0, %2}"
6952 [(set_attr "type" "alu")
6953 (set_attr "pent_pair" "pu")
6954 (set_attr "mode" "SI")])
6956 (define_expand "subsi3"
6957 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6958 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6959 (match_operand:SI 2 "general_operand" "")))
6960 (clobber (reg:CC FLAGS_REG))])]
6962 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6964 (define_insn "*subsi_1"
6965 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6966 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6967 (match_operand:SI 2 "general_operand" "ri,rm")))
6968 (clobber (reg:CC FLAGS_REG))]
6969 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6970 "sub{l}\t{%2, %0|%0, %2}"
6971 [(set_attr "type" "alu")
6972 (set_attr "mode" "SI")])
6974 (define_insn "*subsi_1_zext"
6975 [(set (match_operand:DI 0 "register_operand" "=r")
6977 (minus:SI (match_operand:SI 1 "register_operand" "0")
6978 (match_operand:SI 2 "general_operand" "rim"))))
6979 (clobber (reg:CC FLAGS_REG))]
6980 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6981 "sub{l}\t{%2, %k0|%k0, %2}"
6982 [(set_attr "type" "alu")
6983 (set_attr "mode" "SI")])
6985 (define_insn "*subsi_2"
6986 [(set (reg FLAGS_REG)
6988 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6989 (match_operand:SI 2 "general_operand" "ri,rm"))
6991 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6992 (minus:SI (match_dup 1) (match_dup 2)))]
6993 "ix86_match_ccmode (insn, CCGOCmode)
6994 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6995 "sub{l}\t{%2, %0|%0, %2}"
6996 [(set_attr "type" "alu")
6997 (set_attr "mode" "SI")])
6999 (define_insn "*subsi_2_zext"
7000 [(set (reg FLAGS_REG)
7002 (minus:SI (match_operand:SI 1 "register_operand" "0")
7003 (match_operand:SI 2 "general_operand" "rim"))
7005 (set (match_operand:DI 0 "register_operand" "=r")
7007 (minus:SI (match_dup 1)
7009 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7010 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7011 "sub{l}\t{%2, %k0|%k0, %2}"
7012 [(set_attr "type" "alu")
7013 (set_attr "mode" "SI")])
7015 (define_insn "*subsi_3"
7016 [(set (reg FLAGS_REG)
7017 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7018 (match_operand:SI 2 "general_operand" "ri,rm")))
7019 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7020 (minus:SI (match_dup 1) (match_dup 2)))]
7021 "ix86_match_ccmode (insn, CCmode)
7022 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7023 "sub{l}\t{%2, %0|%0, %2}"
7024 [(set_attr "type" "alu")
7025 (set_attr "mode" "SI")])
7027 (define_insn "*subsi_3_zext"
7028 [(set (reg FLAGS_REG)
7029 (compare (match_operand:SI 1 "register_operand" "0")
7030 (match_operand:SI 2 "general_operand" "rim")))
7031 (set (match_operand:DI 0 "register_operand" "=r")
7033 (minus:SI (match_dup 1)
7035 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7036 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7037 "sub{l}\t{%2, %1|%1, %2}"
7038 [(set_attr "type" "alu")
7039 (set_attr "mode" "DI")])
7041 (define_expand "subhi3"
7042 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7043 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7044 (match_operand:HI 2 "general_operand" "")))
7045 (clobber (reg:CC FLAGS_REG))])]
7046 "TARGET_HIMODE_MATH"
7047 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7049 (define_insn "*subhi_1"
7050 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7051 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7052 (match_operand:HI 2 "general_operand" "ri,rm")))
7053 (clobber (reg:CC FLAGS_REG))]
7054 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7055 "sub{w}\t{%2, %0|%0, %2}"
7056 [(set_attr "type" "alu")
7057 (set_attr "mode" "HI")])
7059 (define_insn "*subhi_2"
7060 [(set (reg FLAGS_REG)
7062 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7063 (match_operand:HI 2 "general_operand" "ri,rm"))
7065 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7066 (minus:HI (match_dup 1) (match_dup 2)))]
7067 "ix86_match_ccmode (insn, CCGOCmode)
7068 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7069 "sub{w}\t{%2, %0|%0, %2}"
7070 [(set_attr "type" "alu")
7071 (set_attr "mode" "HI")])
7073 (define_insn "*subhi_3"
7074 [(set (reg FLAGS_REG)
7075 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7076 (match_operand:HI 2 "general_operand" "ri,rm")))
7077 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7078 (minus:HI (match_dup 1) (match_dup 2)))]
7079 "ix86_match_ccmode (insn, CCmode)
7080 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7081 "sub{w}\t{%2, %0|%0, %2}"
7082 [(set_attr "type" "alu")
7083 (set_attr "mode" "HI")])
7085 (define_expand "subqi3"
7086 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7087 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7088 (match_operand:QI 2 "general_operand" "")))
7089 (clobber (reg:CC FLAGS_REG))])]
7090 "TARGET_QIMODE_MATH"
7091 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7093 (define_insn "*subqi_1"
7094 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7095 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7096 (match_operand:QI 2 "general_operand" "qn,qmn")))
7097 (clobber (reg:CC FLAGS_REG))]
7098 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7099 "sub{b}\t{%2, %0|%0, %2}"
7100 [(set_attr "type" "alu")
7101 (set_attr "mode" "QI")])
7103 (define_insn "*subqi_1_slp"
7104 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7105 (minus:QI (match_dup 0)
7106 (match_operand:QI 1 "general_operand" "qn,qmn")))
7107 (clobber (reg:CC FLAGS_REG))]
7108 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7109 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7110 "sub{b}\t{%1, %0|%0, %1}"
7111 [(set_attr "type" "alu1")
7112 (set_attr "mode" "QI")])
7114 (define_insn "*subqi_2"
7115 [(set (reg FLAGS_REG)
7117 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7118 (match_operand:QI 2 "general_operand" "qi,qm"))
7120 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7121 (minus:HI (match_dup 1) (match_dup 2)))]
7122 "ix86_match_ccmode (insn, CCGOCmode)
7123 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7124 "sub{b}\t{%2, %0|%0, %2}"
7125 [(set_attr "type" "alu")
7126 (set_attr "mode" "QI")])
7128 (define_insn "*subqi_3"
7129 [(set (reg FLAGS_REG)
7130 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7131 (match_operand:QI 2 "general_operand" "qi,qm")))
7132 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7133 (minus:HI (match_dup 1) (match_dup 2)))]
7134 "ix86_match_ccmode (insn, CCmode)
7135 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7136 "sub{b}\t{%2, %0|%0, %2}"
7137 [(set_attr "type" "alu")
7138 (set_attr "mode" "QI")])
7140 ;; The patterns that match these are at the end of this file.
7142 (define_expand "subxf3"
7143 [(set (match_operand:XF 0 "register_operand" "")
7144 (minus:XF (match_operand:XF 1 "register_operand" "")
7145 (match_operand:XF 2 "register_operand" "")))]
7149 (define_expand "subdf3"
7150 [(set (match_operand:DF 0 "register_operand" "")
7151 (minus:DF (match_operand:DF 1 "register_operand" "")
7152 (match_operand:DF 2 "nonimmediate_operand" "")))]
7153 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7156 (define_expand "subsf3"
7157 [(set (match_operand:SF 0 "register_operand" "")
7158 (minus:SF (match_operand:SF 1 "register_operand" "")
7159 (match_operand:SF 2 "nonimmediate_operand" "")))]
7160 "TARGET_80387 || TARGET_SSE_MATH"
7163 ;; Multiply instructions
7165 (define_expand "muldi3"
7166 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7167 (mult:DI (match_operand:DI 1 "register_operand" "")
7168 (match_operand:DI 2 "x86_64_general_operand" "")))
7169 (clobber (reg:CC FLAGS_REG))])]
7174 ;; IMUL reg64, reg64, imm8 Direct
7175 ;; IMUL reg64, mem64, imm8 VectorPath
7176 ;; IMUL reg64, reg64, imm32 Direct
7177 ;; IMUL reg64, mem64, imm32 VectorPath
7178 ;; IMUL reg64, reg64 Direct
7179 ;; IMUL reg64, mem64 Direct
7181 (define_insn "*muldi3_1_rex64"
7182 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7183 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7184 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7185 (clobber (reg:CC FLAGS_REG))]
7187 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7189 imul{q}\t{%2, %1, %0|%0, %1, %2}
7190 imul{q}\t{%2, %1, %0|%0, %1, %2}
7191 imul{q}\t{%2, %0|%0, %2}"
7192 [(set_attr "type" "imul")
7193 (set_attr "prefix_0f" "0,0,1")
7194 (set (attr "athlon_decode")
7195 (cond [(eq_attr "cpu" "athlon")
7196 (const_string "vector")
7197 (eq_attr "alternative" "1")
7198 (const_string "vector")
7199 (and (eq_attr "alternative" "2")
7200 (match_operand 1 "memory_operand" ""))
7201 (const_string "vector")]
7202 (const_string "direct")))
7203 (set (attr "amdfam10_decode")
7204 (cond [(and (eq_attr "alternative" "0,1")
7205 (match_operand 1 "memory_operand" ""))
7206 (const_string "vector")]
7207 (const_string "direct")))
7208 (set_attr "mode" "DI")])
7210 (define_expand "mulsi3"
7211 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7212 (mult:SI (match_operand:SI 1 "register_operand" "")
7213 (match_operand:SI 2 "general_operand" "")))
7214 (clobber (reg:CC FLAGS_REG))])]
7219 ;; IMUL reg32, reg32, imm8 Direct
7220 ;; IMUL reg32, mem32, imm8 VectorPath
7221 ;; IMUL reg32, reg32, imm32 Direct
7222 ;; IMUL reg32, mem32, imm32 VectorPath
7223 ;; IMUL reg32, reg32 Direct
7224 ;; IMUL reg32, mem32 Direct
7226 (define_insn "*mulsi3_1"
7227 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7228 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7229 (match_operand:SI 2 "general_operand" "K,i,mr")))
7230 (clobber (reg:CC FLAGS_REG))]
7231 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7233 imul{l}\t{%2, %1, %0|%0, %1, %2}
7234 imul{l}\t{%2, %1, %0|%0, %1, %2}
7235 imul{l}\t{%2, %0|%0, %2}"
7236 [(set_attr "type" "imul")
7237 (set_attr "prefix_0f" "0,0,1")
7238 (set (attr "athlon_decode")
7239 (cond [(eq_attr "cpu" "athlon")
7240 (const_string "vector")
7241 (eq_attr "alternative" "1")
7242 (const_string "vector")
7243 (and (eq_attr "alternative" "2")
7244 (match_operand 1 "memory_operand" ""))
7245 (const_string "vector")]
7246 (const_string "direct")))
7247 (set (attr "amdfam10_decode")
7248 (cond [(and (eq_attr "alternative" "0,1")
7249 (match_operand 1 "memory_operand" ""))
7250 (const_string "vector")]
7251 (const_string "direct")))
7252 (set_attr "mode" "SI")])
7254 (define_insn "*mulsi3_1_zext"
7255 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7257 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7258 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7259 (clobber (reg:CC FLAGS_REG))]
7261 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7263 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7264 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7265 imul{l}\t{%2, %k0|%k0, %2}"
7266 [(set_attr "type" "imul")
7267 (set_attr "prefix_0f" "0,0,1")
7268 (set (attr "athlon_decode")
7269 (cond [(eq_attr "cpu" "athlon")
7270 (const_string "vector")
7271 (eq_attr "alternative" "1")
7272 (const_string "vector")
7273 (and (eq_attr "alternative" "2")
7274 (match_operand 1 "memory_operand" ""))
7275 (const_string "vector")]
7276 (const_string "direct")))
7277 (set (attr "amdfam10_decode")
7278 (cond [(and (eq_attr "alternative" "0,1")
7279 (match_operand 1 "memory_operand" ""))
7280 (const_string "vector")]
7281 (const_string "direct")))
7282 (set_attr "mode" "SI")])
7284 (define_expand "mulhi3"
7285 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7286 (mult:HI (match_operand:HI 1 "register_operand" "")
7287 (match_operand:HI 2 "general_operand" "")))
7288 (clobber (reg:CC FLAGS_REG))])]
7289 "TARGET_HIMODE_MATH"
7293 ;; IMUL reg16, reg16, imm8 VectorPath
7294 ;; IMUL reg16, mem16, imm8 VectorPath
7295 ;; IMUL reg16, reg16, imm16 VectorPath
7296 ;; IMUL reg16, mem16, imm16 VectorPath
7297 ;; IMUL reg16, reg16 Direct
7298 ;; IMUL reg16, mem16 Direct
7299 (define_insn "*mulhi3_1"
7300 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7301 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7302 (match_operand:HI 2 "general_operand" "K,i,mr")))
7303 (clobber (reg:CC FLAGS_REG))]
7304 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7306 imul{w}\t{%2, %1, %0|%0, %1, %2}
7307 imul{w}\t{%2, %1, %0|%0, %1, %2}
7308 imul{w}\t{%2, %0|%0, %2}"
7309 [(set_attr "type" "imul")
7310 (set_attr "prefix_0f" "0,0,1")
7311 (set (attr "athlon_decode")
7312 (cond [(eq_attr "cpu" "athlon")
7313 (const_string "vector")
7314 (eq_attr "alternative" "1,2")
7315 (const_string "vector")]
7316 (const_string "direct")))
7317 (set (attr "amdfam10_decode")
7318 (cond [(eq_attr "alternative" "0,1")
7319 (const_string "vector")]
7320 (const_string "direct")))
7321 (set_attr "mode" "HI")])
7323 (define_expand "mulqi3"
7324 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7325 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7326 (match_operand:QI 2 "register_operand" "")))
7327 (clobber (reg:CC FLAGS_REG))])]
7328 "TARGET_QIMODE_MATH"
7335 (define_insn "*mulqi3_1"
7336 [(set (match_operand:QI 0 "register_operand" "=a")
7337 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7338 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7339 (clobber (reg:CC FLAGS_REG))]
7341 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7343 [(set_attr "type" "imul")
7344 (set_attr "length_immediate" "0")
7345 (set (attr "athlon_decode")
7346 (if_then_else (eq_attr "cpu" "athlon")
7347 (const_string "vector")
7348 (const_string "direct")))
7349 (set_attr "amdfam10_decode" "direct")
7350 (set_attr "mode" "QI")])
7352 (define_expand "umulqihi3"
7353 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7354 (mult:HI (zero_extend:HI
7355 (match_operand:QI 1 "nonimmediate_operand" ""))
7357 (match_operand:QI 2 "register_operand" ""))))
7358 (clobber (reg:CC FLAGS_REG))])]
7359 "TARGET_QIMODE_MATH"
7362 (define_insn "*umulqihi3_1"
7363 [(set (match_operand:HI 0 "register_operand" "=a")
7364 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7365 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7366 (clobber (reg:CC FLAGS_REG))]
7368 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7370 [(set_attr "type" "imul")
7371 (set_attr "length_immediate" "0")
7372 (set (attr "athlon_decode")
7373 (if_then_else (eq_attr "cpu" "athlon")
7374 (const_string "vector")
7375 (const_string "direct")))
7376 (set_attr "amdfam10_decode" "direct")
7377 (set_attr "mode" "QI")])
7379 (define_expand "mulqihi3"
7380 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7381 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7382 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7383 (clobber (reg:CC FLAGS_REG))])]
7384 "TARGET_QIMODE_MATH"
7387 (define_insn "*mulqihi3_insn"
7388 [(set (match_operand:HI 0 "register_operand" "=a")
7389 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7390 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7391 (clobber (reg:CC FLAGS_REG))]
7393 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7395 [(set_attr "type" "imul")
7396 (set_attr "length_immediate" "0")
7397 (set (attr "athlon_decode")
7398 (if_then_else (eq_attr "cpu" "athlon")
7399 (const_string "vector")
7400 (const_string "direct")))
7401 (set_attr "amdfam10_decode" "direct")
7402 (set_attr "mode" "QI")])
7404 (define_expand "umulditi3"
7405 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7406 (mult:TI (zero_extend:TI
7407 (match_operand:DI 1 "nonimmediate_operand" ""))
7409 (match_operand:DI 2 "register_operand" ""))))
7410 (clobber (reg:CC FLAGS_REG))])]
7414 (define_insn "*umulditi3_insn"
7415 [(set (match_operand:TI 0 "register_operand" "=A")
7416 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7417 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7418 (clobber (reg:CC FLAGS_REG))]
7420 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7422 [(set_attr "type" "imul")
7423 (set_attr "length_immediate" "0")
7424 (set (attr "athlon_decode")
7425 (if_then_else (eq_attr "cpu" "athlon")
7426 (const_string "vector")
7427 (const_string "double")))
7428 (set_attr "amdfam10_decode" "double")
7429 (set_attr "mode" "DI")])
7431 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7432 (define_expand "umulsidi3"
7433 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7434 (mult:DI (zero_extend:DI
7435 (match_operand:SI 1 "nonimmediate_operand" ""))
7437 (match_operand:SI 2 "register_operand" ""))))
7438 (clobber (reg:CC FLAGS_REG))])]
7442 (define_insn "*umulsidi3_insn"
7443 [(set (match_operand:DI 0 "register_operand" "=A")
7444 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7445 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7446 (clobber (reg:CC FLAGS_REG))]
7448 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7450 [(set_attr "type" "imul")
7451 (set_attr "length_immediate" "0")
7452 (set (attr "athlon_decode")
7453 (if_then_else (eq_attr "cpu" "athlon")
7454 (const_string "vector")
7455 (const_string "double")))
7456 (set_attr "amdfam10_decode" "double")
7457 (set_attr "mode" "SI")])
7459 (define_expand "mulditi3"
7460 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7461 (mult:TI (sign_extend:TI
7462 (match_operand:DI 1 "nonimmediate_operand" ""))
7464 (match_operand:DI 2 "register_operand" ""))))
7465 (clobber (reg:CC FLAGS_REG))])]
7469 (define_insn "*mulditi3_insn"
7470 [(set (match_operand:TI 0 "register_operand" "=A")
7471 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7472 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7473 (clobber (reg:CC FLAGS_REG))]
7475 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7477 [(set_attr "type" "imul")
7478 (set_attr "length_immediate" "0")
7479 (set (attr "athlon_decode")
7480 (if_then_else (eq_attr "cpu" "athlon")
7481 (const_string "vector")
7482 (const_string "double")))
7483 (set_attr "amdfam10_decode" "double")
7484 (set_attr "mode" "DI")])
7486 (define_expand "mulsidi3"
7487 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7488 (mult:DI (sign_extend:DI
7489 (match_operand:SI 1 "nonimmediate_operand" ""))
7491 (match_operand:SI 2 "register_operand" ""))))
7492 (clobber (reg:CC FLAGS_REG))])]
7496 (define_insn "*mulsidi3_insn"
7497 [(set (match_operand:DI 0 "register_operand" "=A")
7498 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7499 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7500 (clobber (reg:CC FLAGS_REG))]
7502 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7504 [(set_attr "type" "imul")
7505 (set_attr "length_immediate" "0")
7506 (set (attr "athlon_decode")
7507 (if_then_else (eq_attr "cpu" "athlon")
7508 (const_string "vector")
7509 (const_string "double")))
7510 (set_attr "amdfam10_decode" "double")
7511 (set_attr "mode" "SI")])
7513 (define_expand "umuldi3_highpart"
7514 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7517 (mult:TI (zero_extend:TI
7518 (match_operand:DI 1 "nonimmediate_operand" ""))
7520 (match_operand:DI 2 "register_operand" "")))
7522 (clobber (match_scratch:DI 3 ""))
7523 (clobber (reg:CC FLAGS_REG))])]
7527 (define_insn "*umuldi3_highpart_rex64"
7528 [(set (match_operand:DI 0 "register_operand" "=d")
7531 (mult:TI (zero_extend:TI
7532 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7534 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7536 (clobber (match_scratch:DI 3 "=1"))
7537 (clobber (reg:CC FLAGS_REG))]
7539 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7541 [(set_attr "type" "imul")
7542 (set_attr "length_immediate" "0")
7543 (set (attr "athlon_decode")
7544 (if_then_else (eq_attr "cpu" "athlon")
7545 (const_string "vector")
7546 (const_string "double")))
7547 (set_attr "amdfam10_decode" "double")
7548 (set_attr "mode" "DI")])
7550 (define_expand "umulsi3_highpart"
7551 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7554 (mult:DI (zero_extend:DI
7555 (match_operand:SI 1 "nonimmediate_operand" ""))
7557 (match_operand:SI 2 "register_operand" "")))
7559 (clobber (match_scratch:SI 3 ""))
7560 (clobber (reg:CC FLAGS_REG))])]
7564 (define_insn "*umulsi3_highpart_insn"
7565 [(set (match_operand:SI 0 "register_operand" "=d")
7568 (mult:DI (zero_extend:DI
7569 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7571 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7573 (clobber (match_scratch:SI 3 "=1"))
7574 (clobber (reg:CC FLAGS_REG))]
7575 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7577 [(set_attr "type" "imul")
7578 (set_attr "length_immediate" "0")
7579 (set (attr "athlon_decode")
7580 (if_then_else (eq_attr "cpu" "athlon")
7581 (const_string "vector")
7582 (const_string "double")))
7583 (set_attr "amdfam10_decode" "double")
7584 (set_attr "mode" "SI")])
7586 (define_insn "*umulsi3_highpart_zext"
7587 [(set (match_operand:DI 0 "register_operand" "=d")
7588 (zero_extend:DI (truncate:SI
7590 (mult:DI (zero_extend:DI
7591 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7593 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7595 (clobber (match_scratch:SI 3 "=1"))
7596 (clobber (reg:CC FLAGS_REG))]
7598 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7600 [(set_attr "type" "imul")
7601 (set_attr "length_immediate" "0")
7602 (set (attr "athlon_decode")
7603 (if_then_else (eq_attr "cpu" "athlon")
7604 (const_string "vector")
7605 (const_string "double")))
7606 (set_attr "amdfam10_decode" "double")
7607 (set_attr "mode" "SI")])
7609 (define_expand "smuldi3_highpart"
7610 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7613 (mult:TI (sign_extend:TI
7614 (match_operand:DI 1 "nonimmediate_operand" ""))
7616 (match_operand:DI 2 "register_operand" "")))
7618 (clobber (match_scratch:DI 3 ""))
7619 (clobber (reg:CC FLAGS_REG))])]
7623 (define_insn "*smuldi3_highpart_rex64"
7624 [(set (match_operand:DI 0 "register_operand" "=d")
7627 (mult:TI (sign_extend:TI
7628 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7630 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7632 (clobber (match_scratch:DI 3 "=1"))
7633 (clobber (reg:CC FLAGS_REG))]
7635 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7637 [(set_attr "type" "imul")
7638 (set (attr "athlon_decode")
7639 (if_then_else (eq_attr "cpu" "athlon")
7640 (const_string "vector")
7641 (const_string "double")))
7642 (set_attr "amdfam10_decode" "double")
7643 (set_attr "mode" "DI")])
7645 (define_expand "smulsi3_highpart"
7646 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7649 (mult:DI (sign_extend:DI
7650 (match_operand:SI 1 "nonimmediate_operand" ""))
7652 (match_operand:SI 2 "register_operand" "")))
7654 (clobber (match_scratch:SI 3 ""))
7655 (clobber (reg:CC FLAGS_REG))])]
7659 (define_insn "*smulsi3_highpart_insn"
7660 [(set (match_operand:SI 0 "register_operand" "=d")
7663 (mult:DI (sign_extend:DI
7664 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7666 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7668 (clobber (match_scratch:SI 3 "=1"))
7669 (clobber (reg:CC FLAGS_REG))]
7670 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7672 [(set_attr "type" "imul")
7673 (set (attr "athlon_decode")
7674 (if_then_else (eq_attr "cpu" "athlon")
7675 (const_string "vector")
7676 (const_string "double")))
7677 (set_attr "amdfam10_decode" "double")
7678 (set_attr "mode" "SI")])
7680 (define_insn "*smulsi3_highpart_zext"
7681 [(set (match_operand:DI 0 "register_operand" "=d")
7682 (zero_extend:DI (truncate:SI
7684 (mult:DI (sign_extend:DI
7685 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7687 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7689 (clobber (match_scratch:SI 3 "=1"))
7690 (clobber (reg:CC FLAGS_REG))]
7692 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7694 [(set_attr "type" "imul")
7695 (set (attr "athlon_decode")
7696 (if_then_else (eq_attr "cpu" "athlon")
7697 (const_string "vector")
7698 (const_string "double")))
7699 (set_attr "amdfam10_decode" "double")
7700 (set_attr "mode" "SI")])
7702 ;; The patterns that match these are at the end of this file.
7704 (define_expand "mulxf3"
7705 [(set (match_operand:XF 0 "register_operand" "")
7706 (mult:XF (match_operand:XF 1 "register_operand" "")
7707 (match_operand:XF 2 "register_operand" "")))]
7711 (define_expand "muldf3"
7712 [(set (match_operand:DF 0 "register_operand" "")
7713 (mult:DF (match_operand:DF 1 "register_operand" "")
7714 (match_operand:DF 2 "nonimmediate_operand" "")))]
7715 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7718 (define_expand "mulsf3"
7719 [(set (match_operand:SF 0 "register_operand" "")
7720 (mult:SF (match_operand:SF 1 "register_operand" "")
7721 (match_operand:SF 2 "nonimmediate_operand" "")))]
7722 "TARGET_80387 || TARGET_SSE_MATH"
7725 ;; Divide instructions
7727 (define_insn "divqi3"
7728 [(set (match_operand:QI 0 "register_operand" "=a")
7729 (div:QI (match_operand:HI 1 "register_operand" "0")
7730 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7731 (clobber (reg:CC FLAGS_REG))]
7732 "TARGET_QIMODE_MATH"
7734 [(set_attr "type" "idiv")
7735 (set_attr "mode" "QI")])
7737 (define_insn "udivqi3"
7738 [(set (match_operand:QI 0 "register_operand" "=a")
7739 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7740 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7741 (clobber (reg:CC FLAGS_REG))]
7742 "TARGET_QIMODE_MATH"
7744 [(set_attr "type" "idiv")
7745 (set_attr "mode" "QI")])
7747 ;; The patterns that match these are at the end of this file.
7749 (define_expand "divxf3"
7750 [(set (match_operand:XF 0 "register_operand" "")
7751 (div:XF (match_operand:XF 1 "register_operand" "")
7752 (match_operand:XF 2 "register_operand" "")))]
7756 (define_expand "divdf3"
7757 [(set (match_operand:DF 0 "register_operand" "")
7758 (div:DF (match_operand:DF 1 "register_operand" "")
7759 (match_operand:DF 2 "nonimmediate_operand" "")))]
7760 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7763 (define_expand "divsf3"
7764 [(set (match_operand:SF 0 "register_operand" "")
7765 (div:SF (match_operand:SF 1 "register_operand" "")
7766 (match_operand:SF 2 "nonimmediate_operand" "")))]
7767 "TARGET_80387 || TARGET_SSE_MATH"
7770 ;; Remainder instructions.
7772 (define_expand "divmoddi4"
7773 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7774 (div:DI (match_operand:DI 1 "register_operand" "")
7775 (match_operand:DI 2 "nonimmediate_operand" "")))
7776 (set (match_operand:DI 3 "register_operand" "")
7777 (mod:DI (match_dup 1) (match_dup 2)))
7778 (clobber (reg:CC FLAGS_REG))])]
7782 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7783 ;; Penalize eax case slightly because it results in worse scheduling
7785 (define_insn "*divmoddi4_nocltd_rex64"
7786 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7787 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7788 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7789 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7790 (mod:DI (match_dup 2) (match_dup 3)))
7791 (clobber (reg:CC FLAGS_REG))]
7792 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7794 [(set_attr "type" "multi")])
7796 (define_insn "*divmoddi4_cltd_rex64"
7797 [(set (match_operand:DI 0 "register_operand" "=a")
7798 (div:DI (match_operand:DI 2 "register_operand" "a")
7799 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7800 (set (match_operand:DI 1 "register_operand" "=&d")
7801 (mod:DI (match_dup 2) (match_dup 3)))
7802 (clobber (reg:CC FLAGS_REG))]
7803 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7805 [(set_attr "type" "multi")])
7807 (define_insn "*divmoddi_noext_rex64"
7808 [(set (match_operand:DI 0 "register_operand" "=a")
7809 (div:DI (match_operand:DI 1 "register_operand" "0")
7810 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7811 (set (match_operand:DI 3 "register_operand" "=d")
7812 (mod:DI (match_dup 1) (match_dup 2)))
7813 (use (match_operand:DI 4 "register_operand" "3"))
7814 (clobber (reg:CC FLAGS_REG))]
7817 [(set_attr "type" "idiv")
7818 (set_attr "mode" "DI")])
7821 [(set (match_operand:DI 0 "register_operand" "")
7822 (div:DI (match_operand:DI 1 "register_operand" "")
7823 (match_operand:DI 2 "nonimmediate_operand" "")))
7824 (set (match_operand:DI 3 "register_operand" "")
7825 (mod:DI (match_dup 1) (match_dup 2)))
7826 (clobber (reg:CC FLAGS_REG))]
7827 "TARGET_64BIT && reload_completed"
7828 [(parallel [(set (match_dup 3)
7829 (ashiftrt:DI (match_dup 4) (const_int 63)))
7830 (clobber (reg:CC FLAGS_REG))])
7831 (parallel [(set (match_dup 0)
7832 (div:DI (reg:DI 0) (match_dup 2)))
7834 (mod:DI (reg:DI 0) (match_dup 2)))
7836 (clobber (reg:CC FLAGS_REG))])]
7838 /* Avoid use of cltd in favor of a mov+shift. */
7839 if (!TARGET_USE_CLTD && !optimize_size)
7841 if (true_regnum (operands[1]))
7842 emit_move_insn (operands[0], operands[1]);
7844 emit_move_insn (operands[3], operands[1]);
7845 operands[4] = operands[3];
7849 gcc_assert (!true_regnum (operands[1]));
7850 operands[4] = operands[1];
7855 (define_expand "divmodsi4"
7856 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7857 (div:SI (match_operand:SI 1 "register_operand" "")
7858 (match_operand:SI 2 "nonimmediate_operand" "")))
7859 (set (match_operand:SI 3 "register_operand" "")
7860 (mod:SI (match_dup 1) (match_dup 2)))
7861 (clobber (reg:CC FLAGS_REG))])]
7865 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7866 ;; Penalize eax case slightly because it results in worse scheduling
7868 (define_insn "*divmodsi4_nocltd"
7869 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7870 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7871 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7872 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7873 (mod:SI (match_dup 2) (match_dup 3)))
7874 (clobber (reg:CC FLAGS_REG))]
7875 "!optimize_size && !TARGET_USE_CLTD"
7877 [(set_attr "type" "multi")])
7879 (define_insn "*divmodsi4_cltd"
7880 [(set (match_operand:SI 0 "register_operand" "=a")
7881 (div:SI (match_operand:SI 2 "register_operand" "a")
7882 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7883 (set (match_operand:SI 1 "register_operand" "=&d")
7884 (mod:SI (match_dup 2) (match_dup 3)))
7885 (clobber (reg:CC FLAGS_REG))]
7886 "optimize_size || TARGET_USE_CLTD"
7888 [(set_attr "type" "multi")])
7890 (define_insn "*divmodsi_noext"
7891 [(set (match_operand:SI 0 "register_operand" "=a")
7892 (div:SI (match_operand:SI 1 "register_operand" "0")
7893 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7894 (set (match_operand:SI 3 "register_operand" "=d")
7895 (mod:SI (match_dup 1) (match_dup 2)))
7896 (use (match_operand:SI 4 "register_operand" "3"))
7897 (clobber (reg:CC FLAGS_REG))]
7900 [(set_attr "type" "idiv")
7901 (set_attr "mode" "SI")])
7904 [(set (match_operand:SI 0 "register_operand" "")
7905 (div:SI (match_operand:SI 1 "register_operand" "")
7906 (match_operand:SI 2 "nonimmediate_operand" "")))
7907 (set (match_operand:SI 3 "register_operand" "")
7908 (mod:SI (match_dup 1) (match_dup 2)))
7909 (clobber (reg:CC FLAGS_REG))]
7911 [(parallel [(set (match_dup 3)
7912 (ashiftrt:SI (match_dup 4) (const_int 31)))
7913 (clobber (reg:CC FLAGS_REG))])
7914 (parallel [(set (match_dup 0)
7915 (div:SI (reg:SI 0) (match_dup 2)))
7917 (mod:SI (reg:SI 0) (match_dup 2)))
7919 (clobber (reg:CC FLAGS_REG))])]
7921 /* Avoid use of cltd in favor of a mov+shift. */
7922 if (!TARGET_USE_CLTD && !optimize_size)
7924 if (true_regnum (operands[1]))
7925 emit_move_insn (operands[0], operands[1]);
7927 emit_move_insn (operands[3], operands[1]);
7928 operands[4] = operands[3];
7932 gcc_assert (!true_regnum (operands[1]));
7933 operands[4] = operands[1];
7937 (define_insn "divmodhi4"
7938 [(set (match_operand:HI 0 "register_operand" "=a")
7939 (div:HI (match_operand:HI 1 "register_operand" "0")
7940 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7941 (set (match_operand:HI 3 "register_operand" "=&d")
7942 (mod:HI (match_dup 1) (match_dup 2)))
7943 (clobber (reg:CC FLAGS_REG))]
7944 "TARGET_HIMODE_MATH"
7946 [(set_attr "type" "multi")
7947 (set_attr "length_immediate" "0")
7948 (set_attr "mode" "SI")])
7950 (define_insn "udivmoddi4"
7951 [(set (match_operand:DI 0 "register_operand" "=a")
7952 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7953 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7954 (set (match_operand:DI 3 "register_operand" "=&d")
7955 (umod:DI (match_dup 1) (match_dup 2)))
7956 (clobber (reg:CC FLAGS_REG))]
7958 "xor{q}\t%3, %3\;div{q}\t%2"
7959 [(set_attr "type" "multi")
7960 (set_attr "length_immediate" "0")
7961 (set_attr "mode" "DI")])
7963 (define_insn "*udivmoddi4_noext"
7964 [(set (match_operand:DI 0 "register_operand" "=a")
7965 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7966 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7967 (set (match_operand:DI 3 "register_operand" "=d")
7968 (umod:DI (match_dup 1) (match_dup 2)))
7970 (clobber (reg:CC FLAGS_REG))]
7973 [(set_attr "type" "idiv")
7974 (set_attr "mode" "DI")])
7977 [(set (match_operand:DI 0 "register_operand" "")
7978 (udiv:DI (match_operand:DI 1 "register_operand" "")
7979 (match_operand:DI 2 "nonimmediate_operand" "")))
7980 (set (match_operand:DI 3 "register_operand" "")
7981 (umod:DI (match_dup 1) (match_dup 2)))
7982 (clobber (reg:CC FLAGS_REG))]
7983 "TARGET_64BIT && reload_completed"
7984 [(set (match_dup 3) (const_int 0))
7985 (parallel [(set (match_dup 0)
7986 (udiv:DI (match_dup 1) (match_dup 2)))
7988 (umod:DI (match_dup 1) (match_dup 2)))
7990 (clobber (reg:CC FLAGS_REG))])]
7993 (define_insn "udivmodsi4"
7994 [(set (match_operand:SI 0 "register_operand" "=a")
7995 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7996 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7997 (set (match_operand:SI 3 "register_operand" "=&d")
7998 (umod:SI (match_dup 1) (match_dup 2)))
7999 (clobber (reg:CC FLAGS_REG))]
8001 "xor{l}\t%3, %3\;div{l}\t%2"
8002 [(set_attr "type" "multi")
8003 (set_attr "length_immediate" "0")
8004 (set_attr "mode" "SI")])
8006 (define_insn "*udivmodsi4_noext"
8007 [(set (match_operand:SI 0 "register_operand" "=a")
8008 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8009 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8010 (set (match_operand:SI 3 "register_operand" "=d")
8011 (umod:SI (match_dup 1) (match_dup 2)))
8013 (clobber (reg:CC FLAGS_REG))]
8016 [(set_attr "type" "idiv")
8017 (set_attr "mode" "SI")])
8020 [(set (match_operand:SI 0 "register_operand" "")
8021 (udiv:SI (match_operand:SI 1 "register_operand" "")
8022 (match_operand:SI 2 "nonimmediate_operand" "")))
8023 (set (match_operand:SI 3 "register_operand" "")
8024 (umod:SI (match_dup 1) (match_dup 2)))
8025 (clobber (reg:CC FLAGS_REG))]
8027 [(set (match_dup 3) (const_int 0))
8028 (parallel [(set (match_dup 0)
8029 (udiv:SI (match_dup 1) (match_dup 2)))
8031 (umod:SI (match_dup 1) (match_dup 2)))
8033 (clobber (reg:CC FLAGS_REG))])]
8036 (define_expand "udivmodhi4"
8037 [(set (match_dup 4) (const_int 0))
8038 (parallel [(set (match_operand:HI 0 "register_operand" "")
8039 (udiv:HI (match_operand:HI 1 "register_operand" "")
8040 (match_operand:HI 2 "nonimmediate_operand" "")))
8041 (set (match_operand:HI 3 "register_operand" "")
8042 (umod:HI (match_dup 1) (match_dup 2)))
8044 (clobber (reg:CC FLAGS_REG))])]
8045 "TARGET_HIMODE_MATH"
8046 "operands[4] = gen_reg_rtx (HImode);")
8048 (define_insn "*udivmodhi_noext"
8049 [(set (match_operand:HI 0 "register_operand" "=a")
8050 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8051 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8052 (set (match_operand:HI 3 "register_operand" "=d")
8053 (umod:HI (match_dup 1) (match_dup 2)))
8054 (use (match_operand:HI 4 "register_operand" "3"))
8055 (clobber (reg:CC FLAGS_REG))]
8058 [(set_attr "type" "idiv")
8059 (set_attr "mode" "HI")])
8061 ;; We cannot use div/idiv for double division, because it causes
8062 ;; "division by zero" on the overflow and that's not what we expect
8063 ;; from truncate. Because true (non truncating) double division is
8064 ;; never generated, we can't create this insn anyway.
8067 ; [(set (match_operand:SI 0 "register_operand" "=a")
8069 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8071 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8072 ; (set (match_operand:SI 3 "register_operand" "=d")
8074 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8075 ; (clobber (reg:CC FLAGS_REG))]
8077 ; "div{l}\t{%2, %0|%0, %2}"
8078 ; [(set_attr "type" "idiv")])
8080 ;;- Logical AND instructions
8082 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8083 ;; Note that this excludes ah.
8085 (define_insn "*testdi_1_rex64"
8086 [(set (reg FLAGS_REG)
8088 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8089 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8091 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8092 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8094 test{l}\t{%k1, %k0|%k0, %k1}
8095 test{l}\t{%k1, %k0|%k0, %k1}
8096 test{q}\t{%1, %0|%0, %1}
8097 test{q}\t{%1, %0|%0, %1}
8098 test{q}\t{%1, %0|%0, %1}"
8099 [(set_attr "type" "test")
8100 (set_attr "modrm" "0,1,0,1,1")
8101 (set_attr "mode" "SI,SI,DI,DI,DI")
8102 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8104 (define_insn "testsi_1"
8105 [(set (reg FLAGS_REG)
8107 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8108 (match_operand:SI 1 "general_operand" "in,in,rin"))
8110 "ix86_match_ccmode (insn, CCNOmode)
8111 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8112 "test{l}\t{%1, %0|%0, %1}"
8113 [(set_attr "type" "test")
8114 (set_attr "modrm" "0,1,1")
8115 (set_attr "mode" "SI")
8116 (set_attr "pent_pair" "uv,np,uv")])
8118 (define_expand "testsi_ccno_1"
8119 [(set (reg:CCNO FLAGS_REG)
8121 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8122 (match_operand:SI 1 "nonmemory_operand" ""))
8127 (define_insn "*testhi_1"
8128 [(set (reg FLAGS_REG)
8129 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8130 (match_operand:HI 1 "general_operand" "n,n,rn"))
8132 "ix86_match_ccmode (insn, CCNOmode)
8133 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8134 "test{w}\t{%1, %0|%0, %1}"
8135 [(set_attr "type" "test")
8136 (set_attr "modrm" "0,1,1")
8137 (set_attr "mode" "HI")
8138 (set_attr "pent_pair" "uv,np,uv")])
8140 (define_expand "testqi_ccz_1"
8141 [(set (reg:CCZ FLAGS_REG)
8142 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8143 (match_operand:QI 1 "nonmemory_operand" ""))
8148 (define_insn "*testqi_1_maybe_si"
8149 [(set (reg FLAGS_REG)
8152 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8153 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8155 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8156 && ix86_match_ccmode (insn,
8157 CONST_INT_P (operands[1])
8158 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8160 if (which_alternative == 3)
8162 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8163 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8164 return "test{l}\t{%1, %k0|%k0, %1}";
8166 return "test{b}\t{%1, %0|%0, %1}";
8168 [(set_attr "type" "test")
8169 (set_attr "modrm" "0,1,1,1")
8170 (set_attr "mode" "QI,QI,QI,SI")
8171 (set_attr "pent_pair" "uv,np,uv,np")])
8173 (define_insn "*testqi_1"
8174 [(set (reg FLAGS_REG)
8177 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8178 (match_operand:QI 1 "general_operand" "n,n,qn"))
8180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8181 && ix86_match_ccmode (insn, CCNOmode)"
8182 "test{b}\t{%1, %0|%0, %1}"
8183 [(set_attr "type" "test")
8184 (set_attr "modrm" "0,1,1")
8185 (set_attr "mode" "QI")
8186 (set_attr "pent_pair" "uv,np,uv")])
8188 (define_expand "testqi_ext_ccno_0"
8189 [(set (reg:CCNO FLAGS_REG)
8193 (match_operand 0 "ext_register_operand" "")
8196 (match_operand 1 "const_int_operand" ""))
8201 (define_insn "*testqi_ext_0"
8202 [(set (reg FLAGS_REG)
8206 (match_operand 0 "ext_register_operand" "Q")
8209 (match_operand 1 "const_int_operand" "n"))
8211 "ix86_match_ccmode (insn, CCNOmode)"
8212 "test{b}\t{%1, %h0|%h0, %1}"
8213 [(set_attr "type" "test")
8214 (set_attr "mode" "QI")
8215 (set_attr "length_immediate" "1")
8216 (set_attr "pent_pair" "np")])
8218 (define_insn "*testqi_ext_1"
8219 [(set (reg FLAGS_REG)
8223 (match_operand 0 "ext_register_operand" "Q")
8227 (match_operand:QI 1 "general_operand" "Qm")))
8229 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8230 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8231 "test{b}\t{%1, %h0|%h0, %1}"
8232 [(set_attr "type" "test")
8233 (set_attr "mode" "QI")])
8235 (define_insn "*testqi_ext_1_rex64"
8236 [(set (reg FLAGS_REG)
8240 (match_operand 0 "ext_register_operand" "Q")
8244 (match_operand:QI 1 "register_operand" "Q")))
8246 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8247 "test{b}\t{%1, %h0|%h0, %1}"
8248 [(set_attr "type" "test")
8249 (set_attr "mode" "QI")])
8251 (define_insn "*testqi_ext_2"
8252 [(set (reg FLAGS_REG)
8256 (match_operand 0 "ext_register_operand" "Q")
8260 (match_operand 1 "ext_register_operand" "Q")
8264 "ix86_match_ccmode (insn, CCNOmode)"
8265 "test{b}\t{%h1, %h0|%h0, %h1}"
8266 [(set_attr "type" "test")
8267 (set_attr "mode" "QI")])
8269 ;; Combine likes to form bit extractions for some tests. Humor it.
8270 (define_insn "*testqi_ext_3"
8271 [(set (reg FLAGS_REG)
8272 (compare (zero_extract:SI
8273 (match_operand 0 "nonimmediate_operand" "rm")
8274 (match_operand:SI 1 "const_int_operand" "")
8275 (match_operand:SI 2 "const_int_operand" ""))
8277 "ix86_match_ccmode (insn, CCNOmode)
8278 && INTVAL (operands[1]) > 0
8279 && INTVAL (operands[2]) >= 0
8280 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8281 && (GET_MODE (operands[0]) == SImode
8282 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8283 || GET_MODE (operands[0]) == HImode
8284 || GET_MODE (operands[0]) == QImode)"
8287 (define_insn "*testqi_ext_3_rex64"
8288 [(set (reg FLAGS_REG)
8289 (compare (zero_extract:DI
8290 (match_operand 0 "nonimmediate_operand" "rm")
8291 (match_operand:DI 1 "const_int_operand" "")
8292 (match_operand:DI 2 "const_int_operand" ""))
8295 && ix86_match_ccmode (insn, CCNOmode)
8296 && INTVAL (operands[1]) > 0
8297 && INTVAL (operands[2]) >= 0
8298 /* Ensure that resulting mask is zero or sign extended operand. */
8299 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8300 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8301 && INTVAL (operands[1]) > 32))
8302 && (GET_MODE (operands[0]) == SImode
8303 || GET_MODE (operands[0]) == DImode
8304 || GET_MODE (operands[0]) == HImode
8305 || GET_MODE (operands[0]) == QImode)"
8309 [(set (match_operand 0 "flags_reg_operand" "")
8310 (match_operator 1 "compare_operator"
8312 (match_operand 2 "nonimmediate_operand" "")
8313 (match_operand 3 "const_int_operand" "")
8314 (match_operand 4 "const_int_operand" ""))
8316 "ix86_match_ccmode (insn, CCNOmode)"
8317 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8319 rtx val = operands[2];
8320 HOST_WIDE_INT len = INTVAL (operands[3]);
8321 HOST_WIDE_INT pos = INTVAL (operands[4]);
8323 enum machine_mode mode, submode;
8325 mode = GET_MODE (val);
8328 /* ??? Combine likes to put non-volatile mem extractions in QImode
8329 no matter the size of the test. So find a mode that works. */
8330 if (! MEM_VOLATILE_P (val))
8332 mode = smallest_mode_for_size (pos + len, MODE_INT);
8333 val = adjust_address (val, mode, 0);
8336 else if (GET_CODE (val) == SUBREG
8337 && (submode = GET_MODE (SUBREG_REG (val)),
8338 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8339 && pos + len <= GET_MODE_BITSIZE (submode))
8341 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8343 val = SUBREG_REG (val);
8345 else if (mode == HImode && pos + len <= 8)
8347 /* Small HImode tests can be converted to QImode. */
8349 val = gen_lowpart (QImode, val);
8352 if (len == HOST_BITS_PER_WIDE_INT)
8355 mask = ((HOST_WIDE_INT)1 << len) - 1;
8358 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8361 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8362 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8363 ;; this is relatively important trick.
8364 ;; Do the conversion only post-reload to avoid limiting of the register class
8367 [(set (match_operand 0 "flags_reg_operand" "")
8368 (match_operator 1 "compare_operator"
8369 [(and (match_operand 2 "register_operand" "")
8370 (match_operand 3 "const_int_operand" ""))
8373 && QI_REG_P (operands[2])
8374 && GET_MODE (operands[2]) != QImode
8375 && ((ix86_match_ccmode (insn, CCZmode)
8376 && !(INTVAL (operands[3]) & ~(255 << 8)))
8377 || (ix86_match_ccmode (insn, CCNOmode)
8378 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8381 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8384 "operands[2] = gen_lowpart (SImode, operands[2]);
8385 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8388 [(set (match_operand 0 "flags_reg_operand" "")
8389 (match_operator 1 "compare_operator"
8390 [(and (match_operand 2 "nonimmediate_operand" "")
8391 (match_operand 3 "const_int_operand" ""))
8394 && GET_MODE (operands[2]) != QImode
8395 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8396 && ((ix86_match_ccmode (insn, CCZmode)
8397 && !(INTVAL (operands[3]) & ~255))
8398 || (ix86_match_ccmode (insn, CCNOmode)
8399 && !(INTVAL (operands[3]) & ~127)))"
8401 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8403 "operands[2] = gen_lowpart (QImode, operands[2]);
8404 operands[3] = gen_lowpart (QImode, operands[3]);")
8407 ;; %%% This used to optimize known byte-wide and operations to memory,
8408 ;; and sometimes to QImode registers. If this is considered useful,
8409 ;; it should be done with splitters.
8411 (define_expand "anddi3"
8412 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8413 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8414 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8415 (clobber (reg:CC FLAGS_REG))]
8417 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8419 (define_insn "*anddi_1_rex64"
8420 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8421 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8422 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8423 (clobber (reg:CC FLAGS_REG))]
8424 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8426 switch (get_attr_type (insn))
8430 enum machine_mode mode;
8432 gcc_assert (CONST_INT_P (operands[2]));
8433 if (INTVAL (operands[2]) == 0xff)
8437 gcc_assert (INTVAL (operands[2]) == 0xffff);
8441 operands[1] = gen_lowpart (mode, operands[1]);
8443 return "movz{bq|x}\t{%1,%0|%0, %1}";
8445 return "movz{wq|x}\t{%1,%0|%0, %1}";
8449 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8450 if (get_attr_mode (insn) == MODE_SI)
8451 return "and{l}\t{%k2, %k0|%k0, %k2}";
8453 return "and{q}\t{%2, %0|%0, %2}";
8456 [(set_attr "type" "alu,alu,alu,imovx")
8457 (set_attr "length_immediate" "*,*,*,0")
8458 (set_attr "mode" "SI,DI,DI,DI")])
8460 (define_insn "*anddi_2"
8461 [(set (reg FLAGS_REG)
8462 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8463 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8465 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8466 (and:DI (match_dup 1) (match_dup 2)))]
8467 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8468 && ix86_binary_operator_ok (AND, DImode, operands)"
8470 and{l}\t{%k2, %k0|%k0, %k2}
8471 and{q}\t{%2, %0|%0, %2}
8472 and{q}\t{%2, %0|%0, %2}"
8473 [(set_attr "type" "alu")
8474 (set_attr "mode" "SI,DI,DI")])
8476 (define_expand "andsi3"
8477 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8478 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8479 (match_operand:SI 2 "general_operand" "")))
8480 (clobber (reg:CC FLAGS_REG))]
8482 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8484 (define_insn "*andsi_1"
8485 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8486 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8487 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8488 (clobber (reg:CC FLAGS_REG))]
8489 "ix86_binary_operator_ok (AND, SImode, operands)"
8491 switch (get_attr_type (insn))
8495 enum machine_mode mode;
8497 gcc_assert (CONST_INT_P (operands[2]));
8498 if (INTVAL (operands[2]) == 0xff)
8502 gcc_assert (INTVAL (operands[2]) == 0xffff);
8506 operands[1] = gen_lowpart (mode, operands[1]);
8508 return "movz{bl|x}\t{%1,%0|%0, %1}";
8510 return "movz{wl|x}\t{%1,%0|%0, %1}";
8514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8515 return "and{l}\t{%2, %0|%0, %2}";
8518 [(set_attr "type" "alu,alu,imovx")
8519 (set_attr "length_immediate" "*,*,0")
8520 (set_attr "mode" "SI")])
8523 [(set (match_operand 0 "register_operand" "")
8525 (const_int -65536)))
8526 (clobber (reg:CC FLAGS_REG))]
8527 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8528 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8529 "operands[1] = gen_lowpart (HImode, operands[0]);")
8532 [(set (match_operand 0 "ext_register_operand" "")
8535 (clobber (reg:CC FLAGS_REG))]
8536 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8537 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8538 "operands[1] = gen_lowpart (QImode, operands[0]);")
8541 [(set (match_operand 0 "ext_register_operand" "")
8543 (const_int -65281)))
8544 (clobber (reg:CC FLAGS_REG))]
8545 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8546 [(parallel [(set (zero_extract:SI (match_dup 0)
8550 (zero_extract:SI (match_dup 0)
8553 (zero_extract:SI (match_dup 0)
8556 (clobber (reg:CC FLAGS_REG))])]
8557 "operands[0] = gen_lowpart (SImode, operands[0]);")
8559 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8560 (define_insn "*andsi_1_zext"
8561 [(set (match_operand:DI 0 "register_operand" "=r")
8563 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8564 (match_operand:SI 2 "general_operand" "rim"))))
8565 (clobber (reg:CC FLAGS_REG))]
8566 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8567 "and{l}\t{%2, %k0|%k0, %2}"
8568 [(set_attr "type" "alu")
8569 (set_attr "mode" "SI")])
8571 (define_insn "*andsi_2"
8572 [(set (reg FLAGS_REG)
8573 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8574 (match_operand:SI 2 "general_operand" "rim,ri"))
8576 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8577 (and:SI (match_dup 1) (match_dup 2)))]
8578 "ix86_match_ccmode (insn, CCNOmode)
8579 && ix86_binary_operator_ok (AND, SImode, operands)"
8580 "and{l}\t{%2, %0|%0, %2}"
8581 [(set_attr "type" "alu")
8582 (set_attr "mode" "SI")])
8584 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8585 (define_insn "*andsi_2_zext"
8586 [(set (reg FLAGS_REG)
8587 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8588 (match_operand:SI 2 "general_operand" "rim"))
8590 (set (match_operand:DI 0 "register_operand" "=r")
8591 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8592 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8593 && ix86_binary_operator_ok (AND, SImode, operands)"
8594 "and{l}\t{%2, %k0|%k0, %2}"
8595 [(set_attr "type" "alu")
8596 (set_attr "mode" "SI")])
8598 (define_expand "andhi3"
8599 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8600 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8601 (match_operand:HI 2 "general_operand" "")))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "TARGET_HIMODE_MATH"
8604 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8606 (define_insn "*andhi_1"
8607 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8608 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8609 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8610 (clobber (reg:CC FLAGS_REG))]
8611 "ix86_binary_operator_ok (AND, HImode, operands)"
8613 switch (get_attr_type (insn))
8616 gcc_assert (CONST_INT_P (operands[2]));
8617 gcc_assert (INTVAL (operands[2]) == 0xff);
8618 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8621 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8623 return "and{w}\t{%2, %0|%0, %2}";
8626 [(set_attr "type" "alu,alu,imovx")
8627 (set_attr "length_immediate" "*,*,0")
8628 (set_attr "mode" "HI,HI,SI")])
8630 (define_insn "*andhi_2"
8631 [(set (reg FLAGS_REG)
8632 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8633 (match_operand:HI 2 "general_operand" "rim,ri"))
8635 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8636 (and:HI (match_dup 1) (match_dup 2)))]
8637 "ix86_match_ccmode (insn, CCNOmode)
8638 && ix86_binary_operator_ok (AND, HImode, operands)"
8639 "and{w}\t{%2, %0|%0, %2}"
8640 [(set_attr "type" "alu")
8641 (set_attr "mode" "HI")])
8643 (define_expand "andqi3"
8644 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8645 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8646 (match_operand:QI 2 "general_operand" "")))
8647 (clobber (reg:CC FLAGS_REG))]
8648 "TARGET_QIMODE_MATH"
8649 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8651 ;; %%% Potential partial reg stall on alternative 2. What to do?
8652 (define_insn "*andqi_1"
8653 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8654 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8655 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8656 (clobber (reg:CC FLAGS_REG))]
8657 "ix86_binary_operator_ok (AND, QImode, operands)"
8659 and{b}\t{%2, %0|%0, %2}
8660 and{b}\t{%2, %0|%0, %2}
8661 and{l}\t{%k2, %k0|%k0, %k2}"
8662 [(set_attr "type" "alu")
8663 (set_attr "mode" "QI,QI,SI")])
8665 (define_insn "*andqi_1_slp"
8666 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8667 (and:QI (match_dup 0)
8668 (match_operand:QI 1 "general_operand" "qi,qmi")))
8669 (clobber (reg:CC FLAGS_REG))]
8670 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8671 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8672 "and{b}\t{%1, %0|%0, %1}"
8673 [(set_attr "type" "alu1")
8674 (set_attr "mode" "QI")])
8676 (define_insn "*andqi_2_maybe_si"
8677 [(set (reg FLAGS_REG)
8679 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8680 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8682 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8683 (and:QI (match_dup 1) (match_dup 2)))]
8684 "ix86_binary_operator_ok (AND, QImode, operands)
8685 && ix86_match_ccmode (insn,
8686 CONST_INT_P (operands[2])
8687 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8689 if (which_alternative == 2)
8691 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8692 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8693 return "and{l}\t{%2, %k0|%k0, %2}";
8695 return "and{b}\t{%2, %0|%0, %2}";
8697 [(set_attr "type" "alu")
8698 (set_attr "mode" "QI,QI,SI")])
8700 (define_insn "*andqi_2"
8701 [(set (reg FLAGS_REG)
8703 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8704 (match_operand:QI 2 "general_operand" "qim,qi"))
8706 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8707 (and:QI (match_dup 1) (match_dup 2)))]
8708 "ix86_match_ccmode (insn, CCNOmode)
8709 && ix86_binary_operator_ok (AND, QImode, operands)"
8710 "and{b}\t{%2, %0|%0, %2}"
8711 [(set_attr "type" "alu")
8712 (set_attr "mode" "QI")])
8714 (define_insn "*andqi_2_slp"
8715 [(set (reg FLAGS_REG)
8717 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8718 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8720 (set (strict_low_part (match_dup 0))
8721 (and:QI (match_dup 0) (match_dup 1)))]
8722 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8723 && ix86_match_ccmode (insn, CCNOmode)
8724 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8725 "and{b}\t{%1, %0|%0, %1}"
8726 [(set_attr "type" "alu1")
8727 (set_attr "mode" "QI")])
8729 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8730 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8731 ;; for a QImode operand, which of course failed.
8733 (define_insn "andqi_ext_0"
8734 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8739 (match_operand 1 "ext_register_operand" "0")
8742 (match_operand 2 "const_int_operand" "n")))
8743 (clobber (reg:CC FLAGS_REG))]
8745 "and{b}\t{%2, %h0|%h0, %2}"
8746 [(set_attr "type" "alu")
8747 (set_attr "length_immediate" "1")
8748 (set_attr "mode" "QI")])
8750 ;; Generated by peephole translating test to and. This shows up
8751 ;; often in fp comparisons.
8753 (define_insn "*andqi_ext_0_cc"
8754 [(set (reg FLAGS_REG)
8758 (match_operand 1 "ext_register_operand" "0")
8761 (match_operand 2 "const_int_operand" "n"))
8763 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8772 "ix86_match_ccmode (insn, CCNOmode)"
8773 "and{b}\t{%2, %h0|%h0, %2}"
8774 [(set_attr "type" "alu")
8775 (set_attr "length_immediate" "1")
8776 (set_attr "mode" "QI")])
8778 (define_insn "*andqi_ext_1"
8779 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8784 (match_operand 1 "ext_register_operand" "0")
8788 (match_operand:QI 2 "general_operand" "Qm"))))
8789 (clobber (reg:CC FLAGS_REG))]
8791 "and{b}\t{%2, %h0|%h0, %2}"
8792 [(set_attr "type" "alu")
8793 (set_attr "length_immediate" "0")
8794 (set_attr "mode" "QI")])
8796 (define_insn "*andqi_ext_1_rex64"
8797 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8802 (match_operand 1 "ext_register_operand" "0")
8806 (match_operand 2 "ext_register_operand" "Q"))))
8807 (clobber (reg:CC FLAGS_REG))]
8809 "and{b}\t{%2, %h0|%h0, %2}"
8810 [(set_attr "type" "alu")
8811 (set_attr "length_immediate" "0")
8812 (set_attr "mode" "QI")])
8814 (define_insn "*andqi_ext_2"
8815 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8820 (match_operand 1 "ext_register_operand" "%0")
8824 (match_operand 2 "ext_register_operand" "Q")
8827 (clobber (reg:CC FLAGS_REG))]
8829 "and{b}\t{%h2, %h0|%h0, %h2}"
8830 [(set_attr "type" "alu")
8831 (set_attr "length_immediate" "0")
8832 (set_attr "mode" "QI")])
8834 ;; Convert wide AND instructions with immediate operand to shorter QImode
8835 ;; equivalents when possible.
8836 ;; Don't do the splitting with memory operands, since it introduces risk
8837 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8838 ;; for size, but that can (should?) be handled by generic code instead.
8840 [(set (match_operand 0 "register_operand" "")
8841 (and (match_operand 1 "register_operand" "")
8842 (match_operand 2 "const_int_operand" "")))
8843 (clobber (reg:CC FLAGS_REG))]
8845 && QI_REG_P (operands[0])
8846 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8847 && !(~INTVAL (operands[2]) & ~(255 << 8))
8848 && GET_MODE (operands[0]) != QImode"
8849 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8850 (and:SI (zero_extract:SI (match_dup 1)
8851 (const_int 8) (const_int 8))
8853 (clobber (reg:CC FLAGS_REG))])]
8854 "operands[0] = gen_lowpart (SImode, operands[0]);
8855 operands[1] = gen_lowpart (SImode, operands[1]);
8856 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8858 ;; Since AND can be encoded with sign extended immediate, this is only
8859 ;; profitable when 7th bit is not set.
8861 [(set (match_operand 0 "register_operand" "")
8862 (and (match_operand 1 "general_operand" "")
8863 (match_operand 2 "const_int_operand" "")))
8864 (clobber (reg:CC FLAGS_REG))]
8866 && ANY_QI_REG_P (operands[0])
8867 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8868 && !(~INTVAL (operands[2]) & ~255)
8869 && !(INTVAL (operands[2]) & 128)
8870 && GET_MODE (operands[0]) != QImode"
8871 [(parallel [(set (strict_low_part (match_dup 0))
8872 (and:QI (match_dup 1)
8874 (clobber (reg:CC FLAGS_REG))])]
8875 "operands[0] = gen_lowpart (QImode, operands[0]);
8876 operands[1] = gen_lowpart (QImode, operands[1]);
8877 operands[2] = gen_lowpart (QImode, operands[2]);")
8879 ;; Logical inclusive OR instructions
8881 ;; %%% This used to optimize known byte-wide and operations to memory.
8882 ;; If this is considered useful, it should be done with splitters.
8884 (define_expand "iordi3"
8885 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8886 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8887 (match_operand:DI 2 "x86_64_general_operand" "")))
8888 (clobber (reg:CC FLAGS_REG))]
8890 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8892 (define_insn "*iordi_1_rex64"
8893 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8894 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8895 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8896 (clobber (reg:CC FLAGS_REG))]
8898 && ix86_binary_operator_ok (IOR, DImode, operands)"
8899 "or{q}\t{%2, %0|%0, %2}"
8900 [(set_attr "type" "alu")
8901 (set_attr "mode" "DI")])
8903 (define_insn "*iordi_2_rex64"
8904 [(set (reg FLAGS_REG)
8905 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8906 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8908 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8909 (ior:DI (match_dup 1) (match_dup 2)))]
8911 && ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_binary_operator_ok (IOR, DImode, operands)"
8913 "or{q}\t{%2, %0|%0, %2}"
8914 [(set_attr "type" "alu")
8915 (set_attr "mode" "DI")])
8917 (define_insn "*iordi_3_rex64"
8918 [(set (reg FLAGS_REG)
8919 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8920 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8922 (clobber (match_scratch:DI 0 "=r"))]
8924 && ix86_match_ccmode (insn, CCNOmode)
8925 && ix86_binary_operator_ok (IOR, DImode, operands)"
8926 "or{q}\t{%2, %0|%0, %2}"
8927 [(set_attr "type" "alu")
8928 (set_attr "mode" "DI")])
8931 (define_expand "iorsi3"
8932 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8933 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8934 (match_operand:SI 2 "general_operand" "")))
8935 (clobber (reg:CC FLAGS_REG))]
8937 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8939 (define_insn "*iorsi_1"
8940 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8941 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8942 (match_operand:SI 2 "general_operand" "ri,rmi")))
8943 (clobber (reg:CC FLAGS_REG))]
8944 "ix86_binary_operator_ok (IOR, SImode, operands)"
8945 "or{l}\t{%2, %0|%0, %2}"
8946 [(set_attr "type" "alu")
8947 (set_attr "mode" "SI")])
8949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8950 (define_insn "*iorsi_1_zext"
8951 [(set (match_operand:DI 0 "register_operand" "=rm")
8953 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8954 (match_operand:SI 2 "general_operand" "rim"))))
8955 (clobber (reg:CC FLAGS_REG))]
8956 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8957 "or{l}\t{%2, %k0|%k0, %2}"
8958 [(set_attr "type" "alu")
8959 (set_attr "mode" "SI")])
8961 (define_insn "*iorsi_1_zext_imm"
8962 [(set (match_operand:DI 0 "register_operand" "=rm")
8963 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8964 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8965 (clobber (reg:CC FLAGS_REG))]
8967 "or{l}\t{%2, %k0|%k0, %2}"
8968 [(set_attr "type" "alu")
8969 (set_attr "mode" "SI")])
8971 (define_insn "*iorsi_2"
8972 [(set (reg FLAGS_REG)
8973 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8974 (match_operand:SI 2 "general_operand" "rim,ri"))
8976 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8977 (ior:SI (match_dup 1) (match_dup 2)))]
8978 "ix86_match_ccmode (insn, CCNOmode)
8979 && ix86_binary_operator_ok (IOR, SImode, operands)"
8980 "or{l}\t{%2, %0|%0, %2}"
8981 [(set_attr "type" "alu")
8982 (set_attr "mode" "SI")])
8984 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8985 ;; ??? Special case for immediate operand is missing - it is tricky.
8986 (define_insn "*iorsi_2_zext"
8987 [(set (reg FLAGS_REG)
8988 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8989 (match_operand:SI 2 "general_operand" "rim"))
8991 (set (match_operand:DI 0 "register_operand" "=r")
8992 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8993 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8994 && ix86_binary_operator_ok (IOR, SImode, operands)"
8995 "or{l}\t{%2, %k0|%k0, %2}"
8996 [(set_attr "type" "alu")
8997 (set_attr "mode" "SI")])
8999 (define_insn "*iorsi_2_zext_imm"
9000 [(set (reg FLAGS_REG)
9001 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9002 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9004 (set (match_operand:DI 0 "register_operand" "=r")
9005 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9006 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9007 && ix86_binary_operator_ok (IOR, SImode, operands)"
9008 "or{l}\t{%2, %k0|%k0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "SI")])
9012 (define_insn "*iorsi_3"
9013 [(set (reg FLAGS_REG)
9014 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9015 (match_operand:SI 2 "general_operand" "rim"))
9017 (clobber (match_scratch:SI 0 "=r"))]
9018 "ix86_match_ccmode (insn, CCNOmode)
9019 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9020 "or{l}\t{%2, %0|%0, %2}"
9021 [(set_attr "type" "alu")
9022 (set_attr "mode" "SI")])
9024 (define_expand "iorhi3"
9025 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9026 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9027 (match_operand:HI 2 "general_operand" "")))
9028 (clobber (reg:CC FLAGS_REG))]
9029 "TARGET_HIMODE_MATH"
9030 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9032 (define_insn "*iorhi_1"
9033 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9034 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9035 (match_operand:HI 2 "general_operand" "rmi,ri")))
9036 (clobber (reg:CC FLAGS_REG))]
9037 "ix86_binary_operator_ok (IOR, HImode, operands)"
9038 "or{w}\t{%2, %0|%0, %2}"
9039 [(set_attr "type" "alu")
9040 (set_attr "mode" "HI")])
9042 (define_insn "*iorhi_2"
9043 [(set (reg FLAGS_REG)
9044 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9045 (match_operand:HI 2 "general_operand" "rim,ri"))
9047 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9048 (ior:HI (match_dup 1) (match_dup 2)))]
9049 "ix86_match_ccmode (insn, CCNOmode)
9050 && ix86_binary_operator_ok (IOR, HImode, operands)"
9051 "or{w}\t{%2, %0|%0, %2}"
9052 [(set_attr "type" "alu")
9053 (set_attr "mode" "HI")])
9055 (define_insn "*iorhi_3"
9056 [(set (reg FLAGS_REG)
9057 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9058 (match_operand:HI 2 "general_operand" "rim"))
9060 (clobber (match_scratch:HI 0 "=r"))]
9061 "ix86_match_ccmode (insn, CCNOmode)
9062 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9063 "or{w}\t{%2, %0|%0, %2}"
9064 [(set_attr "type" "alu")
9065 (set_attr "mode" "HI")])
9067 (define_expand "iorqi3"
9068 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9069 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9070 (match_operand:QI 2 "general_operand" "")))
9071 (clobber (reg:CC FLAGS_REG))]
9072 "TARGET_QIMODE_MATH"
9073 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9075 ;; %%% Potential partial reg stall on alternative 2. What to do?
9076 (define_insn "*iorqi_1"
9077 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9078 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9079 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9080 (clobber (reg:CC FLAGS_REG))]
9081 "ix86_binary_operator_ok (IOR, QImode, operands)"
9083 or{b}\t{%2, %0|%0, %2}
9084 or{b}\t{%2, %0|%0, %2}
9085 or{l}\t{%k2, %k0|%k0, %k2}"
9086 [(set_attr "type" "alu")
9087 (set_attr "mode" "QI,QI,SI")])
9089 (define_insn "*iorqi_1_slp"
9090 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9091 (ior:QI (match_dup 0)
9092 (match_operand:QI 1 "general_operand" "qmi,qi")))
9093 (clobber (reg:CC FLAGS_REG))]
9094 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9095 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9096 "or{b}\t{%1, %0|%0, %1}"
9097 [(set_attr "type" "alu1")
9098 (set_attr "mode" "QI")])
9100 (define_insn "*iorqi_2"
9101 [(set (reg FLAGS_REG)
9102 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9103 (match_operand:QI 2 "general_operand" "qim,qi"))
9105 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9106 (ior:QI (match_dup 1) (match_dup 2)))]
9107 "ix86_match_ccmode (insn, CCNOmode)
9108 && ix86_binary_operator_ok (IOR, QImode, operands)"
9109 "or{b}\t{%2, %0|%0, %2}"
9110 [(set_attr "type" "alu")
9111 (set_attr "mode" "QI")])
9113 (define_insn "*iorqi_2_slp"
9114 [(set (reg FLAGS_REG)
9115 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9116 (match_operand:QI 1 "general_operand" "qim,qi"))
9118 (set (strict_low_part (match_dup 0))
9119 (ior:QI (match_dup 0) (match_dup 1)))]
9120 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9121 && ix86_match_ccmode (insn, CCNOmode)
9122 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9123 "or{b}\t{%1, %0|%0, %1}"
9124 [(set_attr "type" "alu1")
9125 (set_attr "mode" "QI")])
9127 (define_insn "*iorqi_3"
9128 [(set (reg FLAGS_REG)
9129 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9130 (match_operand:QI 2 "general_operand" "qim"))
9132 (clobber (match_scratch:QI 0 "=q"))]
9133 "ix86_match_ccmode (insn, CCNOmode)
9134 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9135 "or{b}\t{%2, %0|%0, %2}"
9136 [(set_attr "type" "alu")
9137 (set_attr "mode" "QI")])
9139 (define_insn "iorqi_ext_0"
9140 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9145 (match_operand 1 "ext_register_operand" "0")
9148 (match_operand 2 "const_int_operand" "n")))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9151 "or{b}\t{%2, %h0|%h0, %2}"
9152 [(set_attr "type" "alu")
9153 (set_attr "length_immediate" "1")
9154 (set_attr "mode" "QI")])
9156 (define_insn "*iorqi_ext_1"
9157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9162 (match_operand 1 "ext_register_operand" "0")
9166 (match_operand:QI 2 "general_operand" "Qm"))))
9167 (clobber (reg:CC FLAGS_REG))]
9169 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170 "or{b}\t{%2, %h0|%h0, %2}"
9171 [(set_attr "type" "alu")
9172 (set_attr "length_immediate" "0")
9173 (set_attr "mode" "QI")])
9175 (define_insn "*iorqi_ext_1_rex64"
9176 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9181 (match_operand 1 "ext_register_operand" "0")
9185 (match_operand 2 "ext_register_operand" "Q"))))
9186 (clobber (reg:CC FLAGS_REG))]
9188 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9189 "or{b}\t{%2, %h0|%h0, %2}"
9190 [(set_attr "type" "alu")
9191 (set_attr "length_immediate" "0")
9192 (set_attr "mode" "QI")])
9194 (define_insn "*iorqi_ext_2"
9195 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9199 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9202 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9205 (clobber (reg:CC FLAGS_REG))]
9206 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207 "ior{b}\t{%h2, %h0|%h0, %h2}"
9208 [(set_attr "type" "alu")
9209 (set_attr "length_immediate" "0")
9210 (set_attr "mode" "QI")])
9213 [(set (match_operand 0 "register_operand" "")
9214 (ior (match_operand 1 "register_operand" "")
9215 (match_operand 2 "const_int_operand" "")))
9216 (clobber (reg:CC FLAGS_REG))]
9218 && QI_REG_P (operands[0])
9219 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9220 && !(INTVAL (operands[2]) & ~(255 << 8))
9221 && GET_MODE (operands[0]) != QImode"
9222 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9223 (ior:SI (zero_extract:SI (match_dup 1)
9224 (const_int 8) (const_int 8))
9226 (clobber (reg:CC FLAGS_REG))])]
9227 "operands[0] = gen_lowpart (SImode, operands[0]);
9228 operands[1] = gen_lowpart (SImode, operands[1]);
9229 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9231 ;; Since OR can be encoded with sign extended immediate, this is only
9232 ;; profitable when 7th bit is set.
9234 [(set (match_operand 0 "register_operand" "")
9235 (ior (match_operand 1 "general_operand" "")
9236 (match_operand 2 "const_int_operand" "")))
9237 (clobber (reg:CC FLAGS_REG))]
9239 && ANY_QI_REG_P (operands[0])
9240 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9241 && !(INTVAL (operands[2]) & ~255)
9242 && (INTVAL (operands[2]) & 128)
9243 && GET_MODE (operands[0]) != QImode"
9244 [(parallel [(set (strict_low_part (match_dup 0))
9245 (ior:QI (match_dup 1)
9247 (clobber (reg:CC FLAGS_REG))])]
9248 "operands[0] = gen_lowpart (QImode, operands[0]);
9249 operands[1] = gen_lowpart (QImode, operands[1]);
9250 operands[2] = gen_lowpart (QImode, operands[2]);")
9252 ;; Logical XOR instructions
9254 ;; %%% This used to optimize known byte-wide and operations to memory.
9255 ;; If this is considered useful, it should be done with splitters.
9257 (define_expand "xordi3"
9258 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9259 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9260 (match_operand:DI 2 "x86_64_general_operand" "")))
9261 (clobber (reg:CC FLAGS_REG))]
9263 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9265 (define_insn "*xordi_1_rex64"
9266 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9267 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9268 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9269 (clobber (reg:CC FLAGS_REG))]
9271 && ix86_binary_operator_ok (XOR, DImode, operands)"
9273 xor{q}\t{%2, %0|%0, %2}
9274 xor{q}\t{%2, %0|%0, %2}"
9275 [(set_attr "type" "alu")
9276 (set_attr "mode" "DI,DI")])
9278 (define_insn "*xordi_2_rex64"
9279 [(set (reg FLAGS_REG)
9280 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9281 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9283 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9284 (xor:DI (match_dup 1) (match_dup 2)))]
9286 && ix86_match_ccmode (insn, CCNOmode)
9287 && ix86_binary_operator_ok (XOR, DImode, operands)"
9289 xor{q}\t{%2, %0|%0, %2}
9290 xor{q}\t{%2, %0|%0, %2}"
9291 [(set_attr "type" "alu")
9292 (set_attr "mode" "DI,DI")])
9294 (define_insn "*xordi_3_rex64"
9295 [(set (reg FLAGS_REG)
9296 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9297 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9299 (clobber (match_scratch:DI 0 "=r"))]
9301 && ix86_match_ccmode (insn, CCNOmode)
9302 && ix86_binary_operator_ok (XOR, DImode, operands)"
9303 "xor{q}\t{%2, %0|%0, %2}"
9304 [(set_attr "type" "alu")
9305 (set_attr "mode" "DI")])
9307 (define_expand "xorsi3"
9308 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9309 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9310 (match_operand:SI 2 "general_operand" "")))
9311 (clobber (reg:CC FLAGS_REG))]
9313 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9315 (define_insn "*xorsi_1"
9316 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9317 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9318 (match_operand:SI 2 "general_operand" "ri,rm")))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "ix86_binary_operator_ok (XOR, SImode, operands)"
9321 "xor{l}\t{%2, %0|%0, %2}"
9322 [(set_attr "type" "alu")
9323 (set_attr "mode" "SI")])
9325 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9326 ;; Add speccase for immediates
9327 (define_insn "*xorsi_1_zext"
9328 [(set (match_operand:DI 0 "register_operand" "=r")
9330 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9331 (match_operand:SI 2 "general_operand" "rim"))))
9332 (clobber (reg:CC FLAGS_REG))]
9333 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9334 "xor{l}\t{%2, %k0|%k0, %2}"
9335 [(set_attr "type" "alu")
9336 (set_attr "mode" "SI")])
9338 (define_insn "*xorsi_1_zext_imm"
9339 [(set (match_operand:DI 0 "register_operand" "=r")
9340 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9341 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9342 (clobber (reg:CC FLAGS_REG))]
9343 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9344 "xor{l}\t{%2, %k0|%k0, %2}"
9345 [(set_attr "type" "alu")
9346 (set_attr "mode" "SI")])
9348 (define_insn "*xorsi_2"
9349 [(set (reg FLAGS_REG)
9350 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9351 (match_operand:SI 2 "general_operand" "rim,ri"))
9353 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9354 (xor:SI (match_dup 1) (match_dup 2)))]
9355 "ix86_match_ccmode (insn, CCNOmode)
9356 && ix86_binary_operator_ok (XOR, SImode, operands)"
9357 "xor{l}\t{%2, %0|%0, %2}"
9358 [(set_attr "type" "alu")
9359 (set_attr "mode" "SI")])
9361 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9362 ;; ??? Special case for immediate operand is missing - it is tricky.
9363 (define_insn "*xorsi_2_zext"
9364 [(set (reg FLAGS_REG)
9365 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9366 (match_operand:SI 2 "general_operand" "rim"))
9368 (set (match_operand:DI 0 "register_operand" "=r")
9369 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9370 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9371 && ix86_binary_operator_ok (XOR, SImode, operands)"
9372 "xor{l}\t{%2, %k0|%k0, %2}"
9373 [(set_attr "type" "alu")
9374 (set_attr "mode" "SI")])
9376 (define_insn "*xorsi_2_zext_imm"
9377 [(set (reg FLAGS_REG)
9378 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9379 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9381 (set (match_operand:DI 0 "register_operand" "=r")
9382 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9383 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9384 && ix86_binary_operator_ok (XOR, SImode, operands)"
9385 "xor{l}\t{%2, %k0|%k0, %2}"
9386 [(set_attr "type" "alu")
9387 (set_attr "mode" "SI")])
9389 (define_insn "*xorsi_3"
9390 [(set (reg FLAGS_REG)
9391 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9392 (match_operand:SI 2 "general_operand" "rim"))
9394 (clobber (match_scratch:SI 0 "=r"))]
9395 "ix86_match_ccmode (insn, CCNOmode)
9396 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9397 "xor{l}\t{%2, %0|%0, %2}"
9398 [(set_attr "type" "alu")
9399 (set_attr "mode" "SI")])
9401 (define_expand "xorhi3"
9402 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9403 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9404 (match_operand:HI 2 "general_operand" "")))
9405 (clobber (reg:CC FLAGS_REG))]
9406 "TARGET_HIMODE_MATH"
9407 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9409 (define_insn "*xorhi_1"
9410 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9411 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9412 (match_operand:HI 2 "general_operand" "rmi,ri")))
9413 (clobber (reg:CC FLAGS_REG))]
9414 "ix86_binary_operator_ok (XOR, HImode, operands)"
9415 "xor{w}\t{%2, %0|%0, %2}"
9416 [(set_attr "type" "alu")
9417 (set_attr "mode" "HI")])
9419 (define_insn "*xorhi_2"
9420 [(set (reg FLAGS_REG)
9421 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9422 (match_operand:HI 2 "general_operand" "rim,ri"))
9424 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9425 (xor:HI (match_dup 1) (match_dup 2)))]
9426 "ix86_match_ccmode (insn, CCNOmode)
9427 && ix86_binary_operator_ok (XOR, HImode, operands)"
9428 "xor{w}\t{%2, %0|%0, %2}"
9429 [(set_attr "type" "alu")
9430 (set_attr "mode" "HI")])
9432 (define_insn "*xorhi_3"
9433 [(set (reg FLAGS_REG)
9434 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9435 (match_operand:HI 2 "general_operand" "rim"))
9437 (clobber (match_scratch:HI 0 "=r"))]
9438 "ix86_match_ccmode (insn, CCNOmode)
9439 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9440 "xor{w}\t{%2, %0|%0, %2}"
9441 [(set_attr "type" "alu")
9442 (set_attr "mode" "HI")])
9444 (define_expand "xorqi3"
9445 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9446 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9447 (match_operand:QI 2 "general_operand" "")))
9448 (clobber (reg:CC FLAGS_REG))]
9449 "TARGET_QIMODE_MATH"
9450 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9452 ;; %%% Potential partial reg stall on alternative 2. What to do?
9453 (define_insn "*xorqi_1"
9454 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9455 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9456 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "ix86_binary_operator_ok (XOR, QImode, operands)"
9460 xor{b}\t{%2, %0|%0, %2}
9461 xor{b}\t{%2, %0|%0, %2}
9462 xor{l}\t{%k2, %k0|%k0, %k2}"
9463 [(set_attr "type" "alu")
9464 (set_attr "mode" "QI,QI,SI")])
9466 (define_insn "*xorqi_1_slp"
9467 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9468 (xor:QI (match_dup 0)
9469 (match_operand:QI 1 "general_operand" "qi,qmi")))
9470 (clobber (reg:CC FLAGS_REG))]
9471 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9472 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9473 "xor{b}\t{%1, %0|%0, %1}"
9474 [(set_attr "type" "alu1")
9475 (set_attr "mode" "QI")])
9477 (define_insn "xorqi_ext_0"
9478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9483 (match_operand 1 "ext_register_operand" "0")
9486 (match_operand 2 "const_int_operand" "n")))
9487 (clobber (reg:CC FLAGS_REG))]
9488 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9489 "xor{b}\t{%2, %h0|%h0, %2}"
9490 [(set_attr "type" "alu")
9491 (set_attr "length_immediate" "1")
9492 (set_attr "mode" "QI")])
9494 (define_insn "*xorqi_ext_1"
9495 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9500 (match_operand 1 "ext_register_operand" "0")
9504 (match_operand:QI 2 "general_operand" "Qm"))))
9505 (clobber (reg:CC FLAGS_REG))]
9507 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9508 "xor{b}\t{%2, %h0|%h0, %2}"
9509 [(set_attr "type" "alu")
9510 (set_attr "length_immediate" "0")
9511 (set_attr "mode" "QI")])
9513 (define_insn "*xorqi_ext_1_rex64"
9514 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9519 (match_operand 1 "ext_register_operand" "0")
9523 (match_operand 2 "ext_register_operand" "Q"))))
9524 (clobber (reg:CC FLAGS_REG))]
9526 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9527 "xor{b}\t{%2, %h0|%h0, %2}"
9528 [(set_attr "type" "alu")
9529 (set_attr "length_immediate" "0")
9530 (set_attr "mode" "QI")])
9532 (define_insn "*xorqi_ext_2"
9533 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9537 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9540 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9543 (clobber (reg:CC FLAGS_REG))]
9544 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9545 "xor{b}\t{%h2, %h0|%h0, %h2}"
9546 [(set_attr "type" "alu")
9547 (set_attr "length_immediate" "0")
9548 (set_attr "mode" "QI")])
9550 (define_insn "*xorqi_cc_1"
9551 [(set (reg FLAGS_REG)
9553 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9554 (match_operand:QI 2 "general_operand" "qim,qi"))
9556 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9557 (xor:QI (match_dup 1) (match_dup 2)))]
9558 "ix86_match_ccmode (insn, CCNOmode)
9559 && ix86_binary_operator_ok (XOR, QImode, operands)"
9560 "xor{b}\t{%2, %0|%0, %2}"
9561 [(set_attr "type" "alu")
9562 (set_attr "mode" "QI")])
9564 (define_insn "*xorqi_2_slp"
9565 [(set (reg FLAGS_REG)
9566 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9567 (match_operand:QI 1 "general_operand" "qim,qi"))
9569 (set (strict_low_part (match_dup 0))
9570 (xor:QI (match_dup 0) (match_dup 1)))]
9571 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9572 && ix86_match_ccmode (insn, CCNOmode)
9573 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9574 "xor{b}\t{%1, %0|%0, %1}"
9575 [(set_attr "type" "alu1")
9576 (set_attr "mode" "QI")])
9578 (define_insn "*xorqi_cc_2"
9579 [(set (reg FLAGS_REG)
9581 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9582 (match_operand:QI 2 "general_operand" "qim"))
9584 (clobber (match_scratch:QI 0 "=q"))]
9585 "ix86_match_ccmode (insn, CCNOmode)
9586 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9587 "xor{b}\t{%2, %0|%0, %2}"
9588 [(set_attr "type" "alu")
9589 (set_attr "mode" "QI")])
9591 (define_insn "*xorqi_cc_ext_1"
9592 [(set (reg FLAGS_REG)
9596 (match_operand 1 "ext_register_operand" "0")
9599 (match_operand:QI 2 "general_operand" "qmn"))
9601 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9605 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9607 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9608 "xor{b}\t{%2, %h0|%h0, %2}"
9609 [(set_attr "type" "alu")
9610 (set_attr "mode" "QI")])
9612 (define_insn "*xorqi_cc_ext_1_rex64"
9613 [(set (reg FLAGS_REG)
9617 (match_operand 1 "ext_register_operand" "0")
9620 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9622 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9626 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9628 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9629 "xor{b}\t{%2, %h0|%h0, %2}"
9630 [(set_attr "type" "alu")
9631 (set_attr "mode" "QI")])
9633 (define_expand "xorqi_cc_ext_1"
9635 (set (reg:CCNO FLAGS_REG)
9639 (match_operand 1 "ext_register_operand" "")
9642 (match_operand:QI 2 "general_operand" ""))
9644 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9648 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9654 [(set (match_operand 0 "register_operand" "")
9655 (xor (match_operand 1 "register_operand" "")
9656 (match_operand 2 "const_int_operand" "")))
9657 (clobber (reg:CC FLAGS_REG))]
9659 && QI_REG_P (operands[0])
9660 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9661 && !(INTVAL (operands[2]) & ~(255 << 8))
9662 && GET_MODE (operands[0]) != QImode"
9663 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9664 (xor:SI (zero_extract:SI (match_dup 1)
9665 (const_int 8) (const_int 8))
9667 (clobber (reg:CC FLAGS_REG))])]
9668 "operands[0] = gen_lowpart (SImode, operands[0]);
9669 operands[1] = gen_lowpart (SImode, operands[1]);
9670 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9672 ;; Since XOR can be encoded with sign extended immediate, this is only
9673 ;; profitable when 7th bit is set.
9675 [(set (match_operand 0 "register_operand" "")
9676 (xor (match_operand 1 "general_operand" "")
9677 (match_operand 2 "const_int_operand" "")))
9678 (clobber (reg:CC FLAGS_REG))]
9680 && ANY_QI_REG_P (operands[0])
9681 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9682 && !(INTVAL (operands[2]) & ~255)
9683 && (INTVAL (operands[2]) & 128)
9684 && GET_MODE (operands[0]) != QImode"
9685 [(parallel [(set (strict_low_part (match_dup 0))
9686 (xor:QI (match_dup 1)
9688 (clobber (reg:CC FLAGS_REG))])]
9689 "operands[0] = gen_lowpart (QImode, operands[0]);
9690 operands[1] = gen_lowpart (QImode, operands[1]);
9691 operands[2] = gen_lowpart (QImode, operands[2]);")
9693 ;; Negation instructions
9695 (define_expand "negti2"
9696 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9697 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9698 (clobber (reg:CC FLAGS_REG))])]
9700 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9702 (define_insn "*negti2_1"
9703 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9704 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9705 (clobber (reg:CC FLAGS_REG))]
9707 && ix86_unary_operator_ok (NEG, TImode, operands)"
9711 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9712 (neg:TI (match_operand:TI 1 "general_operand" "")))
9713 (clobber (reg:CC FLAGS_REG))]
9714 "TARGET_64BIT && reload_completed"
9716 [(set (reg:CCZ FLAGS_REG)
9717 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9718 (set (match_dup 0) (neg:DI (match_dup 2)))])
9721 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9724 (clobber (reg:CC FLAGS_REG))])
9727 (neg:DI (match_dup 1)))
9728 (clobber (reg:CC FLAGS_REG))])]
9729 "split_ti (operands+1, 1, operands+2, operands+3);
9730 split_ti (operands+0, 1, operands+0, operands+1);")
9732 (define_expand "negdi2"
9733 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9734 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9735 (clobber (reg:CC FLAGS_REG))])]
9737 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9739 (define_insn "*negdi2_1"
9740 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9741 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9742 (clobber (reg:CC FLAGS_REG))]
9744 && ix86_unary_operator_ok (NEG, DImode, operands)"
9748 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9749 (neg:DI (match_operand:DI 1 "general_operand" "")))
9750 (clobber (reg:CC FLAGS_REG))]
9751 "!TARGET_64BIT && reload_completed"
9753 [(set (reg:CCZ FLAGS_REG)
9754 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9755 (set (match_dup 0) (neg:SI (match_dup 2)))])
9758 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9761 (clobber (reg:CC FLAGS_REG))])
9764 (neg:SI (match_dup 1)))
9765 (clobber (reg:CC FLAGS_REG))])]
9766 "split_di (operands+1, 1, operands+2, operands+3);
9767 split_di (operands+0, 1, operands+0, operands+1);")
9769 (define_insn "*negdi2_1_rex64"
9770 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9771 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9772 (clobber (reg:CC FLAGS_REG))]
9773 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9775 [(set_attr "type" "negnot")
9776 (set_attr "mode" "DI")])
9778 ;; The problem with neg is that it does not perform (compare x 0),
9779 ;; it really performs (compare 0 x), which leaves us with the zero
9780 ;; flag being the only useful item.
9782 (define_insn "*negdi2_cmpz_rex64"
9783 [(set (reg:CCZ FLAGS_REG)
9784 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9786 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9787 (neg:DI (match_dup 1)))]
9788 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9790 [(set_attr "type" "negnot")
9791 (set_attr "mode" "DI")])
9794 (define_expand "negsi2"
9795 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9796 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9797 (clobber (reg:CC FLAGS_REG))])]
9799 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9801 (define_insn "*negsi2_1"
9802 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9803 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9804 (clobber (reg:CC FLAGS_REG))]
9805 "ix86_unary_operator_ok (NEG, SImode, operands)"
9807 [(set_attr "type" "negnot")
9808 (set_attr "mode" "SI")])
9810 ;; Combine is quite creative about this pattern.
9811 (define_insn "*negsi2_1_zext"
9812 [(set (match_operand:DI 0 "register_operand" "=r")
9813 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9816 (clobber (reg:CC FLAGS_REG))]
9817 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9819 [(set_attr "type" "negnot")
9820 (set_attr "mode" "SI")])
9822 ;; The problem with neg is that it does not perform (compare x 0),
9823 ;; it really performs (compare 0 x), which leaves us with the zero
9824 ;; flag being the only useful item.
9826 (define_insn "*negsi2_cmpz"
9827 [(set (reg:CCZ FLAGS_REG)
9828 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9830 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9831 (neg:SI (match_dup 1)))]
9832 "ix86_unary_operator_ok (NEG, SImode, operands)"
9834 [(set_attr "type" "negnot")
9835 (set_attr "mode" "SI")])
9837 (define_insn "*negsi2_cmpz_zext"
9838 [(set (reg:CCZ FLAGS_REG)
9839 (compare:CCZ (lshiftrt:DI
9841 (match_operand:DI 1 "register_operand" "0")
9845 (set (match_operand:DI 0 "register_operand" "=r")
9846 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9849 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9851 [(set_attr "type" "negnot")
9852 (set_attr "mode" "SI")])
9854 (define_expand "neghi2"
9855 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9856 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9857 (clobber (reg:CC FLAGS_REG))])]
9858 "TARGET_HIMODE_MATH"
9859 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9861 (define_insn "*neghi2_1"
9862 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9863 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9864 (clobber (reg:CC FLAGS_REG))]
9865 "ix86_unary_operator_ok (NEG, HImode, operands)"
9867 [(set_attr "type" "negnot")
9868 (set_attr "mode" "HI")])
9870 (define_insn "*neghi2_cmpz"
9871 [(set (reg:CCZ FLAGS_REG)
9872 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9874 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9875 (neg:HI (match_dup 1)))]
9876 "ix86_unary_operator_ok (NEG, HImode, operands)"
9878 [(set_attr "type" "negnot")
9879 (set_attr "mode" "HI")])
9881 (define_expand "negqi2"
9882 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9883 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9884 (clobber (reg:CC FLAGS_REG))])]
9885 "TARGET_QIMODE_MATH"
9886 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9888 (define_insn "*negqi2_1"
9889 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9890 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9891 (clobber (reg:CC FLAGS_REG))]
9892 "ix86_unary_operator_ok (NEG, QImode, operands)"
9894 [(set_attr "type" "negnot")
9895 (set_attr "mode" "QI")])
9897 (define_insn "*negqi2_cmpz"
9898 [(set (reg:CCZ FLAGS_REG)
9899 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9901 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9902 (neg:QI (match_dup 1)))]
9903 "ix86_unary_operator_ok (NEG, QImode, operands)"
9905 [(set_attr "type" "negnot")
9906 (set_attr "mode" "QI")])
9908 ;; Changing of sign for FP values is doable using integer unit too.
9910 (define_expand "negsf2"
9911 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9912 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9913 "TARGET_80387 || TARGET_SSE_MATH"
9914 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9916 (define_expand "abssf2"
9917 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9918 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9919 "TARGET_80387 || TARGET_SSE_MATH"
9920 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9922 (define_insn "*absnegsf2_mixed"
9923 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9924 (match_operator:SF 3 "absneg_operator"
9925 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9926 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9927 (clobber (reg:CC FLAGS_REG))]
9928 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9929 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9932 (define_insn "*absnegsf2_sse"
9933 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9934 (match_operator:SF 3 "absneg_operator"
9935 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9936 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9937 (clobber (reg:CC FLAGS_REG))]
9939 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9942 (define_insn "*absnegsf2_i387"
9943 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9944 (match_operator:SF 3 "absneg_operator"
9945 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9946 (use (match_operand 2 "" ""))
9947 (clobber (reg:CC FLAGS_REG))]
9948 "TARGET_80387 && !TARGET_SSE_MATH
9949 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9952 (define_expand "copysignsf3"
9953 [(match_operand:SF 0 "register_operand" "")
9954 (match_operand:SF 1 "nonmemory_operand" "")
9955 (match_operand:SF 2 "register_operand" "")]
9958 ix86_expand_copysign (operands);
9962 (define_insn_and_split "copysignsf3_const"
9963 [(set (match_operand:SF 0 "register_operand" "=x")
9965 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9966 (match_operand:SF 2 "register_operand" "0")
9967 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9971 "&& reload_completed"
9974 ix86_split_copysign_const (operands);
9978 (define_insn "copysignsf3_var"
9979 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9981 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9982 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9983 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9984 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9986 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9991 [(set (match_operand:SF 0 "register_operand" "")
9993 [(match_operand:SF 2 "register_operand" "")
9994 (match_operand:SF 3 "register_operand" "")
9995 (match_operand:V4SF 4 "" "")
9996 (match_operand:V4SF 5 "" "")]
9998 (clobber (match_scratch:V4SF 1 ""))]
9999 "TARGET_SSE_MATH && reload_completed"
10002 ix86_split_copysign_var (operands);
10006 (define_expand "negdf2"
10007 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10008 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10009 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10010 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10012 (define_expand "absdf2"
10013 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10014 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10015 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10016 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10018 (define_insn "*absnegdf2_mixed"
10019 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
10020 (match_operator:DF 3 "absneg_operator"
10021 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10022 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
10023 (clobber (reg:CC FLAGS_REG))]
10024 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10025 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10028 (define_insn "*absnegdf2_sse"
10029 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10030 (match_operator:DF 3 "absneg_operator"
10031 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10032 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10033 (clobber (reg:CC FLAGS_REG))]
10034 "TARGET_SSE2 && TARGET_SSE_MATH
10035 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10038 (define_insn "*absnegdf2_i387"
10039 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10040 (match_operator:DF 3 "absneg_operator"
10041 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10042 (use (match_operand 2 "" ""))
10043 (clobber (reg:CC FLAGS_REG))]
10044 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10045 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10048 (define_expand "copysigndf3"
10049 [(match_operand:DF 0 "register_operand" "")
10050 (match_operand:DF 1 "nonmemory_operand" "")
10051 (match_operand:DF 2 "register_operand" "")]
10052 "TARGET_SSE2 && TARGET_SSE_MATH"
10054 ix86_expand_copysign (operands);
10058 (define_insn_and_split "copysigndf3_const"
10059 [(set (match_operand:DF 0 "register_operand" "=x")
10061 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
10062 (match_operand:DF 2 "register_operand" "0")
10063 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10065 "TARGET_SSE2 && TARGET_SSE_MATH"
10067 "&& reload_completed"
10070 ix86_split_copysign_const (operands);
10074 (define_insn "copysigndf3_var"
10075 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
10077 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
10078 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
10079 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10080 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10082 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
10083 "TARGET_SSE2 && TARGET_SSE_MATH"
10087 [(set (match_operand:DF 0 "register_operand" "")
10089 [(match_operand:DF 2 "register_operand" "")
10090 (match_operand:DF 3 "register_operand" "")
10091 (match_operand:V2DF 4 "" "")
10092 (match_operand:V2DF 5 "" "")]
10094 (clobber (match_scratch:V2DF 1 ""))]
10095 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10098 ix86_split_copysign_var (operands);
10102 (define_expand "negxf2"
10103 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10104 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10106 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10108 (define_expand "absxf2"
10109 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10110 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10112 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10114 (define_insn "*absnegxf2_i387"
10115 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10116 (match_operator:XF 3 "absneg_operator"
10117 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10118 (use (match_operand 2 "" ""))
10119 (clobber (reg:CC FLAGS_REG))]
10121 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10124 ;; Splitters for fp abs and neg.
10127 [(set (match_operand 0 "fp_register_operand" "")
10128 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10129 (use (match_operand 2 "" ""))
10130 (clobber (reg:CC FLAGS_REG))]
10132 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10135 [(set (match_operand 0 "register_operand" "")
10136 (match_operator 3 "absneg_operator"
10137 [(match_operand 1 "register_operand" "")]))
10138 (use (match_operand 2 "nonimmediate_operand" ""))
10139 (clobber (reg:CC FLAGS_REG))]
10140 "reload_completed && SSE_REG_P (operands[0])"
10141 [(set (match_dup 0) (match_dup 3))]
10143 enum machine_mode mode = GET_MODE (operands[0]);
10144 enum machine_mode vmode = GET_MODE (operands[2]);
10147 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10148 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10149 if (operands_match_p (operands[0], operands[2]))
10152 operands[1] = operands[2];
10155 if (GET_CODE (operands[3]) == ABS)
10156 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10158 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10163 [(set (match_operand:SF 0 "register_operand" "")
10164 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10165 (use (match_operand:V4SF 2 "" ""))
10166 (clobber (reg:CC FLAGS_REG))]
10168 [(parallel [(set (match_dup 0) (match_dup 1))
10169 (clobber (reg:CC FLAGS_REG))])]
10172 operands[0] = gen_lowpart (SImode, operands[0]);
10173 if (GET_CODE (operands[1]) == ABS)
10175 tmp = gen_int_mode (0x7fffffff, SImode);
10176 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10180 tmp = gen_int_mode (0x80000000, SImode);
10181 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10187 [(set (match_operand:DF 0 "register_operand" "")
10188 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10189 (use (match_operand 2 "" ""))
10190 (clobber (reg:CC FLAGS_REG))]
10192 [(parallel [(set (match_dup 0) (match_dup 1))
10193 (clobber (reg:CC FLAGS_REG))])]
10198 tmp = gen_lowpart (DImode, operands[0]);
10199 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10202 if (GET_CODE (operands[1]) == ABS)
10205 tmp = gen_rtx_NOT (DImode, tmp);
10209 operands[0] = gen_highpart (SImode, operands[0]);
10210 if (GET_CODE (operands[1]) == ABS)
10212 tmp = gen_int_mode (0x7fffffff, SImode);
10213 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10217 tmp = gen_int_mode (0x80000000, SImode);
10218 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10225 [(set (match_operand:XF 0 "register_operand" "")
10226 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10227 (use (match_operand 2 "" ""))
10228 (clobber (reg:CC FLAGS_REG))]
10230 [(parallel [(set (match_dup 0) (match_dup 1))
10231 (clobber (reg:CC FLAGS_REG))])]
10234 operands[0] = gen_rtx_REG (SImode,
10235 true_regnum (operands[0])
10236 + (TARGET_64BIT ? 1 : 2));
10237 if (GET_CODE (operands[1]) == ABS)
10239 tmp = GEN_INT (0x7fff);
10240 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10244 tmp = GEN_INT (0x8000);
10245 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10251 [(set (match_operand 0 "memory_operand" "")
10252 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10253 (use (match_operand 2 "" ""))
10254 (clobber (reg:CC FLAGS_REG))]
10256 [(parallel [(set (match_dup 0) (match_dup 1))
10257 (clobber (reg:CC FLAGS_REG))])]
10259 enum machine_mode mode = GET_MODE (operands[0]);
10260 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10263 operands[0] = adjust_address (operands[0], QImode, size - 1);
10264 if (GET_CODE (operands[1]) == ABS)
10266 tmp = gen_int_mode (0x7f, QImode);
10267 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10271 tmp = gen_int_mode (0x80, QImode);
10272 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10277 ;; Conditionalize these after reload. If they match before reload, we
10278 ;; lose the clobber and ability to use integer instructions.
10280 (define_insn "*negsf2_1"
10281 [(set (match_operand:SF 0 "register_operand" "=f")
10282 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10283 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10285 [(set_attr "type" "fsgn")
10286 (set_attr "mode" "SF")])
10288 (define_insn "*negdf2_1"
10289 [(set (match_operand:DF 0 "register_operand" "=f")
10290 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10291 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10293 [(set_attr "type" "fsgn")
10294 (set_attr "mode" "DF")])
10296 (define_insn "*negxf2_1"
10297 [(set (match_operand:XF 0 "register_operand" "=f")
10298 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10301 [(set_attr "type" "fsgn")
10302 (set_attr "mode" "XF")])
10304 (define_insn "*abssf2_1"
10305 [(set (match_operand:SF 0 "register_operand" "=f")
10306 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10307 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10309 [(set_attr "type" "fsgn")
10310 (set_attr "mode" "SF")])
10312 (define_insn "*absdf2_1"
10313 [(set (match_operand:DF 0 "register_operand" "=f")
10314 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10315 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10317 [(set_attr "type" "fsgn")
10318 (set_attr "mode" "DF")])
10320 (define_insn "*absxf2_1"
10321 [(set (match_operand:XF 0 "register_operand" "=f")
10322 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10325 [(set_attr "type" "fsgn")
10326 (set_attr "mode" "DF")])
10328 (define_insn "*negextendsfdf2"
10329 [(set (match_operand:DF 0 "register_operand" "=f")
10330 (neg:DF (float_extend:DF
10331 (match_operand:SF 1 "register_operand" "0"))))]
10332 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10334 [(set_attr "type" "fsgn")
10335 (set_attr "mode" "DF")])
10337 (define_insn "*negextenddfxf2"
10338 [(set (match_operand:XF 0 "register_operand" "=f")
10339 (neg:XF (float_extend:XF
10340 (match_operand:DF 1 "register_operand" "0"))))]
10343 [(set_attr "type" "fsgn")
10344 (set_attr "mode" "XF")])
10346 (define_insn "*negextendsfxf2"
10347 [(set (match_operand:XF 0 "register_operand" "=f")
10348 (neg:XF (float_extend:XF
10349 (match_operand:SF 1 "register_operand" "0"))))]
10352 [(set_attr "type" "fsgn")
10353 (set_attr "mode" "XF")])
10355 (define_insn "*absextendsfdf2"
10356 [(set (match_operand:DF 0 "register_operand" "=f")
10357 (abs:DF (float_extend:DF
10358 (match_operand:SF 1 "register_operand" "0"))))]
10359 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10361 [(set_attr "type" "fsgn")
10362 (set_attr "mode" "DF")])
10364 (define_insn "*absextenddfxf2"
10365 [(set (match_operand:XF 0 "register_operand" "=f")
10366 (abs:XF (float_extend:XF
10367 (match_operand:DF 1 "register_operand" "0"))))]
10370 [(set_attr "type" "fsgn")
10371 (set_attr "mode" "XF")])
10373 (define_insn "*absextendsfxf2"
10374 [(set (match_operand:XF 0 "register_operand" "=f")
10375 (abs:XF (float_extend:XF
10376 (match_operand:SF 1 "register_operand" "0"))))]
10379 [(set_attr "type" "fsgn")
10380 (set_attr "mode" "XF")])
10382 ;; One complement instructions
10384 (define_expand "one_cmpldi2"
10385 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10386 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10388 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10390 (define_insn "*one_cmpldi2_1_rex64"
10391 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10392 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10393 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10395 [(set_attr "type" "negnot")
10396 (set_attr "mode" "DI")])
10398 (define_insn "*one_cmpldi2_2_rex64"
10399 [(set (reg FLAGS_REG)
10400 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10402 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10403 (not:DI (match_dup 1)))]
10404 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10405 && ix86_unary_operator_ok (NOT, DImode, operands)"
10407 [(set_attr "type" "alu1")
10408 (set_attr "mode" "DI")])
10411 [(set (match_operand 0 "flags_reg_operand" "")
10412 (match_operator 2 "compare_operator"
10413 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10415 (set (match_operand:DI 1 "nonimmediate_operand" "")
10416 (not:DI (match_dup 3)))]
10417 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10418 [(parallel [(set (match_dup 0)
10420 [(xor:DI (match_dup 3) (const_int -1))
10423 (xor:DI (match_dup 3) (const_int -1)))])]
10426 (define_expand "one_cmplsi2"
10427 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10428 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10430 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10432 (define_insn "*one_cmplsi2_1"
10433 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10434 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10435 "ix86_unary_operator_ok (NOT, SImode, operands)"
10437 [(set_attr "type" "negnot")
10438 (set_attr "mode" "SI")])
10440 ;; ??? Currently never generated - xor is used instead.
10441 (define_insn "*one_cmplsi2_1_zext"
10442 [(set (match_operand:DI 0 "register_operand" "=r")
10443 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10444 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10446 [(set_attr "type" "negnot")
10447 (set_attr "mode" "SI")])
10449 (define_insn "*one_cmplsi2_2"
10450 [(set (reg FLAGS_REG)
10451 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10453 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10454 (not:SI (match_dup 1)))]
10455 "ix86_match_ccmode (insn, CCNOmode)
10456 && ix86_unary_operator_ok (NOT, SImode, operands)"
10458 [(set_attr "type" "alu1")
10459 (set_attr "mode" "SI")])
10462 [(set (match_operand 0 "flags_reg_operand" "")
10463 (match_operator 2 "compare_operator"
10464 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10466 (set (match_operand:SI 1 "nonimmediate_operand" "")
10467 (not:SI (match_dup 3)))]
10468 "ix86_match_ccmode (insn, CCNOmode)"
10469 [(parallel [(set (match_dup 0)
10470 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10473 (xor:SI (match_dup 3) (const_int -1)))])]
10476 ;; ??? Currently never generated - xor is used instead.
10477 (define_insn "*one_cmplsi2_2_zext"
10478 [(set (reg FLAGS_REG)
10479 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10481 (set (match_operand:DI 0 "register_operand" "=r")
10482 (zero_extend:DI (not:SI (match_dup 1))))]
10483 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10484 && ix86_unary_operator_ok (NOT, SImode, operands)"
10486 [(set_attr "type" "alu1")
10487 (set_attr "mode" "SI")])
10490 [(set (match_operand 0 "flags_reg_operand" "")
10491 (match_operator 2 "compare_operator"
10492 [(not:SI (match_operand:SI 3 "register_operand" ""))
10494 (set (match_operand:DI 1 "register_operand" "")
10495 (zero_extend:DI (not:SI (match_dup 3))))]
10496 "ix86_match_ccmode (insn, CCNOmode)"
10497 [(parallel [(set (match_dup 0)
10498 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10501 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10504 (define_expand "one_cmplhi2"
10505 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10506 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10507 "TARGET_HIMODE_MATH"
10508 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10510 (define_insn "*one_cmplhi2_1"
10511 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10512 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10513 "ix86_unary_operator_ok (NOT, HImode, operands)"
10515 [(set_attr "type" "negnot")
10516 (set_attr "mode" "HI")])
10518 (define_insn "*one_cmplhi2_2"
10519 [(set (reg FLAGS_REG)
10520 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10522 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10523 (not:HI (match_dup 1)))]
10524 "ix86_match_ccmode (insn, CCNOmode)
10525 && ix86_unary_operator_ok (NEG, HImode, operands)"
10527 [(set_attr "type" "alu1")
10528 (set_attr "mode" "HI")])
10531 [(set (match_operand 0 "flags_reg_operand" "")
10532 (match_operator 2 "compare_operator"
10533 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10535 (set (match_operand:HI 1 "nonimmediate_operand" "")
10536 (not:HI (match_dup 3)))]
10537 "ix86_match_ccmode (insn, CCNOmode)"
10538 [(parallel [(set (match_dup 0)
10539 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10542 (xor:HI (match_dup 3) (const_int -1)))])]
10545 ;; %%% Potential partial reg stall on alternative 1. What to do?
10546 (define_expand "one_cmplqi2"
10547 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10548 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10549 "TARGET_QIMODE_MATH"
10550 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10552 (define_insn "*one_cmplqi2_1"
10553 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10554 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10555 "ix86_unary_operator_ok (NOT, QImode, operands)"
10559 [(set_attr "type" "negnot")
10560 (set_attr "mode" "QI,SI")])
10562 (define_insn "*one_cmplqi2_2"
10563 [(set (reg FLAGS_REG)
10564 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10566 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10567 (not:QI (match_dup 1)))]
10568 "ix86_match_ccmode (insn, CCNOmode)
10569 && ix86_unary_operator_ok (NOT, QImode, operands)"
10571 [(set_attr "type" "alu1")
10572 (set_attr "mode" "QI")])
10575 [(set (match_operand 0 "flags_reg_operand" "")
10576 (match_operator 2 "compare_operator"
10577 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10579 (set (match_operand:QI 1 "nonimmediate_operand" "")
10580 (not:QI (match_dup 3)))]
10581 "ix86_match_ccmode (insn, CCNOmode)"
10582 [(parallel [(set (match_dup 0)
10583 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10586 (xor:QI (match_dup 3) (const_int -1)))])]
10589 ;; Arithmetic shift instructions
10591 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10592 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10593 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10594 ;; from the assembler input.
10596 ;; This instruction shifts the target reg/mem as usual, but instead of
10597 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10598 ;; is a left shift double, bits are taken from the high order bits of
10599 ;; reg, else if the insn is a shift right double, bits are taken from the
10600 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10601 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10603 ;; Since sh[lr]d does not change the `reg' operand, that is done
10604 ;; separately, making all shifts emit pairs of shift double and normal
10605 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10606 ;; support a 63 bit shift, each shift where the count is in a reg expands
10607 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10609 ;; If the shift count is a constant, we need never emit more than one
10610 ;; shift pair, instead using moves and sign extension for counts greater
10613 (define_expand "ashlti3"
10614 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10615 (ashift:TI (match_operand:TI 1 "register_operand" "")
10616 (match_operand:QI 2 "nonmemory_operand" "")))
10617 (clobber (reg:CC FLAGS_REG))])]
10620 if (! immediate_operand (operands[2], QImode))
10622 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10625 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10629 (define_insn "ashlti3_1"
10630 [(set (match_operand:TI 0 "register_operand" "=r")
10631 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10632 (match_operand:QI 2 "register_operand" "c")))
10633 (clobber (match_scratch:DI 3 "=&r"))
10634 (clobber (reg:CC FLAGS_REG))]
10637 [(set_attr "type" "multi")])
10639 (define_insn "*ashlti3_2"
10640 [(set (match_operand:TI 0 "register_operand" "=r")
10641 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10642 (match_operand:QI 2 "immediate_operand" "O")))
10643 (clobber (reg:CC FLAGS_REG))]
10646 [(set_attr "type" "multi")])
10649 [(set (match_operand:TI 0 "register_operand" "")
10650 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10651 (match_operand:QI 2 "register_operand" "")))
10652 (clobber (match_scratch:DI 3 ""))
10653 (clobber (reg:CC FLAGS_REG))]
10654 "TARGET_64BIT && reload_completed"
10656 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10659 [(set (match_operand:TI 0 "register_operand" "")
10660 (ashift:TI (match_operand:TI 1 "register_operand" "")
10661 (match_operand:QI 2 "immediate_operand" "")))
10662 (clobber (reg:CC FLAGS_REG))]
10663 "TARGET_64BIT && reload_completed"
10665 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10667 (define_insn "x86_64_shld"
10668 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10669 (ior:DI (ashift:DI (match_dup 0)
10670 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10671 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10672 (minus:QI (const_int 64) (match_dup 2)))))
10673 (clobber (reg:CC FLAGS_REG))]
10676 shld{q}\t{%2, %1, %0|%0, %1, %2}
10677 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10678 [(set_attr "type" "ishift")
10679 (set_attr "prefix_0f" "1")
10680 (set_attr "mode" "DI")
10681 (set_attr "athlon_decode" "vector")
10682 (set_attr "amdfam10_decode" "vector")])
10684 (define_expand "x86_64_shift_adj"
10685 [(set (reg:CCZ FLAGS_REG)
10686 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10689 (set (match_operand:DI 0 "register_operand" "")
10690 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10691 (match_operand:DI 1 "register_operand" "")
10694 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10695 (match_operand:DI 3 "register_operand" "r")
10700 (define_expand "ashldi3"
10701 [(set (match_operand:DI 0 "shiftdi_operand" "")
10702 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10703 (match_operand:QI 2 "nonmemory_operand" "")))]
10705 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10707 (define_insn "*ashldi3_1_rex64"
10708 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10709 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10710 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10711 (clobber (reg:CC FLAGS_REG))]
10712 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10714 switch (get_attr_type (insn))
10717 gcc_assert (operands[2] == const1_rtx);
10718 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10719 return "add{q}\t%0, %0";
10722 gcc_assert (CONST_INT_P (operands[2]));
10723 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10724 operands[1] = gen_rtx_MULT (DImode, operands[1],
10725 GEN_INT (1 << INTVAL (operands[2])));
10726 return "lea{q}\t{%a1, %0|%0, %a1}";
10729 if (REG_P (operands[2]))
10730 return "sal{q}\t{%b2, %0|%0, %b2}";
10731 else if (operands[2] == const1_rtx
10732 && (TARGET_SHIFT1 || optimize_size))
10733 return "sal{q}\t%0";
10735 return "sal{q}\t{%2, %0|%0, %2}";
10738 [(set (attr "type")
10739 (cond [(eq_attr "alternative" "1")
10740 (const_string "lea")
10741 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10743 (match_operand 0 "register_operand" ""))
10744 (match_operand 2 "const1_operand" ""))
10745 (const_string "alu")
10747 (const_string "ishift")))
10748 (set_attr "mode" "DI")])
10750 ;; Convert lea to the lea pattern to avoid flags dependency.
10752 [(set (match_operand:DI 0 "register_operand" "")
10753 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10754 (match_operand:QI 2 "immediate_operand" "")))
10755 (clobber (reg:CC FLAGS_REG))]
10756 "TARGET_64BIT && reload_completed
10757 && true_regnum (operands[0]) != true_regnum (operands[1])"
10758 [(set (match_dup 0)
10759 (mult:DI (match_dup 1)
10761 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10763 ;; This pattern can't accept a variable shift count, since shifts by
10764 ;; zero don't affect the flags. We assume that shifts by constant
10765 ;; zero are optimized away.
10766 (define_insn "*ashldi3_cmp_rex64"
10767 [(set (reg FLAGS_REG)
10769 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10770 (match_operand:QI 2 "immediate_operand" "e"))
10772 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10773 (ashift:DI (match_dup 1) (match_dup 2)))]
10774 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10775 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10777 || !TARGET_PARTIAL_FLAG_REG_STALL
10778 || (operands[2] == const1_rtx
10780 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10782 switch (get_attr_type (insn))
10785 gcc_assert (operands[2] == const1_rtx);
10786 return "add{q}\t%0, %0";
10789 if (REG_P (operands[2]))
10790 return "sal{q}\t{%b2, %0|%0, %b2}";
10791 else if (operands[2] == const1_rtx
10792 && (TARGET_SHIFT1 || optimize_size))
10793 return "sal{q}\t%0";
10795 return "sal{q}\t{%2, %0|%0, %2}";
10798 [(set (attr "type")
10799 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10801 (match_operand 0 "register_operand" ""))
10802 (match_operand 2 "const1_operand" ""))
10803 (const_string "alu")
10805 (const_string "ishift")))
10806 (set_attr "mode" "DI")])
10808 (define_insn "*ashldi3_cconly_rex64"
10809 [(set (reg FLAGS_REG)
10811 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10812 (match_operand:QI 2 "immediate_operand" "e"))
10814 (clobber (match_scratch:DI 0 "=r"))]
10815 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10816 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10818 || !TARGET_PARTIAL_FLAG_REG_STALL
10819 || (operands[2] == const1_rtx
10821 || TARGET_DOUBLE_WITH_ADD)))"
10823 switch (get_attr_type (insn))
10826 gcc_assert (operands[2] == const1_rtx);
10827 return "add{q}\t%0, %0";
10830 if (REG_P (operands[2]))
10831 return "sal{q}\t{%b2, %0|%0, %b2}";
10832 else if (operands[2] == const1_rtx
10833 && (TARGET_SHIFT1 || optimize_size))
10834 return "sal{q}\t%0";
10836 return "sal{q}\t{%2, %0|%0, %2}";
10839 [(set (attr "type")
10840 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10842 (match_operand 0 "register_operand" ""))
10843 (match_operand 2 "const1_operand" ""))
10844 (const_string "alu")
10846 (const_string "ishift")))
10847 (set_attr "mode" "DI")])
10849 (define_insn "*ashldi3_1"
10850 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10851 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10852 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10853 (clobber (reg:CC FLAGS_REG))]
10856 [(set_attr "type" "multi")])
10858 ;; By default we don't ask for a scratch register, because when DImode
10859 ;; values are manipulated, registers are already at a premium. But if
10860 ;; we have one handy, we won't turn it away.
10862 [(match_scratch:SI 3 "r")
10863 (parallel [(set (match_operand:DI 0 "register_operand" "")
10864 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10865 (match_operand:QI 2 "nonmemory_operand" "")))
10866 (clobber (reg:CC FLAGS_REG))])
10868 "!TARGET_64BIT && TARGET_CMOVE"
10870 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10873 [(set (match_operand:DI 0 "register_operand" "")
10874 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10875 (match_operand:QI 2 "nonmemory_operand" "")))
10876 (clobber (reg:CC FLAGS_REG))]
10877 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10878 ? flow2_completed : reload_completed)"
10880 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10882 (define_insn "x86_shld_1"
10883 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10884 (ior:SI (ashift:SI (match_dup 0)
10885 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10886 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10887 (minus:QI (const_int 32) (match_dup 2)))))
10888 (clobber (reg:CC FLAGS_REG))]
10891 shld{l}\t{%2, %1, %0|%0, %1, %2}
10892 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10893 [(set_attr "type" "ishift")
10894 (set_attr "prefix_0f" "1")
10895 (set_attr "mode" "SI")
10896 (set_attr "pent_pair" "np")
10897 (set_attr "athlon_decode" "vector")
10898 (set_attr "amdfam10_decode" "vector")])
10900 (define_expand "x86_shift_adj_1"
10901 [(set (reg:CCZ FLAGS_REG)
10902 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10905 (set (match_operand:SI 0 "register_operand" "")
10906 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10907 (match_operand:SI 1 "register_operand" "")
10910 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10911 (match_operand:SI 3 "register_operand" "r")
10916 (define_expand "x86_shift_adj_2"
10917 [(use (match_operand:SI 0 "register_operand" ""))
10918 (use (match_operand:SI 1 "register_operand" ""))
10919 (use (match_operand:QI 2 "register_operand" ""))]
10922 rtx label = gen_label_rtx ();
10925 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10927 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10928 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10929 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10930 gen_rtx_LABEL_REF (VOIDmode, label),
10932 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10933 JUMP_LABEL (tmp) = label;
10935 emit_move_insn (operands[0], operands[1]);
10936 ix86_expand_clear (operands[1]);
10938 emit_label (label);
10939 LABEL_NUSES (label) = 1;
10944 (define_expand "ashlsi3"
10945 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10946 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10947 (match_operand:QI 2 "nonmemory_operand" "")))
10948 (clobber (reg:CC FLAGS_REG))]
10950 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10952 (define_insn "*ashlsi3_1"
10953 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10954 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10955 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10956 (clobber (reg:CC FLAGS_REG))]
10957 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10959 switch (get_attr_type (insn))
10962 gcc_assert (operands[2] == const1_rtx);
10963 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10964 return "add{l}\t%0, %0";
10970 if (REG_P (operands[2]))
10971 return "sal{l}\t{%b2, %0|%0, %b2}";
10972 else if (operands[2] == const1_rtx
10973 && (TARGET_SHIFT1 || optimize_size))
10974 return "sal{l}\t%0";
10976 return "sal{l}\t{%2, %0|%0, %2}";
10979 [(set (attr "type")
10980 (cond [(eq_attr "alternative" "1")
10981 (const_string "lea")
10982 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10984 (match_operand 0 "register_operand" ""))
10985 (match_operand 2 "const1_operand" ""))
10986 (const_string "alu")
10988 (const_string "ishift")))
10989 (set_attr "mode" "SI")])
10991 ;; Convert lea to the lea pattern to avoid flags dependency.
10993 [(set (match_operand 0 "register_operand" "")
10994 (ashift (match_operand 1 "index_register_operand" "")
10995 (match_operand:QI 2 "const_int_operand" "")))
10996 (clobber (reg:CC FLAGS_REG))]
10998 && true_regnum (operands[0]) != true_regnum (operands[1])
10999 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11003 enum machine_mode mode = GET_MODE (operands[0]);
11005 if (GET_MODE_SIZE (mode) < 4)
11006 operands[0] = gen_lowpart (SImode, operands[0]);
11008 operands[1] = gen_lowpart (Pmode, operands[1]);
11009 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11011 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11012 if (Pmode != SImode)
11013 pat = gen_rtx_SUBREG (SImode, pat, 0);
11014 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11018 ;; Rare case of shifting RSP is handled by generating move and shift
11020 [(set (match_operand 0 "register_operand" "")
11021 (ashift (match_operand 1 "register_operand" "")
11022 (match_operand:QI 2 "const_int_operand" "")))
11023 (clobber (reg:CC FLAGS_REG))]
11025 && true_regnum (operands[0]) != true_regnum (operands[1])"
11029 emit_move_insn (operands[0], operands[1]);
11030 pat = gen_rtx_SET (VOIDmode, operands[0],
11031 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11032 operands[0], operands[2]));
11033 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11034 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11038 (define_insn "*ashlsi3_1_zext"
11039 [(set (match_operand:DI 0 "register_operand" "=r,r")
11040 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11041 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11042 (clobber (reg:CC FLAGS_REG))]
11043 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11045 switch (get_attr_type (insn))
11048 gcc_assert (operands[2] == const1_rtx);
11049 return "add{l}\t%k0, %k0";
11055 if (REG_P (operands[2]))
11056 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11057 else if (operands[2] == const1_rtx
11058 && (TARGET_SHIFT1 || optimize_size))
11059 return "sal{l}\t%k0";
11061 return "sal{l}\t{%2, %k0|%k0, %2}";
11064 [(set (attr "type")
11065 (cond [(eq_attr "alternative" "1")
11066 (const_string "lea")
11067 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11069 (match_operand 2 "const1_operand" ""))
11070 (const_string "alu")
11072 (const_string "ishift")))
11073 (set_attr "mode" "SI")])
11075 ;; Convert lea to the lea pattern to avoid flags dependency.
11077 [(set (match_operand:DI 0 "register_operand" "")
11078 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11079 (match_operand:QI 2 "const_int_operand" ""))))
11080 (clobber (reg:CC FLAGS_REG))]
11081 "TARGET_64BIT && reload_completed
11082 && true_regnum (operands[0]) != true_regnum (operands[1])"
11083 [(set (match_dup 0) (zero_extend:DI
11084 (subreg:SI (mult:SI (match_dup 1)
11085 (match_dup 2)) 0)))]
11087 operands[1] = gen_lowpart (Pmode, operands[1]);
11088 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11091 ;; This pattern can't accept a variable shift count, since shifts by
11092 ;; zero don't affect the flags. We assume that shifts by constant
11093 ;; zero are optimized away.
11094 (define_insn "*ashlsi3_cmp"
11095 [(set (reg FLAGS_REG)
11097 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11098 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11100 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11101 (ashift:SI (match_dup 1) (match_dup 2)))]
11102 "ix86_match_ccmode (insn, CCGOCmode)
11103 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11105 || !TARGET_PARTIAL_FLAG_REG_STALL
11106 || (operands[2] == const1_rtx
11108 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11110 switch (get_attr_type (insn))
11113 gcc_assert (operands[2] == const1_rtx);
11114 return "add{l}\t%0, %0";
11117 if (REG_P (operands[2]))
11118 return "sal{l}\t{%b2, %0|%0, %b2}";
11119 else if (operands[2] == const1_rtx
11120 && (TARGET_SHIFT1 || optimize_size))
11121 return "sal{l}\t%0";
11123 return "sal{l}\t{%2, %0|%0, %2}";
11126 [(set (attr "type")
11127 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11129 (match_operand 0 "register_operand" ""))
11130 (match_operand 2 "const1_operand" ""))
11131 (const_string "alu")
11133 (const_string "ishift")))
11134 (set_attr "mode" "SI")])
11136 (define_insn "*ashlsi3_cconly"
11137 [(set (reg FLAGS_REG)
11139 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11140 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11142 (clobber (match_scratch:SI 0 "=r"))]
11143 "ix86_match_ccmode (insn, CCGOCmode)
11144 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11146 || !TARGET_PARTIAL_FLAG_REG_STALL
11147 || (operands[2] == const1_rtx
11149 || TARGET_DOUBLE_WITH_ADD)))"
11151 switch (get_attr_type (insn))
11154 gcc_assert (operands[2] == const1_rtx);
11155 return "add{l}\t%0, %0";
11158 if (REG_P (operands[2]))
11159 return "sal{l}\t{%b2, %0|%0, %b2}";
11160 else if (operands[2] == const1_rtx
11161 && (TARGET_SHIFT1 || optimize_size))
11162 return "sal{l}\t%0";
11164 return "sal{l}\t{%2, %0|%0, %2}";
11167 [(set (attr "type")
11168 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11170 (match_operand 0 "register_operand" ""))
11171 (match_operand 2 "const1_operand" ""))
11172 (const_string "alu")
11174 (const_string "ishift")))
11175 (set_attr "mode" "SI")])
11177 (define_insn "*ashlsi3_cmp_zext"
11178 [(set (reg FLAGS_REG)
11180 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11181 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11183 (set (match_operand:DI 0 "register_operand" "=r")
11184 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11185 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11186 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11188 || !TARGET_PARTIAL_FLAG_REG_STALL
11189 || (operands[2] == const1_rtx
11191 || TARGET_DOUBLE_WITH_ADD)))"
11193 switch (get_attr_type (insn))
11196 gcc_assert (operands[2] == const1_rtx);
11197 return "add{l}\t%k0, %k0";
11200 if (REG_P (operands[2]))
11201 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11202 else if (operands[2] == const1_rtx
11203 && (TARGET_SHIFT1 || optimize_size))
11204 return "sal{l}\t%k0";
11206 return "sal{l}\t{%2, %k0|%k0, %2}";
11209 [(set (attr "type")
11210 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11212 (match_operand 2 "const1_operand" ""))
11213 (const_string "alu")
11215 (const_string "ishift")))
11216 (set_attr "mode" "SI")])
11218 (define_expand "ashlhi3"
11219 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11220 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11221 (match_operand:QI 2 "nonmemory_operand" "")))
11222 (clobber (reg:CC FLAGS_REG))]
11223 "TARGET_HIMODE_MATH"
11224 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11226 (define_insn "*ashlhi3_1_lea"
11227 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11228 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11229 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11230 (clobber (reg:CC FLAGS_REG))]
11231 "!TARGET_PARTIAL_REG_STALL
11232 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11234 switch (get_attr_type (insn))
11239 gcc_assert (operands[2] == const1_rtx);
11240 return "add{w}\t%0, %0";
11243 if (REG_P (operands[2]))
11244 return "sal{w}\t{%b2, %0|%0, %b2}";
11245 else if (operands[2] == const1_rtx
11246 && (TARGET_SHIFT1 || optimize_size))
11247 return "sal{w}\t%0";
11249 return "sal{w}\t{%2, %0|%0, %2}";
11252 [(set (attr "type")
11253 (cond [(eq_attr "alternative" "1")
11254 (const_string "lea")
11255 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11257 (match_operand 0 "register_operand" ""))
11258 (match_operand 2 "const1_operand" ""))
11259 (const_string "alu")
11261 (const_string "ishift")))
11262 (set_attr "mode" "HI,SI")])
11264 (define_insn "*ashlhi3_1"
11265 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11266 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11267 (match_operand:QI 2 "nonmemory_operand" "cI")))
11268 (clobber (reg:CC FLAGS_REG))]
11269 "TARGET_PARTIAL_REG_STALL
11270 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11272 switch (get_attr_type (insn))
11275 gcc_assert (operands[2] == const1_rtx);
11276 return "add{w}\t%0, %0";
11279 if (REG_P (operands[2]))
11280 return "sal{w}\t{%b2, %0|%0, %b2}";
11281 else if (operands[2] == const1_rtx
11282 && (TARGET_SHIFT1 || optimize_size))
11283 return "sal{w}\t%0";
11285 return "sal{w}\t{%2, %0|%0, %2}";
11288 [(set (attr "type")
11289 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11291 (match_operand 0 "register_operand" ""))
11292 (match_operand 2 "const1_operand" ""))
11293 (const_string "alu")
11295 (const_string "ishift")))
11296 (set_attr "mode" "HI")])
11298 ;; This pattern can't accept a variable shift count, since shifts by
11299 ;; zero don't affect the flags. We assume that shifts by constant
11300 ;; zero are optimized away.
11301 (define_insn "*ashlhi3_cmp"
11302 [(set (reg FLAGS_REG)
11304 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11305 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11307 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11308 (ashift:HI (match_dup 1) (match_dup 2)))]
11309 "ix86_match_ccmode (insn, CCGOCmode)
11310 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11312 || !TARGET_PARTIAL_FLAG_REG_STALL
11313 || (operands[2] == const1_rtx
11315 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11317 switch (get_attr_type (insn))
11320 gcc_assert (operands[2] == const1_rtx);
11321 return "add{w}\t%0, %0";
11324 if (REG_P (operands[2]))
11325 return "sal{w}\t{%b2, %0|%0, %b2}";
11326 else if (operands[2] == const1_rtx
11327 && (TARGET_SHIFT1 || optimize_size))
11328 return "sal{w}\t%0";
11330 return "sal{w}\t{%2, %0|%0, %2}";
11333 [(set (attr "type")
11334 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11336 (match_operand 0 "register_operand" ""))
11337 (match_operand 2 "const1_operand" ""))
11338 (const_string "alu")
11340 (const_string "ishift")))
11341 (set_attr "mode" "HI")])
11343 (define_insn "*ashlhi3_cconly"
11344 [(set (reg FLAGS_REG)
11346 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11347 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11349 (clobber (match_scratch:HI 0 "=r"))]
11350 "ix86_match_ccmode (insn, CCGOCmode)
11351 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11353 || !TARGET_PARTIAL_FLAG_REG_STALL
11354 || (operands[2] == const1_rtx
11356 || TARGET_DOUBLE_WITH_ADD)))"
11358 switch (get_attr_type (insn))
11361 gcc_assert (operands[2] == const1_rtx);
11362 return "add{w}\t%0, %0";
11365 if (REG_P (operands[2]))
11366 return "sal{w}\t{%b2, %0|%0, %b2}";
11367 else if (operands[2] == const1_rtx
11368 && (TARGET_SHIFT1 || optimize_size))
11369 return "sal{w}\t%0";
11371 return "sal{w}\t{%2, %0|%0, %2}";
11374 [(set (attr "type")
11375 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11377 (match_operand 0 "register_operand" ""))
11378 (match_operand 2 "const1_operand" ""))
11379 (const_string "alu")
11381 (const_string "ishift")))
11382 (set_attr "mode" "HI")])
11384 (define_expand "ashlqi3"
11385 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11386 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11387 (match_operand:QI 2 "nonmemory_operand" "")))
11388 (clobber (reg:CC FLAGS_REG))]
11389 "TARGET_QIMODE_MATH"
11390 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11392 ;; %%% Potential partial reg stall on alternative 2. What to do?
11394 (define_insn "*ashlqi3_1_lea"
11395 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11396 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11397 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11398 (clobber (reg:CC FLAGS_REG))]
11399 "!TARGET_PARTIAL_REG_STALL
11400 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11402 switch (get_attr_type (insn))
11407 gcc_assert (operands[2] == const1_rtx);
11408 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11409 return "add{l}\t%k0, %k0";
11411 return "add{b}\t%0, %0";
11414 if (REG_P (operands[2]))
11416 if (get_attr_mode (insn) == MODE_SI)
11417 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11419 return "sal{b}\t{%b2, %0|%0, %b2}";
11421 else if (operands[2] == const1_rtx
11422 && (TARGET_SHIFT1 || optimize_size))
11424 if (get_attr_mode (insn) == MODE_SI)
11425 return "sal{l}\t%0";
11427 return "sal{b}\t%0";
11431 if (get_attr_mode (insn) == MODE_SI)
11432 return "sal{l}\t{%2, %k0|%k0, %2}";
11434 return "sal{b}\t{%2, %0|%0, %2}";
11438 [(set (attr "type")
11439 (cond [(eq_attr "alternative" "2")
11440 (const_string "lea")
11441 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11443 (match_operand 0 "register_operand" ""))
11444 (match_operand 2 "const1_operand" ""))
11445 (const_string "alu")
11447 (const_string "ishift")))
11448 (set_attr "mode" "QI,SI,SI")])
11450 (define_insn "*ashlqi3_1"
11451 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11452 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11453 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11454 (clobber (reg:CC FLAGS_REG))]
11455 "TARGET_PARTIAL_REG_STALL
11456 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11458 switch (get_attr_type (insn))
11461 gcc_assert (operands[2] == const1_rtx);
11462 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11463 return "add{l}\t%k0, %k0";
11465 return "add{b}\t%0, %0";
11468 if (REG_P (operands[2]))
11470 if (get_attr_mode (insn) == MODE_SI)
11471 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11473 return "sal{b}\t{%b2, %0|%0, %b2}";
11475 else if (operands[2] == const1_rtx
11476 && (TARGET_SHIFT1 || optimize_size))
11478 if (get_attr_mode (insn) == MODE_SI)
11479 return "sal{l}\t%0";
11481 return "sal{b}\t%0";
11485 if (get_attr_mode (insn) == MODE_SI)
11486 return "sal{l}\t{%2, %k0|%k0, %2}";
11488 return "sal{b}\t{%2, %0|%0, %2}";
11492 [(set (attr "type")
11493 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11495 (match_operand 0 "register_operand" ""))
11496 (match_operand 2 "const1_operand" ""))
11497 (const_string "alu")
11499 (const_string "ishift")))
11500 (set_attr "mode" "QI,SI")])
11502 ;; This pattern can't accept a variable shift count, since shifts by
11503 ;; zero don't affect the flags. We assume that shifts by constant
11504 ;; zero are optimized away.
11505 (define_insn "*ashlqi3_cmp"
11506 [(set (reg FLAGS_REG)
11508 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11509 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11511 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11512 (ashift:QI (match_dup 1) (match_dup 2)))]
11513 "ix86_match_ccmode (insn, CCGOCmode)
11514 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11516 || !TARGET_PARTIAL_FLAG_REG_STALL
11517 || (operands[2] == const1_rtx
11519 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11521 switch (get_attr_type (insn))
11524 gcc_assert (operands[2] == const1_rtx);
11525 return "add{b}\t%0, %0";
11528 if (REG_P (operands[2]))
11529 return "sal{b}\t{%b2, %0|%0, %b2}";
11530 else if (operands[2] == const1_rtx
11531 && (TARGET_SHIFT1 || optimize_size))
11532 return "sal{b}\t%0";
11534 return "sal{b}\t{%2, %0|%0, %2}";
11537 [(set (attr "type")
11538 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11540 (match_operand 0 "register_operand" ""))
11541 (match_operand 2 "const1_operand" ""))
11542 (const_string "alu")
11544 (const_string "ishift")))
11545 (set_attr "mode" "QI")])
11547 (define_insn "*ashlqi3_cconly"
11548 [(set (reg FLAGS_REG)
11550 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11551 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11553 (clobber (match_scratch:QI 0 "=q"))]
11554 "ix86_match_ccmode (insn, CCGOCmode)
11555 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11557 || !TARGET_PARTIAL_FLAG_REG_STALL
11558 || (operands[2] == const1_rtx
11560 || TARGET_DOUBLE_WITH_ADD)))"
11562 switch (get_attr_type (insn))
11565 gcc_assert (operands[2] == const1_rtx);
11566 return "add{b}\t%0, %0";
11569 if (REG_P (operands[2]))
11570 return "sal{b}\t{%b2, %0|%0, %b2}";
11571 else if (operands[2] == const1_rtx
11572 && (TARGET_SHIFT1 || optimize_size))
11573 return "sal{b}\t%0";
11575 return "sal{b}\t{%2, %0|%0, %2}";
11578 [(set (attr "type")
11579 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11581 (match_operand 0 "register_operand" ""))
11582 (match_operand 2 "const1_operand" ""))
11583 (const_string "alu")
11585 (const_string "ishift")))
11586 (set_attr "mode" "QI")])
11588 ;; See comment above `ashldi3' about how this works.
11590 (define_expand "ashrti3"
11591 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11592 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11593 (match_operand:QI 2 "nonmemory_operand" "")))
11594 (clobber (reg:CC FLAGS_REG))])]
11597 if (! immediate_operand (operands[2], QImode))
11599 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11602 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11606 (define_insn "ashrti3_1"
11607 [(set (match_operand:TI 0 "register_operand" "=r")
11608 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11609 (match_operand:QI 2 "register_operand" "c")))
11610 (clobber (match_scratch:DI 3 "=&r"))
11611 (clobber (reg:CC FLAGS_REG))]
11614 [(set_attr "type" "multi")])
11616 (define_insn "*ashrti3_2"
11617 [(set (match_operand:TI 0 "register_operand" "=r")
11618 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11619 (match_operand:QI 2 "immediate_operand" "O")))
11620 (clobber (reg:CC FLAGS_REG))]
11623 [(set_attr "type" "multi")])
11626 [(set (match_operand:TI 0 "register_operand" "")
11627 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11628 (match_operand:QI 2 "register_operand" "")))
11629 (clobber (match_scratch:DI 3 ""))
11630 (clobber (reg:CC FLAGS_REG))]
11631 "TARGET_64BIT && reload_completed"
11633 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11636 [(set (match_operand:TI 0 "register_operand" "")
11637 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11638 (match_operand:QI 2 "immediate_operand" "")))
11639 (clobber (reg:CC FLAGS_REG))]
11640 "TARGET_64BIT && reload_completed"
11642 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11644 (define_insn "x86_64_shrd"
11645 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11646 (ior:DI (ashiftrt:DI (match_dup 0)
11647 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11648 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11649 (minus:QI (const_int 64) (match_dup 2)))))
11650 (clobber (reg:CC FLAGS_REG))]
11653 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11654 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11655 [(set_attr "type" "ishift")
11656 (set_attr "prefix_0f" "1")
11657 (set_attr "mode" "DI")
11658 (set_attr "athlon_decode" "vector")
11659 (set_attr "amdfam10_decode" "vector")])
11661 (define_expand "ashrdi3"
11662 [(set (match_operand:DI 0 "shiftdi_operand" "")
11663 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11664 (match_operand:QI 2 "nonmemory_operand" "")))]
11666 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11668 (define_insn "*ashrdi3_63_rex64"
11669 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11670 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11671 (match_operand:DI 2 "const_int_operand" "i,i")))
11672 (clobber (reg:CC FLAGS_REG))]
11673 "TARGET_64BIT && INTVAL (operands[2]) == 63
11674 && (TARGET_USE_CLTD || optimize_size)
11675 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11678 sar{q}\t{%2, %0|%0, %2}"
11679 [(set_attr "type" "imovx,ishift")
11680 (set_attr "prefix_0f" "0,*")
11681 (set_attr "length_immediate" "0,*")
11682 (set_attr "modrm" "0,1")
11683 (set_attr "mode" "DI")])
11685 (define_insn "*ashrdi3_1_one_bit_rex64"
11686 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11687 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11688 (match_operand:QI 2 "const1_operand" "")))
11689 (clobber (reg:CC FLAGS_REG))]
11690 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11691 && (TARGET_SHIFT1 || optimize_size)"
11693 [(set_attr "type" "ishift")
11694 (set (attr "length")
11695 (if_then_else (match_operand:DI 0 "register_operand" "")
11697 (const_string "*")))])
11699 (define_insn "*ashrdi3_1_rex64"
11700 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11701 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11702 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11703 (clobber (reg:CC FLAGS_REG))]
11704 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11706 sar{q}\t{%2, %0|%0, %2}
11707 sar{q}\t{%b2, %0|%0, %b2}"
11708 [(set_attr "type" "ishift")
11709 (set_attr "mode" "DI")])
11711 ;; This pattern can't accept a variable shift count, since shifts by
11712 ;; zero don't affect the flags. We assume that shifts by constant
11713 ;; zero are optimized away.
11714 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11715 [(set (reg FLAGS_REG)
11717 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11718 (match_operand:QI 2 "const1_operand" ""))
11720 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11721 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11722 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11723 && (TARGET_SHIFT1 || optimize_size)
11724 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11726 [(set_attr "type" "ishift")
11727 (set (attr "length")
11728 (if_then_else (match_operand:DI 0 "register_operand" "")
11730 (const_string "*")))])
11732 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11733 [(set (reg FLAGS_REG)
11735 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11736 (match_operand:QI 2 "const1_operand" ""))
11738 (clobber (match_scratch:DI 0 "=r"))]
11739 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11740 && (TARGET_SHIFT1 || optimize_size)
11741 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11743 [(set_attr "type" "ishift")
11744 (set_attr "length" "2")])
11746 ;; This pattern can't accept a variable shift count, since shifts by
11747 ;; zero don't affect the flags. We assume that shifts by constant
11748 ;; zero are optimized away.
11749 (define_insn "*ashrdi3_cmp_rex64"
11750 [(set (reg FLAGS_REG)
11752 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11753 (match_operand:QI 2 "const_int_operand" "n"))
11755 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11756 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11757 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11758 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11760 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11761 "sar{q}\t{%2, %0|%0, %2}"
11762 [(set_attr "type" "ishift")
11763 (set_attr "mode" "DI")])
11765 (define_insn "*ashrdi3_cconly_rex64"
11766 [(set (reg FLAGS_REG)
11768 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11769 (match_operand:QI 2 "const_int_operand" "n"))
11771 (clobber (match_scratch:DI 0 "=r"))]
11772 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11773 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11775 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11776 "sar{q}\t{%2, %0|%0, %2}"
11777 [(set_attr "type" "ishift")
11778 (set_attr "mode" "DI")])
11780 (define_insn "*ashrdi3_1"
11781 [(set (match_operand:DI 0 "register_operand" "=r")
11782 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11783 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11784 (clobber (reg:CC FLAGS_REG))]
11787 [(set_attr "type" "multi")])
11789 ;; By default we don't ask for a scratch register, because when DImode
11790 ;; values are manipulated, registers are already at a premium. But if
11791 ;; we have one handy, we won't turn it away.
11793 [(match_scratch:SI 3 "r")
11794 (parallel [(set (match_operand:DI 0 "register_operand" "")
11795 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11796 (match_operand:QI 2 "nonmemory_operand" "")))
11797 (clobber (reg:CC FLAGS_REG))])
11799 "!TARGET_64BIT && TARGET_CMOVE"
11801 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11804 [(set (match_operand:DI 0 "register_operand" "")
11805 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11806 (match_operand:QI 2 "nonmemory_operand" "")))
11807 (clobber (reg:CC FLAGS_REG))]
11808 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11809 ? flow2_completed : reload_completed)"
11811 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11813 (define_insn "x86_shrd_1"
11814 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11815 (ior:SI (ashiftrt:SI (match_dup 0)
11816 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11817 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11818 (minus:QI (const_int 32) (match_dup 2)))))
11819 (clobber (reg:CC FLAGS_REG))]
11822 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11823 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11824 [(set_attr "type" "ishift")
11825 (set_attr "prefix_0f" "1")
11826 (set_attr "pent_pair" "np")
11827 (set_attr "mode" "SI")])
11829 (define_expand "x86_shift_adj_3"
11830 [(use (match_operand:SI 0 "register_operand" ""))
11831 (use (match_operand:SI 1 "register_operand" ""))
11832 (use (match_operand:QI 2 "register_operand" ""))]
11835 rtx label = gen_label_rtx ();
11838 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11840 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11841 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11842 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11843 gen_rtx_LABEL_REF (VOIDmode, label),
11845 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11846 JUMP_LABEL (tmp) = label;
11848 emit_move_insn (operands[0], operands[1]);
11849 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11851 emit_label (label);
11852 LABEL_NUSES (label) = 1;
11857 (define_insn "ashrsi3_31"
11858 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11859 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11860 (match_operand:SI 2 "const_int_operand" "i,i")))
11861 (clobber (reg:CC FLAGS_REG))]
11862 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11863 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11866 sar{l}\t{%2, %0|%0, %2}"
11867 [(set_attr "type" "imovx,ishift")
11868 (set_attr "prefix_0f" "0,*")
11869 (set_attr "length_immediate" "0,*")
11870 (set_attr "modrm" "0,1")
11871 (set_attr "mode" "SI")])
11873 (define_insn "*ashrsi3_31_zext"
11874 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11875 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11876 (match_operand:SI 2 "const_int_operand" "i,i"))))
11877 (clobber (reg:CC FLAGS_REG))]
11878 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11879 && INTVAL (operands[2]) == 31
11880 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11883 sar{l}\t{%2, %k0|%k0, %2}"
11884 [(set_attr "type" "imovx,ishift")
11885 (set_attr "prefix_0f" "0,*")
11886 (set_attr "length_immediate" "0,*")
11887 (set_attr "modrm" "0,1")
11888 (set_attr "mode" "SI")])
11890 (define_expand "ashrsi3"
11891 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11892 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11893 (match_operand:QI 2 "nonmemory_operand" "")))
11894 (clobber (reg:CC FLAGS_REG))]
11896 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11898 (define_insn "*ashrsi3_1_one_bit"
11899 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11900 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11901 (match_operand:QI 2 "const1_operand" "")))
11902 (clobber (reg:CC FLAGS_REG))]
11903 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11904 && (TARGET_SHIFT1 || optimize_size)"
11906 [(set_attr "type" "ishift")
11907 (set (attr "length")
11908 (if_then_else (match_operand:SI 0 "register_operand" "")
11910 (const_string "*")))])
11912 (define_insn "*ashrsi3_1_one_bit_zext"
11913 [(set (match_operand:DI 0 "register_operand" "=r")
11914 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11915 (match_operand:QI 2 "const1_operand" ""))))
11916 (clobber (reg:CC FLAGS_REG))]
11917 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11918 && (TARGET_SHIFT1 || optimize_size)"
11920 [(set_attr "type" "ishift")
11921 (set_attr "length" "2")])
11923 (define_insn "*ashrsi3_1"
11924 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11925 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11926 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11927 (clobber (reg:CC FLAGS_REG))]
11928 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11930 sar{l}\t{%2, %0|%0, %2}
11931 sar{l}\t{%b2, %0|%0, %b2}"
11932 [(set_attr "type" "ishift")
11933 (set_attr "mode" "SI")])
11935 (define_insn "*ashrsi3_1_zext"
11936 [(set (match_operand:DI 0 "register_operand" "=r,r")
11937 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11938 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11939 (clobber (reg:CC FLAGS_REG))]
11940 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11942 sar{l}\t{%2, %k0|%k0, %2}
11943 sar{l}\t{%b2, %k0|%k0, %b2}"
11944 [(set_attr "type" "ishift")
11945 (set_attr "mode" "SI")])
11947 ;; This pattern can't accept a variable shift count, since shifts by
11948 ;; zero don't affect the flags. We assume that shifts by constant
11949 ;; zero are optimized away.
11950 (define_insn "*ashrsi3_one_bit_cmp"
11951 [(set (reg FLAGS_REG)
11953 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11954 (match_operand:QI 2 "const1_operand" ""))
11956 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11957 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11958 "ix86_match_ccmode (insn, CCGOCmode)
11959 && (TARGET_SHIFT1 || optimize_size)
11960 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11962 [(set_attr "type" "ishift")
11963 (set (attr "length")
11964 (if_then_else (match_operand:SI 0 "register_operand" "")
11966 (const_string "*")))])
11968 (define_insn "*ashrsi3_one_bit_cconly"
11969 [(set (reg FLAGS_REG)
11971 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11972 (match_operand:QI 2 "const1_operand" ""))
11974 (clobber (match_scratch:SI 0 "=r"))]
11975 "ix86_match_ccmode (insn, CCGOCmode)
11976 && (TARGET_SHIFT1 || optimize_size)
11977 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11979 [(set_attr "type" "ishift")
11980 (set_attr "length" "2")])
11982 (define_insn "*ashrsi3_one_bit_cmp_zext"
11983 [(set (reg FLAGS_REG)
11985 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11986 (match_operand:QI 2 "const1_operand" ""))
11988 (set (match_operand:DI 0 "register_operand" "=r")
11989 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11990 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11991 && (TARGET_SHIFT1 || optimize_size)
11992 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11994 [(set_attr "type" "ishift")
11995 (set_attr "length" "2")])
11997 ;; This pattern can't accept a variable shift count, since shifts by
11998 ;; zero don't affect the flags. We assume that shifts by constant
11999 ;; zero are optimized away.
12000 (define_insn "*ashrsi3_cmp"
12001 [(set (reg FLAGS_REG)
12003 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12004 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12006 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12007 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12008 "ix86_match_ccmode (insn, CCGOCmode)
12009 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12011 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12012 "sar{l}\t{%2, %0|%0, %2}"
12013 [(set_attr "type" "ishift")
12014 (set_attr "mode" "SI")])
12016 (define_insn "*ashrsi3_cconly"
12017 [(set (reg FLAGS_REG)
12019 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12020 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12022 (clobber (match_scratch:SI 0 "=r"))]
12023 "ix86_match_ccmode (insn, CCGOCmode)
12024 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12026 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12027 "sar{l}\t{%2, %0|%0, %2}"
12028 [(set_attr "type" "ishift")
12029 (set_attr "mode" "SI")])
12031 (define_insn "*ashrsi3_cmp_zext"
12032 [(set (reg FLAGS_REG)
12034 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12035 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12037 (set (match_operand:DI 0 "register_operand" "=r")
12038 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12039 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12040 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12042 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12043 "sar{l}\t{%2, %k0|%k0, %2}"
12044 [(set_attr "type" "ishift")
12045 (set_attr "mode" "SI")])
12047 (define_expand "ashrhi3"
12048 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12049 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12050 (match_operand:QI 2 "nonmemory_operand" "")))
12051 (clobber (reg:CC FLAGS_REG))]
12052 "TARGET_HIMODE_MATH"
12053 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12055 (define_insn "*ashrhi3_1_one_bit"
12056 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12057 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12058 (match_operand:QI 2 "const1_operand" "")))
12059 (clobber (reg:CC FLAGS_REG))]
12060 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12061 && (TARGET_SHIFT1 || optimize_size)"
12063 [(set_attr "type" "ishift")
12064 (set (attr "length")
12065 (if_then_else (match_operand 0 "register_operand" "")
12067 (const_string "*")))])
12069 (define_insn "*ashrhi3_1"
12070 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12071 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12072 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12073 (clobber (reg:CC FLAGS_REG))]
12074 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12076 sar{w}\t{%2, %0|%0, %2}
12077 sar{w}\t{%b2, %0|%0, %b2}"
12078 [(set_attr "type" "ishift")
12079 (set_attr "mode" "HI")])
12081 ;; This pattern can't accept a variable shift count, since shifts by
12082 ;; zero don't affect the flags. We assume that shifts by constant
12083 ;; zero are optimized away.
12084 (define_insn "*ashrhi3_one_bit_cmp"
12085 [(set (reg FLAGS_REG)
12087 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12088 (match_operand:QI 2 "const1_operand" ""))
12090 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12091 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12092 "ix86_match_ccmode (insn, CCGOCmode)
12093 && (TARGET_SHIFT1 || optimize_size)
12094 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12096 [(set_attr "type" "ishift")
12097 (set (attr "length")
12098 (if_then_else (match_operand 0 "register_operand" "")
12100 (const_string "*")))])
12102 (define_insn "*ashrhi3_one_bit_cconly"
12103 [(set (reg FLAGS_REG)
12105 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12106 (match_operand:QI 2 "const1_operand" ""))
12108 (clobber (match_scratch:HI 0 "=r"))]
12109 "ix86_match_ccmode (insn, CCGOCmode)
12110 && (TARGET_SHIFT1 || optimize_size)
12111 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12113 [(set_attr "type" "ishift")
12114 (set_attr "length" "2")])
12116 ;; This pattern can't accept a variable shift count, since shifts by
12117 ;; zero don't affect the flags. We assume that shifts by constant
12118 ;; zero are optimized away.
12119 (define_insn "*ashrhi3_cmp"
12120 [(set (reg FLAGS_REG)
12122 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12123 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12125 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12126 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12127 "ix86_match_ccmode (insn, CCGOCmode)
12128 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12130 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12131 "sar{w}\t{%2, %0|%0, %2}"
12132 [(set_attr "type" "ishift")
12133 (set_attr "mode" "HI")])
12135 (define_insn "*ashrhi3_cconly"
12136 [(set (reg FLAGS_REG)
12138 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12139 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12141 (clobber (match_scratch:HI 0 "=r"))]
12142 "ix86_match_ccmode (insn, CCGOCmode)
12143 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12145 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12146 "sar{w}\t{%2, %0|%0, %2}"
12147 [(set_attr "type" "ishift")
12148 (set_attr "mode" "HI")])
12150 (define_expand "ashrqi3"
12151 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12152 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12153 (match_operand:QI 2 "nonmemory_operand" "")))
12154 (clobber (reg:CC FLAGS_REG))]
12155 "TARGET_QIMODE_MATH"
12156 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12158 (define_insn "*ashrqi3_1_one_bit"
12159 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12160 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12161 (match_operand:QI 2 "const1_operand" "")))
12162 (clobber (reg:CC FLAGS_REG))]
12163 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12164 && (TARGET_SHIFT1 || optimize_size)"
12166 [(set_attr "type" "ishift")
12167 (set (attr "length")
12168 (if_then_else (match_operand 0 "register_operand" "")
12170 (const_string "*")))])
12172 (define_insn "*ashrqi3_1_one_bit_slp"
12173 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12174 (ashiftrt:QI (match_dup 0)
12175 (match_operand:QI 1 "const1_operand" "")))
12176 (clobber (reg:CC FLAGS_REG))]
12177 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12178 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12179 && (TARGET_SHIFT1 || optimize_size)"
12181 [(set_attr "type" "ishift1")
12182 (set (attr "length")
12183 (if_then_else (match_operand 0 "register_operand" "")
12185 (const_string "*")))])
12187 (define_insn "*ashrqi3_1"
12188 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12189 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12190 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12191 (clobber (reg:CC FLAGS_REG))]
12192 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12194 sar{b}\t{%2, %0|%0, %2}
12195 sar{b}\t{%b2, %0|%0, %b2}"
12196 [(set_attr "type" "ishift")
12197 (set_attr "mode" "QI")])
12199 (define_insn "*ashrqi3_1_slp"
12200 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12201 (ashiftrt:QI (match_dup 0)
12202 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12203 (clobber (reg:CC FLAGS_REG))]
12204 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12205 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12207 sar{b}\t{%1, %0|%0, %1}
12208 sar{b}\t{%b1, %0|%0, %b1}"
12209 [(set_attr "type" "ishift1")
12210 (set_attr "mode" "QI")])
12212 ;; This pattern can't accept a variable shift count, since shifts by
12213 ;; zero don't affect the flags. We assume that shifts by constant
12214 ;; zero are optimized away.
12215 (define_insn "*ashrqi3_one_bit_cmp"
12216 [(set (reg FLAGS_REG)
12218 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12219 (match_operand:QI 2 "const1_operand" "I"))
12221 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12222 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12223 "ix86_match_ccmode (insn, CCGOCmode)
12224 && (TARGET_SHIFT1 || optimize_size)
12225 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12227 [(set_attr "type" "ishift")
12228 (set (attr "length")
12229 (if_then_else (match_operand 0 "register_operand" "")
12231 (const_string "*")))])
12233 (define_insn "*ashrqi3_one_bit_cconly"
12234 [(set (reg FLAGS_REG)
12236 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12237 (match_operand:QI 2 "const1_operand" "I"))
12239 (clobber (match_scratch:QI 0 "=q"))]
12240 "ix86_match_ccmode (insn, CCGOCmode)
12241 && (TARGET_SHIFT1 || optimize_size)
12242 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12244 [(set_attr "type" "ishift")
12245 (set_attr "length" "2")])
12247 ;; This pattern can't accept a variable shift count, since shifts by
12248 ;; zero don't affect the flags. We assume that shifts by constant
12249 ;; zero are optimized away.
12250 (define_insn "*ashrqi3_cmp"
12251 [(set (reg FLAGS_REG)
12253 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12254 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12256 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12257 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12258 "ix86_match_ccmode (insn, CCGOCmode)
12259 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12261 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12262 "sar{b}\t{%2, %0|%0, %2}"
12263 [(set_attr "type" "ishift")
12264 (set_attr "mode" "QI")])
12266 (define_insn "*ashrqi3_cconly"
12267 [(set (reg FLAGS_REG)
12269 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12270 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12272 (clobber (match_scratch:QI 0 "=q"))]
12273 "ix86_match_ccmode (insn, CCGOCmode)
12274 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12276 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12277 "sar{b}\t{%2, %0|%0, %2}"
12278 [(set_attr "type" "ishift")
12279 (set_attr "mode" "QI")])
12282 ;; Logical shift instructions
12284 ;; See comment above `ashldi3' about how this works.
12286 (define_expand "lshrti3"
12287 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12288 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12289 (match_operand:QI 2 "nonmemory_operand" "")))
12290 (clobber (reg:CC FLAGS_REG))])]
12293 if (! immediate_operand (operands[2], QImode))
12295 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12298 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12302 (define_insn "lshrti3_1"
12303 [(set (match_operand:TI 0 "register_operand" "=r")
12304 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12305 (match_operand:QI 2 "register_operand" "c")))
12306 (clobber (match_scratch:DI 3 "=&r"))
12307 (clobber (reg:CC FLAGS_REG))]
12310 [(set_attr "type" "multi")])
12312 (define_insn "*lshrti3_2"
12313 [(set (match_operand:TI 0 "register_operand" "=r")
12314 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12315 (match_operand:QI 2 "immediate_operand" "O")))
12316 (clobber (reg:CC FLAGS_REG))]
12319 [(set_attr "type" "multi")])
12322 [(set (match_operand:TI 0 "register_operand" "")
12323 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12324 (match_operand:QI 2 "register_operand" "")))
12325 (clobber (match_scratch:DI 3 ""))
12326 (clobber (reg:CC FLAGS_REG))]
12327 "TARGET_64BIT && reload_completed"
12329 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12332 [(set (match_operand:TI 0 "register_operand" "")
12333 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12334 (match_operand:QI 2 "immediate_operand" "")))
12335 (clobber (reg:CC FLAGS_REG))]
12336 "TARGET_64BIT && reload_completed"
12338 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12340 (define_expand "lshrdi3"
12341 [(set (match_operand:DI 0 "shiftdi_operand" "")
12342 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12343 (match_operand:QI 2 "nonmemory_operand" "")))]
12345 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12347 (define_insn "*lshrdi3_1_one_bit_rex64"
12348 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12349 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12350 (match_operand:QI 2 "const1_operand" "")))
12351 (clobber (reg:CC FLAGS_REG))]
12352 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12353 && (TARGET_SHIFT1 || optimize_size)"
12355 [(set_attr "type" "ishift")
12356 (set (attr "length")
12357 (if_then_else (match_operand:DI 0 "register_operand" "")
12359 (const_string "*")))])
12361 (define_insn "*lshrdi3_1_rex64"
12362 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12363 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12364 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12365 (clobber (reg:CC FLAGS_REG))]
12366 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12368 shr{q}\t{%2, %0|%0, %2}
12369 shr{q}\t{%b2, %0|%0, %b2}"
12370 [(set_attr "type" "ishift")
12371 (set_attr "mode" "DI")])
12373 ;; This pattern can't accept a variable shift count, since shifts by
12374 ;; zero don't affect the flags. We assume that shifts by constant
12375 ;; zero are optimized away.
12376 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12377 [(set (reg FLAGS_REG)
12379 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12380 (match_operand:QI 2 "const1_operand" ""))
12382 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12383 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12384 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12385 && (TARGET_SHIFT1 || optimize_size)
12386 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12388 [(set_attr "type" "ishift")
12389 (set (attr "length")
12390 (if_then_else (match_operand:DI 0 "register_operand" "")
12392 (const_string "*")))])
12394 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12395 [(set (reg FLAGS_REG)
12397 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12398 (match_operand:QI 2 "const1_operand" ""))
12400 (clobber (match_scratch:DI 0 "=r"))]
12401 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12402 && (TARGET_SHIFT1 || optimize_size)
12403 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12405 [(set_attr "type" "ishift")
12406 (set_attr "length" "2")])
12408 ;; This pattern can't accept a variable shift count, since shifts by
12409 ;; zero don't affect the flags. We assume that shifts by constant
12410 ;; zero are optimized away.
12411 (define_insn "*lshrdi3_cmp_rex64"
12412 [(set (reg FLAGS_REG)
12414 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12415 (match_operand:QI 2 "const_int_operand" "e"))
12417 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12418 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12419 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12420 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12422 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12423 "shr{q}\t{%2, %0|%0, %2}"
12424 [(set_attr "type" "ishift")
12425 (set_attr "mode" "DI")])
12427 (define_insn "*lshrdi3_cconly_rex64"
12428 [(set (reg FLAGS_REG)
12430 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12431 (match_operand:QI 2 "const_int_operand" "e"))
12433 (clobber (match_scratch:DI 0 "=r"))]
12434 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12435 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12437 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12438 "shr{q}\t{%2, %0|%0, %2}"
12439 [(set_attr "type" "ishift")
12440 (set_attr "mode" "DI")])
12442 (define_insn "*lshrdi3_1"
12443 [(set (match_operand:DI 0 "register_operand" "=r")
12444 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12445 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12446 (clobber (reg:CC FLAGS_REG))]
12449 [(set_attr "type" "multi")])
12451 ;; By default we don't ask for a scratch register, because when DImode
12452 ;; values are manipulated, registers are already at a premium. But if
12453 ;; we have one handy, we won't turn it away.
12455 [(match_scratch:SI 3 "r")
12456 (parallel [(set (match_operand:DI 0 "register_operand" "")
12457 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12458 (match_operand:QI 2 "nonmemory_operand" "")))
12459 (clobber (reg:CC FLAGS_REG))])
12461 "!TARGET_64BIT && TARGET_CMOVE"
12463 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12466 [(set (match_operand:DI 0 "register_operand" "")
12467 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12468 (match_operand:QI 2 "nonmemory_operand" "")))
12469 (clobber (reg:CC FLAGS_REG))]
12470 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12471 ? flow2_completed : reload_completed)"
12473 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12475 (define_expand "lshrsi3"
12476 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12477 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12478 (match_operand:QI 2 "nonmemory_operand" "")))
12479 (clobber (reg:CC FLAGS_REG))]
12481 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12483 (define_insn "*lshrsi3_1_one_bit"
12484 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12485 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12486 (match_operand:QI 2 "const1_operand" "")))
12487 (clobber (reg:CC FLAGS_REG))]
12488 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12489 && (TARGET_SHIFT1 || optimize_size)"
12491 [(set_attr "type" "ishift")
12492 (set (attr "length")
12493 (if_then_else (match_operand:SI 0 "register_operand" "")
12495 (const_string "*")))])
12497 (define_insn "*lshrsi3_1_one_bit_zext"
12498 [(set (match_operand:DI 0 "register_operand" "=r")
12499 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12500 (match_operand:QI 2 "const1_operand" "")))
12501 (clobber (reg:CC FLAGS_REG))]
12502 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12503 && (TARGET_SHIFT1 || optimize_size)"
12505 [(set_attr "type" "ishift")
12506 (set_attr "length" "2")])
12508 (define_insn "*lshrsi3_1"
12509 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12510 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12511 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12512 (clobber (reg:CC FLAGS_REG))]
12513 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12515 shr{l}\t{%2, %0|%0, %2}
12516 shr{l}\t{%b2, %0|%0, %b2}"
12517 [(set_attr "type" "ishift")
12518 (set_attr "mode" "SI")])
12520 (define_insn "*lshrsi3_1_zext"
12521 [(set (match_operand:DI 0 "register_operand" "=r,r")
12523 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12524 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12525 (clobber (reg:CC FLAGS_REG))]
12526 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12528 shr{l}\t{%2, %k0|%k0, %2}
12529 shr{l}\t{%b2, %k0|%k0, %b2}"
12530 [(set_attr "type" "ishift")
12531 (set_attr "mode" "SI")])
12533 ;; This pattern can't accept a variable shift count, since shifts by
12534 ;; zero don't affect the flags. We assume that shifts by constant
12535 ;; zero are optimized away.
12536 (define_insn "*lshrsi3_one_bit_cmp"
12537 [(set (reg FLAGS_REG)
12539 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12540 (match_operand:QI 2 "const1_operand" ""))
12542 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12543 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12544 "ix86_match_ccmode (insn, CCGOCmode)
12545 && (TARGET_SHIFT1 || optimize_size)
12546 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12548 [(set_attr "type" "ishift")
12549 (set (attr "length")
12550 (if_then_else (match_operand:SI 0 "register_operand" "")
12552 (const_string "*")))])
12554 (define_insn "*lshrsi3_one_bit_cconly"
12555 [(set (reg FLAGS_REG)
12557 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12558 (match_operand:QI 2 "const1_operand" ""))
12560 (clobber (match_scratch:SI 0 "=r"))]
12561 "ix86_match_ccmode (insn, CCGOCmode)
12562 && (TARGET_SHIFT1 || optimize_size)
12563 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12565 [(set_attr "type" "ishift")
12566 (set_attr "length" "2")])
12568 (define_insn "*lshrsi3_cmp_one_bit_zext"
12569 [(set (reg FLAGS_REG)
12571 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12572 (match_operand:QI 2 "const1_operand" ""))
12574 (set (match_operand:DI 0 "register_operand" "=r")
12575 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12576 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12577 && (TARGET_SHIFT1 || optimize_size)
12578 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12580 [(set_attr "type" "ishift")
12581 (set_attr "length" "2")])
12583 ;; This pattern can't accept a variable shift count, since shifts by
12584 ;; zero don't affect the flags. We assume that shifts by constant
12585 ;; zero are optimized away.
12586 (define_insn "*lshrsi3_cmp"
12587 [(set (reg FLAGS_REG)
12589 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12590 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12592 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12593 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12594 "ix86_match_ccmode (insn, CCGOCmode)
12595 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12597 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12598 "shr{l}\t{%2, %0|%0, %2}"
12599 [(set_attr "type" "ishift")
12600 (set_attr "mode" "SI")])
12602 (define_insn "*lshrsi3_cconly"
12603 [(set (reg FLAGS_REG)
12605 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12606 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12608 (clobber (match_scratch:SI 0 "=r"))]
12609 "ix86_match_ccmode (insn, CCGOCmode)
12610 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12612 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12613 "shr{l}\t{%2, %0|%0, %2}"
12614 [(set_attr "type" "ishift")
12615 (set_attr "mode" "SI")])
12617 (define_insn "*lshrsi3_cmp_zext"
12618 [(set (reg FLAGS_REG)
12620 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12621 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12623 (set (match_operand:DI 0 "register_operand" "=r")
12624 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12625 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12626 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12628 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12629 "shr{l}\t{%2, %k0|%k0, %2}"
12630 [(set_attr "type" "ishift")
12631 (set_attr "mode" "SI")])
12633 (define_expand "lshrhi3"
12634 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12635 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12636 (match_operand:QI 2 "nonmemory_operand" "")))
12637 (clobber (reg:CC FLAGS_REG))]
12638 "TARGET_HIMODE_MATH"
12639 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12641 (define_insn "*lshrhi3_1_one_bit"
12642 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12643 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12644 (match_operand:QI 2 "const1_operand" "")))
12645 (clobber (reg:CC FLAGS_REG))]
12646 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12647 && (TARGET_SHIFT1 || optimize_size)"
12649 [(set_attr "type" "ishift")
12650 (set (attr "length")
12651 (if_then_else (match_operand 0 "register_operand" "")
12653 (const_string "*")))])
12655 (define_insn "*lshrhi3_1"
12656 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12657 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12658 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12659 (clobber (reg:CC FLAGS_REG))]
12660 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12662 shr{w}\t{%2, %0|%0, %2}
12663 shr{w}\t{%b2, %0|%0, %b2}"
12664 [(set_attr "type" "ishift")
12665 (set_attr "mode" "HI")])
12667 ;; This pattern can't accept a variable shift count, since shifts by
12668 ;; zero don't affect the flags. We assume that shifts by constant
12669 ;; zero are optimized away.
12670 (define_insn "*lshrhi3_one_bit_cmp"
12671 [(set (reg FLAGS_REG)
12673 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12674 (match_operand:QI 2 "const1_operand" ""))
12676 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12677 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12678 "ix86_match_ccmode (insn, CCGOCmode)
12679 && (TARGET_SHIFT1 || optimize_size)
12680 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12682 [(set_attr "type" "ishift")
12683 (set (attr "length")
12684 (if_then_else (match_operand:SI 0 "register_operand" "")
12686 (const_string "*")))])
12688 (define_insn "*lshrhi3_one_bit_cconly"
12689 [(set (reg FLAGS_REG)
12691 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12692 (match_operand:QI 2 "const1_operand" ""))
12694 (clobber (match_scratch:HI 0 "=r"))]
12695 "ix86_match_ccmode (insn, CCGOCmode)
12696 && (TARGET_SHIFT1 || optimize_size)
12697 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12699 [(set_attr "type" "ishift")
12700 (set_attr "length" "2")])
12702 ;; This pattern can't accept a variable shift count, since shifts by
12703 ;; zero don't affect the flags. We assume that shifts by constant
12704 ;; zero are optimized away.
12705 (define_insn "*lshrhi3_cmp"
12706 [(set (reg FLAGS_REG)
12708 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12709 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12711 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12712 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12713 "ix86_match_ccmode (insn, CCGOCmode)
12714 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12716 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12717 "shr{w}\t{%2, %0|%0, %2}"
12718 [(set_attr "type" "ishift")
12719 (set_attr "mode" "HI")])
12721 (define_insn "*lshrhi3_cconly"
12722 [(set (reg FLAGS_REG)
12724 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12725 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12727 (clobber (match_scratch:HI 0 "=r"))]
12728 "ix86_match_ccmode (insn, CCGOCmode)
12729 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12731 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12732 "shr{w}\t{%2, %0|%0, %2}"
12733 [(set_attr "type" "ishift")
12734 (set_attr "mode" "HI")])
12736 (define_expand "lshrqi3"
12737 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12738 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12739 (match_operand:QI 2 "nonmemory_operand" "")))
12740 (clobber (reg:CC FLAGS_REG))]
12741 "TARGET_QIMODE_MATH"
12742 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12744 (define_insn "*lshrqi3_1_one_bit"
12745 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12746 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12747 (match_operand:QI 2 "const1_operand" "")))
12748 (clobber (reg:CC FLAGS_REG))]
12749 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12750 && (TARGET_SHIFT1 || optimize_size)"
12752 [(set_attr "type" "ishift")
12753 (set (attr "length")
12754 (if_then_else (match_operand 0 "register_operand" "")
12756 (const_string "*")))])
12758 (define_insn "*lshrqi3_1_one_bit_slp"
12759 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12760 (lshiftrt:QI (match_dup 0)
12761 (match_operand:QI 1 "const1_operand" "")))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12764 && (TARGET_SHIFT1 || optimize_size)"
12766 [(set_attr "type" "ishift1")
12767 (set (attr "length")
12768 (if_then_else (match_operand 0 "register_operand" "")
12770 (const_string "*")))])
12772 (define_insn "*lshrqi3_1"
12773 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12774 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12775 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12776 (clobber (reg:CC FLAGS_REG))]
12777 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12779 shr{b}\t{%2, %0|%0, %2}
12780 shr{b}\t{%b2, %0|%0, %b2}"
12781 [(set_attr "type" "ishift")
12782 (set_attr "mode" "QI")])
12784 (define_insn "*lshrqi3_1_slp"
12785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12786 (lshiftrt:QI (match_dup 0)
12787 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12788 (clobber (reg:CC FLAGS_REG))]
12789 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12790 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12792 shr{b}\t{%1, %0|%0, %1}
12793 shr{b}\t{%b1, %0|%0, %b1}"
12794 [(set_attr "type" "ishift1")
12795 (set_attr "mode" "QI")])
12797 ;; This pattern can't accept a variable shift count, since shifts by
12798 ;; zero don't affect the flags. We assume that shifts by constant
12799 ;; zero are optimized away.
12800 (define_insn "*lshrqi2_one_bit_cmp"
12801 [(set (reg FLAGS_REG)
12803 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12804 (match_operand:QI 2 "const1_operand" ""))
12806 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12807 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12808 "ix86_match_ccmode (insn, CCGOCmode)
12809 && (TARGET_SHIFT1 || optimize_size)
12810 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12812 [(set_attr "type" "ishift")
12813 (set (attr "length")
12814 (if_then_else (match_operand:SI 0 "register_operand" "")
12816 (const_string "*")))])
12818 (define_insn "*lshrqi2_one_bit_cconly"
12819 [(set (reg FLAGS_REG)
12821 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12822 (match_operand:QI 2 "const1_operand" ""))
12824 (clobber (match_scratch:QI 0 "=q"))]
12825 "ix86_match_ccmode (insn, CCGOCmode)
12826 && (TARGET_SHIFT1 || optimize_size)
12827 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12829 [(set_attr "type" "ishift")
12830 (set_attr "length" "2")])
12832 ;; This pattern can't accept a variable shift count, since shifts by
12833 ;; zero don't affect the flags. We assume that shifts by constant
12834 ;; zero are optimized away.
12835 (define_insn "*lshrqi2_cmp"
12836 [(set (reg FLAGS_REG)
12838 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12839 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12841 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12842 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12843 "ix86_match_ccmode (insn, CCGOCmode)
12844 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12846 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12847 "shr{b}\t{%2, %0|%0, %2}"
12848 [(set_attr "type" "ishift")
12849 (set_attr "mode" "QI")])
12851 (define_insn "*lshrqi2_cconly"
12852 [(set (reg FLAGS_REG)
12854 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12855 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12857 (clobber (match_scratch:QI 0 "=q"))]
12858 "ix86_match_ccmode (insn, CCGOCmode)
12859 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12861 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12862 "shr{b}\t{%2, %0|%0, %2}"
12863 [(set_attr "type" "ishift")
12864 (set_attr "mode" "QI")])
12866 ;; Rotate instructions
12868 (define_expand "rotldi3"
12869 [(set (match_operand:DI 0 "shiftdi_operand" "")
12870 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12871 (match_operand:QI 2 "nonmemory_operand" "")))
12872 (clobber (reg:CC FLAGS_REG))]
12877 ix86_expand_binary_operator (ROTATE, DImode, operands);
12880 if (!const_1_to_31_operand (operands[2], VOIDmode))
12882 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12886 ;; Implement rotation using two double-precision shift instructions
12887 ;; and a scratch register.
12888 (define_insn_and_split "ix86_rotldi3"
12889 [(set (match_operand:DI 0 "register_operand" "=r")
12890 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12891 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12892 (clobber (reg:CC FLAGS_REG))
12893 (clobber (match_scratch:SI 3 "=&r"))]
12896 "&& reload_completed"
12897 [(set (match_dup 3) (match_dup 4))
12899 [(set (match_dup 4)
12900 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12901 (lshiftrt:SI (match_dup 5)
12902 (minus:QI (const_int 32) (match_dup 2)))))
12903 (clobber (reg:CC FLAGS_REG))])
12905 [(set (match_dup 5)
12906 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12907 (lshiftrt:SI (match_dup 3)
12908 (minus:QI (const_int 32) (match_dup 2)))))
12909 (clobber (reg:CC FLAGS_REG))])]
12910 "split_di (operands, 1, operands + 4, operands + 5);")
12912 (define_insn "*rotlsi3_1_one_bit_rex64"
12913 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12914 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12915 (match_operand:QI 2 "const1_operand" "")))
12916 (clobber (reg:CC FLAGS_REG))]
12917 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12918 && (TARGET_SHIFT1 || optimize_size)"
12920 [(set_attr "type" "rotate")
12921 (set (attr "length")
12922 (if_then_else (match_operand:DI 0 "register_operand" "")
12924 (const_string "*")))])
12926 (define_insn "*rotldi3_1_rex64"
12927 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12928 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12929 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12930 (clobber (reg:CC FLAGS_REG))]
12931 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12933 rol{q}\t{%2, %0|%0, %2}
12934 rol{q}\t{%b2, %0|%0, %b2}"
12935 [(set_attr "type" "rotate")
12936 (set_attr "mode" "DI")])
12938 (define_expand "rotlsi3"
12939 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12940 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12941 (match_operand:QI 2 "nonmemory_operand" "")))
12942 (clobber (reg:CC FLAGS_REG))]
12944 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12946 (define_insn "*rotlsi3_1_one_bit"
12947 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12948 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12949 (match_operand:QI 2 "const1_operand" "")))
12950 (clobber (reg:CC FLAGS_REG))]
12951 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12952 && (TARGET_SHIFT1 || optimize_size)"
12954 [(set_attr "type" "rotate")
12955 (set (attr "length")
12956 (if_then_else (match_operand:SI 0 "register_operand" "")
12958 (const_string "*")))])
12960 (define_insn "*rotlsi3_1_one_bit_zext"
12961 [(set (match_operand:DI 0 "register_operand" "=r")
12963 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12964 (match_operand:QI 2 "const1_operand" ""))))
12965 (clobber (reg:CC FLAGS_REG))]
12966 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12967 && (TARGET_SHIFT1 || optimize_size)"
12969 [(set_attr "type" "rotate")
12970 (set_attr "length" "2")])
12972 (define_insn "*rotlsi3_1"
12973 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12974 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12975 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12976 (clobber (reg:CC FLAGS_REG))]
12977 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12979 rol{l}\t{%2, %0|%0, %2}
12980 rol{l}\t{%b2, %0|%0, %b2}"
12981 [(set_attr "type" "rotate")
12982 (set_attr "mode" "SI")])
12984 (define_insn "*rotlsi3_1_zext"
12985 [(set (match_operand:DI 0 "register_operand" "=r,r")
12987 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12988 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12989 (clobber (reg:CC FLAGS_REG))]
12990 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12992 rol{l}\t{%2, %k0|%k0, %2}
12993 rol{l}\t{%b2, %k0|%k0, %b2}"
12994 [(set_attr "type" "rotate")
12995 (set_attr "mode" "SI")])
12997 (define_expand "rotlhi3"
12998 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12999 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13000 (match_operand:QI 2 "nonmemory_operand" "")))
13001 (clobber (reg:CC FLAGS_REG))]
13002 "TARGET_HIMODE_MATH"
13003 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13005 (define_insn "*rotlhi3_1_one_bit"
13006 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13007 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13008 (match_operand:QI 2 "const1_operand" "")))
13009 (clobber (reg:CC FLAGS_REG))]
13010 "ix86_binary_operator_ok (ROTATE, HImode, operands)
13011 && (TARGET_SHIFT1 || optimize_size)"
13013 [(set_attr "type" "rotate")
13014 (set (attr "length")
13015 (if_then_else (match_operand 0 "register_operand" "")
13017 (const_string "*")))])
13019 (define_insn "*rotlhi3_1"
13020 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13021 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13022 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13023 (clobber (reg:CC FLAGS_REG))]
13024 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13026 rol{w}\t{%2, %0|%0, %2}
13027 rol{w}\t{%b2, %0|%0, %b2}"
13028 [(set_attr "type" "rotate")
13029 (set_attr "mode" "HI")])
13031 (define_expand "rotlqi3"
13032 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13033 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13034 (match_operand:QI 2 "nonmemory_operand" "")))
13035 (clobber (reg:CC FLAGS_REG))]
13036 "TARGET_QIMODE_MATH"
13037 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13039 (define_insn "*rotlqi3_1_one_bit_slp"
13040 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13041 (rotate:QI (match_dup 0)
13042 (match_operand:QI 1 "const1_operand" "")))
13043 (clobber (reg:CC FLAGS_REG))]
13044 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13045 && (TARGET_SHIFT1 || optimize_size)"
13047 [(set_attr "type" "rotate1")
13048 (set (attr "length")
13049 (if_then_else (match_operand 0 "register_operand" "")
13051 (const_string "*")))])
13053 (define_insn "*rotlqi3_1_one_bit"
13054 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13055 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13056 (match_operand:QI 2 "const1_operand" "")))
13057 (clobber (reg:CC FLAGS_REG))]
13058 "ix86_binary_operator_ok (ROTATE, QImode, operands)
13059 && (TARGET_SHIFT1 || optimize_size)"
13061 [(set_attr "type" "rotate")
13062 (set (attr "length")
13063 (if_then_else (match_operand 0 "register_operand" "")
13065 (const_string "*")))])
13067 (define_insn "*rotlqi3_1_slp"
13068 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13069 (rotate:QI (match_dup 0)
13070 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13071 (clobber (reg:CC FLAGS_REG))]
13072 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13073 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13075 rol{b}\t{%1, %0|%0, %1}
13076 rol{b}\t{%b1, %0|%0, %b1}"
13077 [(set_attr "type" "rotate1")
13078 (set_attr "mode" "QI")])
13080 (define_insn "*rotlqi3_1"
13081 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13082 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13083 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13084 (clobber (reg:CC FLAGS_REG))]
13085 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13087 rol{b}\t{%2, %0|%0, %2}
13088 rol{b}\t{%b2, %0|%0, %b2}"
13089 [(set_attr "type" "rotate")
13090 (set_attr "mode" "QI")])
13092 (define_expand "rotrdi3"
13093 [(set (match_operand:DI 0 "shiftdi_operand" "")
13094 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13095 (match_operand:QI 2 "nonmemory_operand" "")))
13096 (clobber (reg:CC FLAGS_REG))]
13101 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13104 if (!const_1_to_31_operand (operands[2], VOIDmode))
13106 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13110 ;; Implement rotation using two double-precision shift instructions
13111 ;; and a scratch register.
13112 (define_insn_and_split "ix86_rotrdi3"
13113 [(set (match_operand:DI 0 "register_operand" "=r")
13114 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13115 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13116 (clobber (reg:CC FLAGS_REG))
13117 (clobber (match_scratch:SI 3 "=&r"))]
13120 "&& reload_completed"
13121 [(set (match_dup 3) (match_dup 4))
13123 [(set (match_dup 4)
13124 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13125 (ashift:SI (match_dup 5)
13126 (minus:QI (const_int 32) (match_dup 2)))))
13127 (clobber (reg:CC FLAGS_REG))])
13129 [(set (match_dup 5)
13130 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13131 (ashift:SI (match_dup 3)
13132 (minus:QI (const_int 32) (match_dup 2)))))
13133 (clobber (reg:CC FLAGS_REG))])]
13134 "split_di (operands, 1, operands + 4, operands + 5);")
13136 (define_insn "*rotrdi3_1_one_bit_rex64"
13137 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13138 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13139 (match_operand:QI 2 "const1_operand" "")))
13140 (clobber (reg:CC FLAGS_REG))]
13141 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13142 && (TARGET_SHIFT1 || optimize_size)"
13144 [(set_attr "type" "rotate")
13145 (set (attr "length")
13146 (if_then_else (match_operand:DI 0 "register_operand" "")
13148 (const_string "*")))])
13150 (define_insn "*rotrdi3_1_rex64"
13151 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13152 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13153 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13154 (clobber (reg:CC FLAGS_REG))]
13155 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13157 ror{q}\t{%2, %0|%0, %2}
13158 ror{q}\t{%b2, %0|%0, %b2}"
13159 [(set_attr "type" "rotate")
13160 (set_attr "mode" "DI")])
13162 (define_expand "rotrsi3"
13163 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13164 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13165 (match_operand:QI 2 "nonmemory_operand" "")))
13166 (clobber (reg:CC FLAGS_REG))]
13168 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13170 (define_insn "*rotrsi3_1_one_bit"
13171 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13172 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13173 (match_operand:QI 2 "const1_operand" "")))
13174 (clobber (reg:CC FLAGS_REG))]
13175 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13176 && (TARGET_SHIFT1 || optimize_size)"
13178 [(set_attr "type" "rotate")
13179 (set (attr "length")
13180 (if_then_else (match_operand:SI 0 "register_operand" "")
13182 (const_string "*")))])
13184 (define_insn "*rotrsi3_1_one_bit_zext"
13185 [(set (match_operand:DI 0 "register_operand" "=r")
13187 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13188 (match_operand:QI 2 "const1_operand" ""))))
13189 (clobber (reg:CC FLAGS_REG))]
13190 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13191 && (TARGET_SHIFT1 || optimize_size)"
13193 [(set_attr "type" "rotate")
13194 (set (attr "length")
13195 (if_then_else (match_operand:SI 0 "register_operand" "")
13197 (const_string "*")))])
13199 (define_insn "*rotrsi3_1"
13200 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13201 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13202 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13203 (clobber (reg:CC FLAGS_REG))]
13204 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13206 ror{l}\t{%2, %0|%0, %2}
13207 ror{l}\t{%b2, %0|%0, %b2}"
13208 [(set_attr "type" "rotate")
13209 (set_attr "mode" "SI")])
13211 (define_insn "*rotrsi3_1_zext"
13212 [(set (match_operand:DI 0 "register_operand" "=r,r")
13214 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13215 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13216 (clobber (reg:CC FLAGS_REG))]
13217 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13219 ror{l}\t{%2, %k0|%k0, %2}
13220 ror{l}\t{%b2, %k0|%k0, %b2}"
13221 [(set_attr "type" "rotate")
13222 (set_attr "mode" "SI")])
13224 (define_expand "rotrhi3"
13225 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13226 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13227 (match_operand:QI 2 "nonmemory_operand" "")))
13228 (clobber (reg:CC FLAGS_REG))]
13229 "TARGET_HIMODE_MATH"
13230 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13232 (define_insn "*rotrhi3_one_bit"
13233 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13234 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13235 (match_operand:QI 2 "const1_operand" "")))
13236 (clobber (reg:CC FLAGS_REG))]
13237 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13238 && (TARGET_SHIFT1 || optimize_size)"
13240 [(set_attr "type" "rotate")
13241 (set (attr "length")
13242 (if_then_else (match_operand 0 "register_operand" "")
13244 (const_string "*")))])
13246 (define_insn "*rotrhi3"
13247 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13248 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13249 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13250 (clobber (reg:CC FLAGS_REG))]
13251 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13253 ror{w}\t{%2, %0|%0, %2}
13254 ror{w}\t{%b2, %0|%0, %b2}"
13255 [(set_attr "type" "rotate")
13256 (set_attr "mode" "HI")])
13258 (define_expand "rotrqi3"
13259 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13260 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13261 (match_operand:QI 2 "nonmemory_operand" "")))
13262 (clobber (reg:CC FLAGS_REG))]
13263 "TARGET_QIMODE_MATH"
13264 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13266 (define_insn "*rotrqi3_1_one_bit"
13267 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13268 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13269 (match_operand:QI 2 "const1_operand" "")))
13270 (clobber (reg:CC FLAGS_REG))]
13271 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13272 && (TARGET_SHIFT1 || optimize_size)"
13274 [(set_attr "type" "rotate")
13275 (set (attr "length")
13276 (if_then_else (match_operand 0 "register_operand" "")
13278 (const_string "*")))])
13280 (define_insn "*rotrqi3_1_one_bit_slp"
13281 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13282 (rotatert:QI (match_dup 0)
13283 (match_operand:QI 1 "const1_operand" "")))
13284 (clobber (reg:CC FLAGS_REG))]
13285 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13286 && (TARGET_SHIFT1 || optimize_size)"
13288 [(set_attr "type" "rotate1")
13289 (set (attr "length")
13290 (if_then_else (match_operand 0 "register_operand" "")
13292 (const_string "*")))])
13294 (define_insn "*rotrqi3_1"
13295 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13296 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13297 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13298 (clobber (reg:CC FLAGS_REG))]
13299 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13301 ror{b}\t{%2, %0|%0, %2}
13302 ror{b}\t{%b2, %0|%0, %b2}"
13303 [(set_attr "type" "rotate")
13304 (set_attr "mode" "QI")])
13306 (define_insn "*rotrqi3_1_slp"
13307 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13308 (rotatert:QI (match_dup 0)
13309 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13310 (clobber (reg:CC FLAGS_REG))]
13311 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13312 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13314 ror{b}\t{%1, %0|%0, %1}
13315 ror{b}\t{%b1, %0|%0, %b1}"
13316 [(set_attr "type" "rotate1")
13317 (set_attr "mode" "QI")])
13319 ;; Bit set / bit test instructions
13321 (define_expand "extv"
13322 [(set (match_operand:SI 0 "register_operand" "")
13323 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13324 (match_operand:SI 2 "const8_operand" "")
13325 (match_operand:SI 3 "const8_operand" "")))]
13328 /* Handle extractions from %ah et al. */
13329 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13332 /* From mips.md: extract_bit_field doesn't verify that our source
13333 matches the predicate, so check it again here. */
13334 if (! ext_register_operand (operands[1], VOIDmode))
13338 (define_expand "extzv"
13339 [(set (match_operand:SI 0 "register_operand" "")
13340 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13341 (match_operand:SI 2 "const8_operand" "")
13342 (match_operand:SI 3 "const8_operand" "")))]
13345 /* Handle extractions from %ah et al. */
13346 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13349 /* From mips.md: extract_bit_field doesn't verify that our source
13350 matches the predicate, so check it again here. */
13351 if (! ext_register_operand (operands[1], VOIDmode))
13355 (define_expand "insv"
13356 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13357 (match_operand 1 "const8_operand" "")
13358 (match_operand 2 "const8_operand" ""))
13359 (match_operand 3 "register_operand" ""))]
13362 /* Handle insertions to %ah et al. */
13363 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13366 /* From mips.md: insert_bit_field doesn't verify that our source
13367 matches the predicate, so check it again here. */
13368 if (! ext_register_operand (operands[0], VOIDmode))
13372 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13374 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13379 ;; %%% bts, btr, btc, bt.
13380 ;; In general these instructions are *slow* when applied to memory,
13381 ;; since they enforce atomic operation. When applied to registers,
13382 ;; it depends on the cpu implementation. They're never faster than
13383 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13384 ;; no point. But in 64-bit, we can't hold the relevant immediates
13385 ;; within the instruction itself, so operating on bits in the high
13386 ;; 32-bits of a register becomes easier.
13388 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13389 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13390 ;; negdf respectively, so they can never be disabled entirely.
13392 (define_insn "*btsq"
13393 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13395 (match_operand:DI 1 "const_0_to_63_operand" ""))
13397 (clobber (reg:CC FLAGS_REG))]
13398 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13400 [(set_attr "type" "alu1")])
13402 (define_insn "*btrq"
13403 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13405 (match_operand:DI 1 "const_0_to_63_operand" ""))
13407 (clobber (reg:CC FLAGS_REG))]
13408 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13410 [(set_attr "type" "alu1")])
13412 (define_insn "*btcq"
13413 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13415 (match_operand:DI 1 "const_0_to_63_operand" ""))
13416 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13417 (clobber (reg:CC FLAGS_REG))]
13418 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13420 [(set_attr "type" "alu1")])
13422 ;; Allow Nocona to avoid these instructions if a register is available.
13425 [(match_scratch:DI 2 "r")
13426 (parallel [(set (zero_extract:DI
13427 (match_operand:DI 0 "register_operand" "")
13429 (match_operand:DI 1 "const_0_to_63_operand" ""))
13431 (clobber (reg:CC FLAGS_REG))])]
13432 "TARGET_64BIT && !TARGET_USE_BT"
13435 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13438 if (HOST_BITS_PER_WIDE_INT >= 64)
13439 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13440 else if (i < HOST_BITS_PER_WIDE_INT)
13441 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13443 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13445 op1 = immed_double_const (lo, hi, DImode);
13448 emit_move_insn (operands[2], op1);
13452 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13457 [(match_scratch:DI 2 "r")
13458 (parallel [(set (zero_extract:DI
13459 (match_operand:DI 0 "register_operand" "")
13461 (match_operand:DI 1 "const_0_to_63_operand" ""))
13463 (clobber (reg:CC FLAGS_REG))])]
13464 "TARGET_64BIT && !TARGET_USE_BT"
13467 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13470 if (HOST_BITS_PER_WIDE_INT >= 64)
13471 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13472 else if (i < HOST_BITS_PER_WIDE_INT)
13473 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13475 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13477 op1 = immed_double_const (~lo, ~hi, DImode);
13480 emit_move_insn (operands[2], op1);
13484 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13489 [(match_scratch:DI 2 "r")
13490 (parallel [(set (zero_extract:DI
13491 (match_operand:DI 0 "register_operand" "")
13493 (match_operand:DI 1 "const_0_to_63_operand" ""))
13494 (not:DI (zero_extract:DI
13495 (match_dup 0) (const_int 1) (match_dup 1))))
13496 (clobber (reg:CC FLAGS_REG))])]
13497 "TARGET_64BIT && !TARGET_USE_BT"
13500 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13503 if (HOST_BITS_PER_WIDE_INT >= 64)
13504 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13505 else if (i < HOST_BITS_PER_WIDE_INT)
13506 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13508 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13510 op1 = immed_double_const (lo, hi, DImode);
13513 emit_move_insn (operands[2], op1);
13517 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13521 ;; Store-flag instructions.
13523 ;; For all sCOND expanders, also expand the compare or test insn that
13524 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13526 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13527 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13528 ;; way, which can later delete the movzx if only QImode is needed.
13530 (define_expand "seq"
13531 [(set (match_operand:QI 0 "register_operand" "")
13532 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13534 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13536 (define_expand "sne"
13537 [(set (match_operand:QI 0 "register_operand" "")
13538 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13540 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13542 (define_expand "sgt"
13543 [(set (match_operand:QI 0 "register_operand" "")
13544 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13546 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13548 (define_expand "sgtu"
13549 [(set (match_operand:QI 0 "register_operand" "")
13550 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13552 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13554 (define_expand "slt"
13555 [(set (match_operand:QI 0 "register_operand" "")
13556 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13558 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13560 (define_expand "sltu"
13561 [(set (match_operand:QI 0 "register_operand" "")
13562 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13564 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13566 (define_expand "sge"
13567 [(set (match_operand:QI 0 "register_operand" "")
13568 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13570 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13572 (define_expand "sgeu"
13573 [(set (match_operand:QI 0 "register_operand" "")
13574 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13576 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13578 (define_expand "sle"
13579 [(set (match_operand:QI 0 "register_operand" "")
13580 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13582 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13584 (define_expand "sleu"
13585 [(set (match_operand:QI 0 "register_operand" "")
13586 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13588 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13590 (define_expand "sunordered"
13591 [(set (match_operand:QI 0 "register_operand" "")
13592 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13593 "TARGET_80387 || TARGET_SSE"
13594 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13596 (define_expand "sordered"
13597 [(set (match_operand:QI 0 "register_operand" "")
13598 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13600 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13602 (define_expand "suneq"
13603 [(set (match_operand:QI 0 "register_operand" "")
13604 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13605 "TARGET_80387 || TARGET_SSE"
13606 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13608 (define_expand "sunge"
13609 [(set (match_operand:QI 0 "register_operand" "")
13610 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13611 "TARGET_80387 || TARGET_SSE"
13612 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13614 (define_expand "sungt"
13615 [(set (match_operand:QI 0 "register_operand" "")
13616 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13617 "TARGET_80387 || TARGET_SSE"
13618 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13620 (define_expand "sunle"
13621 [(set (match_operand:QI 0 "register_operand" "")
13622 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13623 "TARGET_80387 || TARGET_SSE"
13624 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13626 (define_expand "sunlt"
13627 [(set (match_operand:QI 0 "register_operand" "")
13628 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13629 "TARGET_80387 || TARGET_SSE"
13630 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13632 (define_expand "sltgt"
13633 [(set (match_operand:QI 0 "register_operand" "")
13634 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13635 "TARGET_80387 || TARGET_SSE"
13636 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13638 (define_insn "*setcc_1"
13639 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13640 (match_operator:QI 1 "ix86_comparison_operator"
13641 [(reg FLAGS_REG) (const_int 0)]))]
13644 [(set_attr "type" "setcc")
13645 (set_attr "mode" "QI")])
13647 (define_insn "*setcc_2"
13648 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13649 (match_operator:QI 1 "ix86_comparison_operator"
13650 [(reg FLAGS_REG) (const_int 0)]))]
13653 [(set_attr "type" "setcc")
13654 (set_attr "mode" "QI")])
13656 ;; In general it is not safe to assume too much about CCmode registers,
13657 ;; so simplify-rtx stops when it sees a second one. Under certain
13658 ;; conditions this is safe on x86, so help combine not create
13665 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13666 (ne:QI (match_operator 1 "ix86_comparison_operator"
13667 [(reg FLAGS_REG) (const_int 0)])
13670 [(set (match_dup 0) (match_dup 1))]
13672 PUT_MODE (operands[1], QImode);
13676 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13677 (ne:QI (match_operator 1 "ix86_comparison_operator"
13678 [(reg FLAGS_REG) (const_int 0)])
13681 [(set (match_dup 0) (match_dup 1))]
13683 PUT_MODE (operands[1], QImode);
13687 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13688 (eq:QI (match_operator 1 "ix86_comparison_operator"
13689 [(reg FLAGS_REG) (const_int 0)])
13692 [(set (match_dup 0) (match_dup 1))]
13694 rtx new_op1 = copy_rtx (operands[1]);
13695 operands[1] = new_op1;
13696 PUT_MODE (new_op1, QImode);
13697 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13698 GET_MODE (XEXP (new_op1, 0))));
13700 /* Make sure that (a) the CCmode we have for the flags is strong
13701 enough for the reversed compare or (b) we have a valid FP compare. */
13702 if (! ix86_comparison_operator (new_op1, VOIDmode))
13707 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13708 (eq:QI (match_operator 1 "ix86_comparison_operator"
13709 [(reg FLAGS_REG) (const_int 0)])
13712 [(set (match_dup 0) (match_dup 1))]
13714 rtx new_op1 = copy_rtx (operands[1]);
13715 operands[1] = new_op1;
13716 PUT_MODE (new_op1, QImode);
13717 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13718 GET_MODE (XEXP (new_op1, 0))));
13720 /* Make sure that (a) the CCmode we have for the flags is strong
13721 enough for the reversed compare or (b) we have a valid FP compare. */
13722 if (! ix86_comparison_operator (new_op1, VOIDmode))
13726 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13727 ;; subsequent logical operations are used to imitate conditional moves.
13728 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13731 (define_insn "*sse_setccsf"
13732 [(set (match_operand:SF 0 "register_operand" "=x")
13733 (match_operator:SF 1 "sse_comparison_operator"
13734 [(match_operand:SF 2 "register_operand" "0")
13735 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13737 "cmp%D1ss\t{%3, %0|%0, %3}"
13738 [(set_attr "type" "ssecmp")
13739 (set_attr "mode" "SF")])
13741 (define_insn "*sse_setccdf"
13742 [(set (match_operand:DF 0 "register_operand" "=x")
13743 (match_operator:DF 1 "sse_comparison_operator"
13744 [(match_operand:DF 2 "register_operand" "0")
13745 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13747 "cmp%D1sd\t{%3, %0|%0, %3}"
13748 [(set_attr "type" "ssecmp")
13749 (set_attr "mode" "DF")])
13751 ;; Basic conditional jump instructions.
13752 ;; We ignore the overflow flag for signed branch instructions.
13754 ;; For all bCOND expanders, also expand the compare or test insn that
13755 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13757 (define_expand "beq"
13759 (if_then_else (match_dup 1)
13760 (label_ref (match_operand 0 "" ""))
13763 "ix86_expand_branch (EQ, operands[0]); DONE;")
13765 (define_expand "bne"
13767 (if_then_else (match_dup 1)
13768 (label_ref (match_operand 0 "" ""))
13771 "ix86_expand_branch (NE, operands[0]); DONE;")
13773 (define_expand "bgt"
13775 (if_then_else (match_dup 1)
13776 (label_ref (match_operand 0 "" ""))
13779 "ix86_expand_branch (GT, operands[0]); DONE;")
13781 (define_expand "bgtu"
13783 (if_then_else (match_dup 1)
13784 (label_ref (match_operand 0 "" ""))
13787 "ix86_expand_branch (GTU, operands[0]); DONE;")
13789 (define_expand "blt"
13791 (if_then_else (match_dup 1)
13792 (label_ref (match_operand 0 "" ""))
13795 "ix86_expand_branch (LT, operands[0]); DONE;")
13797 (define_expand "bltu"
13799 (if_then_else (match_dup 1)
13800 (label_ref (match_operand 0 "" ""))
13803 "ix86_expand_branch (LTU, operands[0]); DONE;")
13805 (define_expand "bge"
13807 (if_then_else (match_dup 1)
13808 (label_ref (match_operand 0 "" ""))
13811 "ix86_expand_branch (GE, operands[0]); DONE;")
13813 (define_expand "bgeu"
13815 (if_then_else (match_dup 1)
13816 (label_ref (match_operand 0 "" ""))
13819 "ix86_expand_branch (GEU, operands[0]); DONE;")
13821 (define_expand "ble"
13823 (if_then_else (match_dup 1)
13824 (label_ref (match_operand 0 "" ""))
13827 "ix86_expand_branch (LE, operands[0]); DONE;")
13829 (define_expand "bleu"
13831 (if_then_else (match_dup 1)
13832 (label_ref (match_operand 0 "" ""))
13835 "ix86_expand_branch (LEU, operands[0]); DONE;")
13837 (define_expand "bunordered"
13839 (if_then_else (match_dup 1)
13840 (label_ref (match_operand 0 "" ""))
13842 "TARGET_80387 || TARGET_SSE_MATH"
13843 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13845 (define_expand "bordered"
13847 (if_then_else (match_dup 1)
13848 (label_ref (match_operand 0 "" ""))
13850 "TARGET_80387 || TARGET_SSE_MATH"
13851 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13853 (define_expand "buneq"
13855 (if_then_else (match_dup 1)
13856 (label_ref (match_operand 0 "" ""))
13858 "TARGET_80387 || TARGET_SSE_MATH"
13859 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13861 (define_expand "bunge"
13863 (if_then_else (match_dup 1)
13864 (label_ref (match_operand 0 "" ""))
13866 "TARGET_80387 || TARGET_SSE_MATH"
13867 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13869 (define_expand "bungt"
13871 (if_then_else (match_dup 1)
13872 (label_ref (match_operand 0 "" ""))
13874 "TARGET_80387 || TARGET_SSE_MATH"
13875 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13877 (define_expand "bunle"
13879 (if_then_else (match_dup 1)
13880 (label_ref (match_operand 0 "" ""))
13882 "TARGET_80387 || TARGET_SSE_MATH"
13883 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13885 (define_expand "bunlt"
13887 (if_then_else (match_dup 1)
13888 (label_ref (match_operand 0 "" ""))
13890 "TARGET_80387 || TARGET_SSE_MATH"
13891 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13893 (define_expand "bltgt"
13895 (if_then_else (match_dup 1)
13896 (label_ref (match_operand 0 "" ""))
13898 "TARGET_80387 || TARGET_SSE_MATH"
13899 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13901 (define_insn "*jcc_1"
13903 (if_then_else (match_operator 1 "ix86_comparison_operator"
13904 [(reg FLAGS_REG) (const_int 0)])
13905 (label_ref (match_operand 0 "" ""))
13909 [(set_attr "type" "ibr")
13910 (set_attr "modrm" "0")
13911 (set (attr "length")
13912 (if_then_else (and (ge (minus (match_dup 0) (pc))
13914 (lt (minus (match_dup 0) (pc))
13919 (define_insn "*jcc_2"
13921 (if_then_else (match_operator 1 "ix86_comparison_operator"
13922 [(reg FLAGS_REG) (const_int 0)])
13924 (label_ref (match_operand 0 "" ""))))]
13927 [(set_attr "type" "ibr")
13928 (set_attr "modrm" "0")
13929 (set (attr "length")
13930 (if_then_else (and (ge (minus (match_dup 0) (pc))
13932 (lt (minus (match_dup 0) (pc))
13937 ;; In general it is not safe to assume too much about CCmode registers,
13938 ;; so simplify-rtx stops when it sees a second one. Under certain
13939 ;; conditions this is safe on x86, so help combine not create
13947 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13948 [(reg FLAGS_REG) (const_int 0)])
13950 (label_ref (match_operand 1 "" ""))
13954 (if_then_else (match_dup 0)
13955 (label_ref (match_dup 1))
13958 PUT_MODE (operands[0], VOIDmode);
13963 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13964 [(reg FLAGS_REG) (const_int 0)])
13966 (label_ref (match_operand 1 "" ""))
13970 (if_then_else (match_dup 0)
13971 (label_ref (match_dup 1))
13974 rtx new_op0 = copy_rtx (operands[0]);
13975 operands[0] = new_op0;
13976 PUT_MODE (new_op0, VOIDmode);
13977 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13978 GET_MODE (XEXP (new_op0, 0))));
13980 /* Make sure that (a) the CCmode we have for the flags is strong
13981 enough for the reversed compare or (b) we have a valid FP compare. */
13982 if (! ix86_comparison_operator (new_op0, VOIDmode))
13986 ;; Define combination compare-and-branch fp compare instructions to use
13987 ;; during early optimization. Splitting the operation apart early makes
13988 ;; for bad code when we want to reverse the operation.
13990 (define_insn "*fp_jcc_1_mixed"
13992 (if_then_else (match_operator 0 "comparison_operator"
13993 [(match_operand 1 "register_operand" "f,x")
13994 (match_operand 2 "nonimmediate_operand" "f,xm")])
13995 (label_ref (match_operand 3 "" ""))
13997 (clobber (reg:CCFP FPSR_REG))
13998 (clobber (reg:CCFP FLAGS_REG))]
13999 "TARGET_MIX_SSE_I387
14000 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14001 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14002 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14005 (define_insn "*fp_jcc_1_sse"
14007 (if_then_else (match_operator 0 "comparison_operator"
14008 [(match_operand 1 "register_operand" "x")
14009 (match_operand 2 "nonimmediate_operand" "xm")])
14010 (label_ref (match_operand 3 "" ""))
14012 (clobber (reg:CCFP FPSR_REG))
14013 (clobber (reg:CCFP FLAGS_REG))]
14015 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14016 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14017 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14020 (define_insn "*fp_jcc_1_387"
14022 (if_then_else (match_operator 0 "comparison_operator"
14023 [(match_operand 1 "register_operand" "f")
14024 (match_operand 2 "register_operand" "f")])
14025 (label_ref (match_operand 3 "" ""))
14027 (clobber (reg:CCFP FPSR_REG))
14028 (clobber (reg:CCFP FLAGS_REG))]
14029 "TARGET_CMOVE && TARGET_80387
14030 && FLOAT_MODE_P (GET_MODE (operands[1]))
14031 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14032 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14035 (define_insn "*fp_jcc_2_mixed"
14037 (if_then_else (match_operator 0 "comparison_operator"
14038 [(match_operand 1 "register_operand" "f,x")
14039 (match_operand 2 "nonimmediate_operand" "f,xm")])
14041 (label_ref (match_operand 3 "" ""))))
14042 (clobber (reg:CCFP FPSR_REG))
14043 (clobber (reg:CCFP FLAGS_REG))]
14044 "TARGET_MIX_SSE_I387
14045 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14046 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14047 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14050 (define_insn "*fp_jcc_2_sse"
14052 (if_then_else (match_operator 0 "comparison_operator"
14053 [(match_operand 1 "register_operand" "x")
14054 (match_operand 2 "nonimmediate_operand" "xm")])
14056 (label_ref (match_operand 3 "" ""))))
14057 (clobber (reg:CCFP FPSR_REG))
14058 (clobber (reg:CCFP FLAGS_REG))]
14060 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14061 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14062 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14065 (define_insn "*fp_jcc_2_387"
14067 (if_then_else (match_operator 0 "comparison_operator"
14068 [(match_operand 1 "register_operand" "f")
14069 (match_operand 2 "register_operand" "f")])
14071 (label_ref (match_operand 3 "" ""))))
14072 (clobber (reg:CCFP FPSR_REG))
14073 (clobber (reg:CCFP FLAGS_REG))]
14074 "TARGET_CMOVE && TARGET_80387
14075 && FLOAT_MODE_P (GET_MODE (operands[1]))
14076 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14077 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14080 (define_insn "*fp_jcc_3_387"
14082 (if_then_else (match_operator 0 "comparison_operator"
14083 [(match_operand 1 "register_operand" "f")
14084 (match_operand 2 "nonimmediate_operand" "fm")])
14085 (label_ref (match_operand 3 "" ""))
14087 (clobber (reg:CCFP FPSR_REG))
14088 (clobber (reg:CCFP FLAGS_REG))
14089 (clobber (match_scratch:HI 4 "=a"))]
14091 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14092 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14093 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14094 && SELECT_CC_MODE (GET_CODE (operands[0]),
14095 operands[1], operands[2]) == CCFPmode
14096 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14099 (define_insn "*fp_jcc_4_387"
14101 (if_then_else (match_operator 0 "comparison_operator"
14102 [(match_operand 1 "register_operand" "f")
14103 (match_operand 2 "nonimmediate_operand" "fm")])
14105 (label_ref (match_operand 3 "" ""))))
14106 (clobber (reg:CCFP FPSR_REG))
14107 (clobber (reg:CCFP FLAGS_REG))
14108 (clobber (match_scratch:HI 4 "=a"))]
14110 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14111 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14112 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14113 && SELECT_CC_MODE (GET_CODE (operands[0]),
14114 operands[1], operands[2]) == CCFPmode
14115 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14118 (define_insn "*fp_jcc_5_387"
14120 (if_then_else (match_operator 0 "comparison_operator"
14121 [(match_operand 1 "register_operand" "f")
14122 (match_operand 2 "register_operand" "f")])
14123 (label_ref (match_operand 3 "" ""))
14125 (clobber (reg:CCFP FPSR_REG))
14126 (clobber (reg:CCFP FLAGS_REG))
14127 (clobber (match_scratch:HI 4 "=a"))]
14129 && FLOAT_MODE_P (GET_MODE (operands[1]))
14130 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14131 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14134 (define_insn "*fp_jcc_6_387"
14136 (if_then_else (match_operator 0 "comparison_operator"
14137 [(match_operand 1 "register_operand" "f")
14138 (match_operand 2 "register_operand" "f")])
14140 (label_ref (match_operand 3 "" ""))))
14141 (clobber (reg:CCFP FPSR_REG))
14142 (clobber (reg:CCFP FLAGS_REG))
14143 (clobber (match_scratch:HI 4 "=a"))]
14145 && FLOAT_MODE_P (GET_MODE (operands[1]))
14146 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14147 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14150 (define_insn "*fp_jcc_7_387"
14152 (if_then_else (match_operator 0 "comparison_operator"
14153 [(match_operand 1 "register_operand" "f")
14154 (match_operand 2 "const0_operand" "X")])
14155 (label_ref (match_operand 3 "" ""))
14157 (clobber (reg:CCFP FPSR_REG))
14158 (clobber (reg:CCFP FLAGS_REG))
14159 (clobber (match_scratch:HI 4 "=a"))]
14161 && FLOAT_MODE_P (GET_MODE (operands[1]))
14162 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14163 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14164 && SELECT_CC_MODE (GET_CODE (operands[0]),
14165 operands[1], operands[2]) == CCFPmode
14166 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14169 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14170 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14171 ;; with a precedence over other operators and is always put in the first
14172 ;; place. Swap condition and operands to match ficom instruction.
14174 (define_insn "*fp_jcc_8<mode>_387"
14176 (if_then_else (match_operator 0 "comparison_operator"
14177 [(match_operator 1 "float_operator"
14178 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14179 (match_operand 3 "register_operand" "f,f")])
14180 (label_ref (match_operand 4 "" ""))
14182 (clobber (reg:CCFP FPSR_REG))
14183 (clobber (reg:CCFP FLAGS_REG))
14184 (clobber (match_scratch:HI 5 "=a,a"))]
14185 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14186 && FLOAT_MODE_P (GET_MODE (operands[3]))
14187 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14188 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14189 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14190 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14195 (if_then_else (match_operator 0 "comparison_operator"
14196 [(match_operand 1 "register_operand" "")
14197 (match_operand 2 "nonimmediate_operand" "")])
14198 (match_operand 3 "" "")
14199 (match_operand 4 "" "")))
14200 (clobber (reg:CCFP FPSR_REG))
14201 (clobber (reg:CCFP FLAGS_REG))]
14205 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14206 operands[3], operands[4], NULL_RTX, NULL_RTX);
14212 (if_then_else (match_operator 0 "comparison_operator"
14213 [(match_operand 1 "register_operand" "")
14214 (match_operand 2 "general_operand" "")])
14215 (match_operand 3 "" "")
14216 (match_operand 4 "" "")))
14217 (clobber (reg:CCFP FPSR_REG))
14218 (clobber (reg:CCFP FLAGS_REG))
14219 (clobber (match_scratch:HI 5 "=a"))]
14223 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14224 operands[3], operands[4], operands[5], NULL_RTX);
14230 (if_then_else (match_operator 0 "comparison_operator"
14231 [(match_operator 1 "float_operator"
14232 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14233 (match_operand 3 "register_operand" "")])
14234 (match_operand 4 "" "")
14235 (match_operand 5 "" "")))
14236 (clobber (reg:CCFP FPSR_REG))
14237 (clobber (reg:CCFP FLAGS_REG))
14238 (clobber (match_scratch:HI 6 "=a"))]
14242 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14243 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14244 operands[3], operands[7],
14245 operands[4], operands[5], operands[6], NULL_RTX);
14249 ;; %%% Kill this when reload knows how to do it.
14252 (if_then_else (match_operator 0 "comparison_operator"
14253 [(match_operator 1 "float_operator"
14254 [(match_operand:X87MODEI12 2 "register_operand" "")])
14255 (match_operand 3 "register_operand" "")])
14256 (match_operand 4 "" "")
14257 (match_operand 5 "" "")))
14258 (clobber (reg:CCFP FPSR_REG))
14259 (clobber (reg:CCFP FLAGS_REG))
14260 (clobber (match_scratch:HI 6 "=a"))]
14264 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14265 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14266 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14267 operands[3], operands[7],
14268 operands[4], operands[5], operands[6], operands[2]);
14272 ;; Unconditional and other jump instructions
14274 (define_insn "jump"
14276 (label_ref (match_operand 0 "" "")))]
14279 [(set_attr "type" "ibr")
14280 (set (attr "length")
14281 (if_then_else (and (ge (minus (match_dup 0) (pc))
14283 (lt (minus (match_dup 0) (pc))
14287 (set_attr "modrm" "0")])
14289 (define_expand "indirect_jump"
14290 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14294 (define_insn "*indirect_jump"
14295 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14298 [(set_attr "type" "ibr")
14299 (set_attr "length_immediate" "0")])
14301 (define_insn "*indirect_jump_rtx64"
14302 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14305 [(set_attr "type" "ibr")
14306 (set_attr "length_immediate" "0")])
14308 (define_expand "tablejump"
14309 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14310 (use (label_ref (match_operand 1 "" "")))])]
14313 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14314 relative. Convert the relative address to an absolute address. */
14318 enum rtx_code code;
14324 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14326 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14330 op1 = pic_offset_table_rtx;
14335 op0 = pic_offset_table_rtx;
14339 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14344 (define_insn "*tablejump_1"
14345 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14346 (use (label_ref (match_operand 1 "" "")))]
14349 [(set_attr "type" "ibr")
14350 (set_attr "length_immediate" "0")])
14352 (define_insn "*tablejump_1_rtx64"
14353 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14354 (use (label_ref (match_operand 1 "" "")))]
14357 [(set_attr "type" "ibr")
14358 (set_attr "length_immediate" "0")])
14360 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14363 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14364 (set (match_operand:QI 1 "register_operand" "")
14365 (match_operator:QI 2 "ix86_comparison_operator"
14366 [(reg FLAGS_REG) (const_int 0)]))
14367 (set (match_operand 3 "q_regs_operand" "")
14368 (zero_extend (match_dup 1)))]
14369 "(peep2_reg_dead_p (3, operands[1])
14370 || operands_match_p (operands[1], operands[3]))
14371 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14372 [(set (match_dup 4) (match_dup 0))
14373 (set (strict_low_part (match_dup 5))
14376 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14377 operands[5] = gen_lowpart (QImode, operands[3]);
14378 ix86_expand_clear (operands[3]);
14381 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14384 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14385 (set (match_operand:QI 1 "register_operand" "")
14386 (match_operator:QI 2 "ix86_comparison_operator"
14387 [(reg FLAGS_REG) (const_int 0)]))
14388 (parallel [(set (match_operand 3 "q_regs_operand" "")
14389 (zero_extend (match_dup 1)))
14390 (clobber (reg:CC FLAGS_REG))])]
14391 "(peep2_reg_dead_p (3, operands[1])
14392 || operands_match_p (operands[1], operands[3]))
14393 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14394 [(set (match_dup 4) (match_dup 0))
14395 (set (strict_low_part (match_dup 5))
14398 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14399 operands[5] = gen_lowpart (QImode, operands[3]);
14400 ix86_expand_clear (operands[3]);
14403 ;; Call instructions.
14405 ;; The predicates normally associated with named expanders are not properly
14406 ;; checked for calls. This is a bug in the generic code, but it isn't that
14407 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14409 ;; Call subroutine returning no value.
14411 (define_expand "call_pop"
14412 [(parallel [(call (match_operand:QI 0 "" "")
14413 (match_operand:SI 1 "" ""))
14414 (set (reg:SI SP_REG)
14415 (plus:SI (reg:SI SP_REG)
14416 (match_operand:SI 3 "" "")))])]
14419 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14423 (define_insn "*call_pop_0"
14424 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14425 (match_operand:SI 1 "" ""))
14426 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14427 (match_operand:SI 2 "immediate_operand" "")))]
14430 if (SIBLING_CALL_P (insn))
14433 return "call\t%P0";
14435 [(set_attr "type" "call")])
14437 (define_insn "*call_pop_1"
14438 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14439 (match_operand:SI 1 "" ""))
14440 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14441 (match_operand:SI 2 "immediate_operand" "i")))]
14444 if (constant_call_address_operand (operands[0], Pmode))
14446 if (SIBLING_CALL_P (insn))
14449 return "call\t%P0";
14451 if (SIBLING_CALL_P (insn))
14454 return "call\t%A0";
14456 [(set_attr "type" "call")])
14458 (define_expand "call"
14459 [(call (match_operand:QI 0 "" "")
14460 (match_operand 1 "" ""))
14461 (use (match_operand 2 "" ""))]
14464 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14468 (define_expand "sibcall"
14469 [(call (match_operand:QI 0 "" "")
14470 (match_operand 1 "" ""))
14471 (use (match_operand 2 "" ""))]
14474 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14478 (define_insn "*call_0"
14479 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14480 (match_operand 1 "" ""))]
14483 if (SIBLING_CALL_P (insn))
14486 return "call\t%P0";
14488 [(set_attr "type" "call")])
14490 (define_insn "*call_1"
14491 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14492 (match_operand 1 "" ""))]
14493 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14495 if (constant_call_address_operand (operands[0], Pmode))
14496 return "call\t%P0";
14497 return "call\t%A0";
14499 [(set_attr "type" "call")])
14501 (define_insn "*sibcall_1"
14502 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14503 (match_operand 1 "" ""))]
14504 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14506 if (constant_call_address_operand (operands[0], Pmode))
14510 [(set_attr "type" "call")])
14512 (define_insn "*call_1_rex64"
14513 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14514 (match_operand 1 "" ""))]
14515 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14517 if (constant_call_address_operand (operands[0], Pmode))
14518 return "call\t%P0";
14519 return "call\t%A0";
14521 [(set_attr "type" "call")])
14523 (define_insn "*sibcall_1_rex64"
14524 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14525 (match_operand 1 "" ""))]
14526 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14528 [(set_attr "type" "call")])
14530 (define_insn "*sibcall_1_rex64_v"
14531 [(call (mem:QI (reg:DI R11_REG))
14532 (match_operand 0 "" ""))]
14533 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14535 [(set_attr "type" "call")])
14538 ;; Call subroutine, returning value in operand 0
14540 (define_expand "call_value_pop"
14541 [(parallel [(set (match_operand 0 "" "")
14542 (call (match_operand:QI 1 "" "")
14543 (match_operand:SI 2 "" "")))
14544 (set (reg:SI SP_REG)
14545 (plus:SI (reg:SI SP_REG)
14546 (match_operand:SI 4 "" "")))])]
14549 ix86_expand_call (operands[0], operands[1], operands[2],
14550 operands[3], operands[4], 0);
14554 (define_expand "call_value"
14555 [(set (match_operand 0 "" "")
14556 (call (match_operand:QI 1 "" "")
14557 (match_operand:SI 2 "" "")))
14558 (use (match_operand:SI 3 "" ""))]
14559 ;; Operand 2 not used on the i386.
14562 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14566 (define_expand "sibcall_value"
14567 [(set (match_operand 0 "" "")
14568 (call (match_operand:QI 1 "" "")
14569 (match_operand:SI 2 "" "")))
14570 (use (match_operand:SI 3 "" ""))]
14571 ;; Operand 2 not used on the i386.
14574 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14578 ;; Call subroutine returning any type.
14580 (define_expand "untyped_call"
14581 [(parallel [(call (match_operand 0 "" "")
14583 (match_operand 1 "" "")
14584 (match_operand 2 "" "")])]
14589 /* In order to give reg-stack an easier job in validating two
14590 coprocessor registers as containing a possible return value,
14591 simply pretend the untyped call returns a complex long double
14594 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14595 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14596 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14599 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14601 rtx set = XVECEXP (operands[2], 0, i);
14602 emit_move_insn (SET_DEST (set), SET_SRC (set));
14605 /* The optimizer does not know that the call sets the function value
14606 registers we stored in the result block. We avoid problems by
14607 claiming that all hard registers are used and clobbered at this
14609 emit_insn (gen_blockage (const0_rtx));
14614 ;; Prologue and epilogue instructions
14616 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14617 ;; all of memory. This blocks insns from being moved across this point.
14619 (define_insn "blockage"
14620 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14623 [(set_attr "length" "0")])
14625 ;; Insn emitted into the body of a function to return from a function.
14626 ;; This is only done if the function's epilogue is known to be simple.
14627 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14629 (define_expand "return"
14631 "ix86_can_use_return_insn_p ()"
14633 if (current_function_pops_args)
14635 rtx popc = GEN_INT (current_function_pops_args);
14636 emit_jump_insn (gen_return_pop_internal (popc));
14641 (define_insn "return_internal"
14645 [(set_attr "length" "1")
14646 (set_attr "length_immediate" "0")
14647 (set_attr "modrm" "0")])
14649 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14650 ;; instruction Athlon and K8 have.
14652 (define_insn "return_internal_long"
14654 (unspec [(const_int 0)] UNSPEC_REP)]
14657 [(set_attr "length" "1")
14658 (set_attr "length_immediate" "0")
14659 (set_attr "prefix_rep" "1")
14660 (set_attr "modrm" "0")])
14662 (define_insn "return_pop_internal"
14664 (use (match_operand:SI 0 "const_int_operand" ""))]
14667 [(set_attr "length" "3")
14668 (set_attr "length_immediate" "2")
14669 (set_attr "modrm" "0")])
14671 (define_insn "return_indirect_internal"
14673 (use (match_operand:SI 0 "register_operand" "r"))]
14676 [(set_attr "type" "ibr")
14677 (set_attr "length_immediate" "0")])
14683 [(set_attr "length" "1")
14684 (set_attr "length_immediate" "0")
14685 (set_attr "modrm" "0")])
14687 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14688 ;; branch prediction penalty for the third jump in a 16-byte
14691 (define_insn "align"
14692 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14695 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14696 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14698 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14699 The align insn is used to avoid 3 jump instructions in the row to improve
14700 branch prediction and the benefits hardly outweigh the cost of extra 8
14701 nops on the average inserted by full alignment pseudo operation. */
14705 [(set_attr "length" "16")])
14707 (define_expand "prologue"
14710 "ix86_expand_prologue (); DONE;")
14712 (define_insn "set_got"
14713 [(set (match_operand:SI 0 "register_operand" "=r")
14714 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14715 (clobber (reg:CC FLAGS_REG))]
14717 { return output_set_got (operands[0], NULL_RTX); }
14718 [(set_attr "type" "multi")
14719 (set_attr "length" "12")])
14721 (define_insn "set_got_labelled"
14722 [(set (match_operand:SI 0 "register_operand" "=r")
14723 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14725 (clobber (reg:CC FLAGS_REG))]
14727 { return output_set_got (operands[0], operands[1]); }
14728 [(set_attr "type" "multi")
14729 (set_attr "length" "12")])
14731 (define_insn "set_got_rex64"
14732 [(set (match_operand:DI 0 "register_operand" "=r")
14733 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14735 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14736 [(set_attr "type" "lea")
14737 (set_attr "length" "6")])
14739 (define_expand "epilogue"
14742 "ix86_expand_epilogue (1); DONE;")
14744 (define_expand "sibcall_epilogue"
14747 "ix86_expand_epilogue (0); DONE;")
14749 (define_expand "eh_return"
14750 [(use (match_operand 0 "register_operand" ""))]
14753 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14755 /* Tricky bit: we write the address of the handler to which we will
14756 be returning into someone else's stack frame, one word below the
14757 stack address we wish to restore. */
14758 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14759 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14760 tmp = gen_rtx_MEM (Pmode, tmp);
14761 emit_move_insn (tmp, ra);
14763 if (Pmode == SImode)
14764 emit_jump_insn (gen_eh_return_si (sa));
14766 emit_jump_insn (gen_eh_return_di (sa));
14771 (define_insn_and_split "eh_return_si"
14773 (unspec [(match_operand:SI 0 "register_operand" "c")]
14774 UNSPEC_EH_RETURN))]
14779 "ix86_expand_epilogue (2); DONE;")
14781 (define_insn_and_split "eh_return_di"
14783 (unspec [(match_operand:DI 0 "register_operand" "c")]
14784 UNSPEC_EH_RETURN))]
14789 "ix86_expand_epilogue (2); DONE;")
14791 (define_insn "leave"
14792 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14793 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14794 (clobber (mem:BLK (scratch)))]
14797 [(set_attr "type" "leave")])
14799 (define_insn "leave_rex64"
14800 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14801 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14802 (clobber (mem:BLK (scratch)))]
14805 [(set_attr "type" "leave")])
14807 (define_expand "ffssi2"
14809 [(set (match_operand:SI 0 "register_operand" "")
14810 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14811 (clobber (match_scratch:SI 2 ""))
14812 (clobber (reg:CC FLAGS_REG))])]
14816 (define_insn_and_split "*ffs_cmove"
14817 [(set (match_operand:SI 0 "register_operand" "=r")
14818 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14819 (clobber (match_scratch:SI 2 "=&r"))
14820 (clobber (reg:CC FLAGS_REG))]
14823 "&& reload_completed"
14824 [(set (match_dup 2) (const_int -1))
14825 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14826 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14827 (set (match_dup 0) (if_then_else:SI
14828 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14831 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14832 (clobber (reg:CC FLAGS_REG))])]
14835 (define_insn_and_split "*ffs_no_cmove"
14836 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14837 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14838 (clobber (match_scratch:SI 2 "=&q"))
14839 (clobber (reg:CC FLAGS_REG))]
14843 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14844 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14845 (set (strict_low_part (match_dup 3))
14846 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14847 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14848 (clobber (reg:CC FLAGS_REG))])
14849 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14850 (clobber (reg:CC FLAGS_REG))])
14851 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14852 (clobber (reg:CC FLAGS_REG))])]
14854 operands[3] = gen_lowpart (QImode, operands[2]);
14855 ix86_expand_clear (operands[2]);
14858 (define_insn "*ffssi_1"
14859 [(set (reg:CCZ FLAGS_REG)
14860 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14862 (set (match_operand:SI 0 "register_operand" "=r")
14863 (ctz:SI (match_dup 1)))]
14865 "bsf{l}\t{%1, %0|%0, %1}"
14866 [(set_attr "prefix_0f" "1")])
14868 (define_expand "ffsdi2"
14870 [(set (match_operand:DI 0 "register_operand" "")
14871 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14872 (clobber (match_scratch:DI 2 ""))
14873 (clobber (reg:CC FLAGS_REG))])]
14874 "TARGET_64BIT && TARGET_CMOVE"
14877 (define_insn_and_split "*ffs_rex64"
14878 [(set (match_operand:DI 0 "register_operand" "=r")
14879 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14880 (clobber (match_scratch:DI 2 "=&r"))
14881 (clobber (reg:CC FLAGS_REG))]
14882 "TARGET_64BIT && TARGET_CMOVE"
14884 "&& reload_completed"
14885 [(set (match_dup 2) (const_int -1))
14886 (parallel [(set (reg:CCZ FLAGS_REG)
14887 (compare:CCZ (match_dup 1) (const_int 0)))
14888 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14889 (set (match_dup 0) (if_then_else:DI
14890 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14893 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14894 (clobber (reg:CC FLAGS_REG))])]
14897 (define_insn "*ffsdi_1"
14898 [(set (reg:CCZ FLAGS_REG)
14899 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14901 (set (match_operand:DI 0 "register_operand" "=r")
14902 (ctz:DI (match_dup 1)))]
14904 "bsf{q}\t{%1, %0|%0, %1}"
14905 [(set_attr "prefix_0f" "1")])
14907 (define_insn "ctzsi2"
14908 [(set (match_operand:SI 0 "register_operand" "=r")
14909 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14910 (clobber (reg:CC FLAGS_REG))]
14912 "bsf{l}\t{%1, %0|%0, %1}"
14913 [(set_attr "prefix_0f" "1")])
14915 (define_insn "ctzdi2"
14916 [(set (match_operand:DI 0 "register_operand" "=r")
14917 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14918 (clobber (reg:CC FLAGS_REG))]
14920 "bsf{q}\t{%1, %0|%0, %1}"
14921 [(set_attr "prefix_0f" "1")])
14923 (define_expand "clzsi2"
14925 [(set (match_operand:SI 0 "register_operand" "")
14926 (minus:SI (const_int 31)
14927 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14928 (clobber (reg:CC FLAGS_REG))])
14930 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14931 (clobber (reg:CC FLAGS_REG))])]
14936 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14941 (define_insn "clzsi2_abm"
14942 [(set (match_operand:SI 0 "register_operand" "=r")
14943 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14944 (clobber (reg:CC FLAGS_REG))]
14946 "lzcnt{l}\t{%1, %0|%0, %1}"
14947 [(set_attr "prefix_rep" "1")
14948 (set_attr "type" "bitmanip")
14949 (set_attr "mode" "SI")])
14951 (define_insn "*bsr"
14952 [(set (match_operand:SI 0 "register_operand" "=r")
14953 (minus:SI (const_int 31)
14954 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14955 (clobber (reg:CC FLAGS_REG))]
14957 "bsr{l}\t{%1, %0|%0, %1}"
14958 [(set_attr "prefix_0f" "1")
14959 (set_attr "mode" "SI")])
14961 (define_insn "popcountsi2"
14962 [(set (match_operand:SI 0 "register_operand" "=r")
14963 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14964 (clobber (reg:CC FLAGS_REG))]
14966 "popcnt{l}\t{%1, %0|%0, %1}"
14967 [(set_attr "prefix_rep" "1")
14968 (set_attr "type" "bitmanip")
14969 (set_attr "mode" "SI")])
14971 (define_insn "*popcountsi2_cmp"
14972 [(set (reg FLAGS_REG)
14974 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14976 (set (match_operand:SI 0 "register_operand" "=r")
14977 (popcount:SI (match_dup 1)))]
14978 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14979 "popcnt{l}\t{%1, %0|%0, %1}"
14980 [(set_attr "prefix_rep" "1")
14981 (set_attr "type" "bitmanip")
14982 (set_attr "mode" "SI")])
14984 (define_insn "*popcountsi2_cmp_zext"
14985 [(set (reg FLAGS_REG)
14987 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14989 (set (match_operand:DI 0 "register_operand" "=r")
14990 (zero_extend:DI(popcount:SI (match_dup 1))))]
14991 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14992 "popcnt{l}\t{%1, %0|%0, %1}"
14993 [(set_attr "prefix_rep" "1")
14994 (set_attr "type" "bitmanip")
14995 (set_attr "mode" "SI")])
14997 (define_insn "bswapsi2"
14998 [(set (match_operand:SI 0 "register_operand" "=r")
14999 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
15000 (clobber (reg:CC FLAGS_REG))]
15003 [(set_attr "prefix_0f" "1")
15004 (set_attr "length" "2")])
15006 (define_insn "*bswapdi2_rex"
15007 [(set (match_operand:DI 0 "register_operand" "=r")
15008 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
15009 (clobber (reg:CC FLAGS_REG))]
15010 "TARGET_64BIT && TARGET_BSWAP"
15012 [(set_attr "prefix_0f" "1")
15013 (set_attr "length" "3")])
15015 (define_expand "bswapdi2"
15016 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15017 (bswap:DI (match_operand:DI 1 "register_operand" "")))
15018 (clobber (reg:CC FLAGS_REG))])]
15024 tmp1 = gen_reg_rtx (SImode);
15025 tmp2 = gen_reg_rtx (SImode);
15026 emit_insn (gen_bswapsi2 (tmp1, gen_lowpart (SImode, operands[1])));
15027 emit_insn (gen_bswapsi2 (tmp2, gen_highpart (SImode, operands[1])));
15028 emit_move_insn (gen_lowpart (SImode, operands[0]), tmp2);
15029 emit_move_insn (gen_highpart (SImode, operands[0]), tmp1);
15034 (define_expand "clzdi2"
15036 [(set (match_operand:DI 0 "register_operand" "")
15037 (minus:DI (const_int 63)
15038 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15039 (clobber (reg:CC FLAGS_REG))])
15041 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15042 (clobber (reg:CC FLAGS_REG))])]
15047 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15052 (define_insn "clzdi2_abm"
15053 [(set (match_operand:DI 0 "register_operand" "=r")
15054 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15055 (clobber (reg:CC FLAGS_REG))]
15056 "TARGET_64BIT && TARGET_ABM"
15057 "lzcnt{q}\t{%1, %0|%0, %1}"
15058 [(set_attr "prefix_rep" "1")
15059 (set_attr "type" "bitmanip")
15060 (set_attr "mode" "DI")])
15062 (define_insn "*bsr_rex64"
15063 [(set (match_operand:DI 0 "register_operand" "=r")
15064 (minus:DI (const_int 63)
15065 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15066 (clobber (reg:CC FLAGS_REG))]
15068 "bsr{q}\t{%1, %0|%0, %1}"
15069 [(set_attr "prefix_0f" "1")
15070 (set_attr "mode" "DI")])
15072 (define_insn "popcountdi2"
15073 [(set (match_operand:DI 0 "register_operand" "=r")
15074 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15075 (clobber (reg:CC FLAGS_REG))]
15076 "TARGET_64BIT && TARGET_POPCNT"
15077 "popcnt{q}\t{%1, %0|%0, %1}"
15078 [(set_attr "prefix_rep" "1")
15079 (set_attr "type" "bitmanip")
15080 (set_attr "mode" "DI")])
15082 (define_insn "*popcountdi2_cmp"
15083 [(set (reg FLAGS_REG)
15085 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15087 (set (match_operand:DI 0 "register_operand" "=r")
15088 (popcount:DI (match_dup 1)))]
15089 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15090 "popcnt{q}\t{%1, %0|%0, %1}"
15091 [(set_attr "prefix_rep" "1")
15092 (set_attr "type" "bitmanip")
15093 (set_attr "mode" "DI")])
15095 (define_expand "clzhi2"
15097 [(set (match_operand:HI 0 "register_operand" "")
15098 (minus:HI (const_int 15)
15099 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15100 (clobber (reg:CC FLAGS_REG))])
15102 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15103 (clobber (reg:CC FLAGS_REG))])]
15108 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15113 (define_insn "clzhi2_abm"
15114 [(set (match_operand:HI 0 "register_operand" "=r")
15115 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15116 (clobber (reg:CC FLAGS_REG))]
15118 "lzcnt{w}\t{%1, %0|%0, %1}"
15119 [(set_attr "prefix_rep" "1")
15120 (set_attr "type" "bitmanip")
15121 (set_attr "mode" "HI")])
15123 (define_insn "*bsrhi"
15124 [(set (match_operand:HI 0 "register_operand" "=r")
15125 (minus:HI (const_int 15)
15126 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15127 (clobber (reg:CC FLAGS_REG))]
15129 "bsr{w}\t{%1, %0|%0, %1}"
15130 [(set_attr "prefix_0f" "1")
15131 (set_attr "mode" "HI")])
15133 (define_insn "popcounthi2"
15134 [(set (match_operand:HI 0 "register_operand" "=r")
15135 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15136 (clobber (reg:CC FLAGS_REG))]
15138 "popcnt{w}\t{%1, %0|%0, %1}"
15139 [(set_attr "prefix_rep" "1")
15140 (set_attr "type" "bitmanip")
15141 (set_attr "mode" "HI")])
15143 (define_insn "*popcounthi2_cmp"
15144 [(set (reg FLAGS_REG)
15146 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15148 (set (match_operand:HI 0 "register_operand" "=r")
15149 (popcount:HI (match_dup 1)))]
15150 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15151 "popcnt{w}\t{%1, %0|%0, %1}"
15152 [(set_attr "prefix_rep" "1")
15153 (set_attr "type" "bitmanip")
15154 (set_attr "mode" "HI")])
15156 (define_expand "paritydi2"
15157 [(set (match_operand:DI 0 "register_operand" "")
15158 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15161 rtx scratch = gen_reg_rtx (QImode);
15164 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15165 NULL_RTX, operands[1]));
15167 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15168 gen_rtx_REG (CCmode, FLAGS_REG),
15170 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15173 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15176 rtx tmp = gen_reg_rtx (SImode);
15178 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15179 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15184 (define_insn_and_split "paritydi2_cmp"
15185 [(set (reg:CC FLAGS_REG)
15186 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15187 (clobber (match_scratch:DI 0 "=r,X"))
15188 (clobber (match_scratch:SI 1 "=r,r"))
15189 (clobber (match_scratch:HI 2 "=Q,Q"))]
15192 "&& reload_completed"
15194 [(set (match_dup 1)
15195 (xor:SI (match_dup 1) (match_dup 4)))
15196 (clobber (reg:CC FLAGS_REG))])
15198 [(set (reg:CC FLAGS_REG)
15199 (parity:CC (match_dup 1)))
15200 (clobber (match_dup 1))
15201 (clobber (match_dup 2))])]
15203 operands[4] = gen_lowpart (SImode, operands[3]);
15205 if (MEM_P (operands[3]))
15206 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15207 else if (! TARGET_64BIT)
15208 operands[1] = gen_highpart (SImode, operands[3]);
15211 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15212 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15216 (define_expand "paritysi2"
15217 [(set (match_operand:SI 0 "register_operand" "")
15218 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15221 rtx scratch = gen_reg_rtx (QImode);
15224 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15226 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15227 gen_rtx_REG (CCmode, FLAGS_REG),
15229 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15231 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15235 (define_insn_and_split "paritysi2_cmp"
15236 [(set (reg:CC FLAGS_REG)
15237 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15238 (clobber (match_scratch:SI 0 "=r,X"))
15239 (clobber (match_scratch:HI 1 "=Q,Q"))]
15242 "&& reload_completed"
15244 [(set (match_dup 1)
15245 (xor:HI (match_dup 1) (match_dup 3)))
15246 (clobber (reg:CC FLAGS_REG))])
15248 [(set (reg:CC FLAGS_REG)
15249 (parity:CC (match_dup 1)))
15250 (clobber (match_dup 1))])]
15252 operands[3] = gen_lowpart (HImode, operands[2]);
15254 if (MEM_P (operands[2]))
15255 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15258 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15259 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15263 (define_insn "*parityhi2_cmp"
15264 [(set (reg:CC FLAGS_REG)
15265 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15266 (clobber (match_scratch:HI 0 "=Q"))]
15268 "xor{b}\t{%h0, %b0|%b0, %h0}"
15269 [(set_attr "length" "2")
15270 (set_attr "mode" "HI")])
15272 (define_insn "*parityqi2_cmp"
15273 [(set (reg:CC FLAGS_REG)
15274 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15277 [(set_attr "length" "2")
15278 (set_attr "mode" "QI")])
15280 ;; Thread-local storage patterns for ELF.
15282 ;; Note that these code sequences must appear exactly as shown
15283 ;; in order to allow linker relaxation.
15285 (define_insn "*tls_global_dynamic_32_gnu"
15286 [(set (match_operand:SI 0 "register_operand" "=a")
15287 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15288 (match_operand:SI 2 "tls_symbolic_operand" "")
15289 (match_operand:SI 3 "call_insn_operand" "")]
15291 (clobber (match_scratch:SI 4 "=d"))
15292 (clobber (match_scratch:SI 5 "=c"))
15293 (clobber (reg:CC FLAGS_REG))]
15294 "!TARGET_64BIT && TARGET_GNU_TLS"
15295 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15296 [(set_attr "type" "multi")
15297 (set_attr "length" "12")])
15299 (define_insn "*tls_global_dynamic_32_sun"
15300 [(set (match_operand:SI 0 "register_operand" "=a")
15301 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15302 (match_operand:SI 2 "tls_symbolic_operand" "")
15303 (match_operand:SI 3 "call_insn_operand" "")]
15305 (clobber (match_scratch:SI 4 "=d"))
15306 (clobber (match_scratch:SI 5 "=c"))
15307 (clobber (reg:CC FLAGS_REG))]
15308 "!TARGET_64BIT && TARGET_SUN_TLS"
15309 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15310 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15311 [(set_attr "type" "multi")
15312 (set_attr "length" "14")])
15314 (define_expand "tls_global_dynamic_32"
15315 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15318 (match_operand:SI 1 "tls_symbolic_operand" "")
15321 (clobber (match_scratch:SI 4 ""))
15322 (clobber (match_scratch:SI 5 ""))
15323 (clobber (reg:CC FLAGS_REG))])]
15327 operands[2] = pic_offset_table_rtx;
15330 operands[2] = gen_reg_rtx (Pmode);
15331 emit_insn (gen_set_got (operands[2]));
15333 if (TARGET_GNU2_TLS)
15335 emit_insn (gen_tls_dynamic_gnu2_32
15336 (operands[0], operands[1], operands[2]));
15339 operands[3] = ix86_tls_get_addr ();
15342 (define_insn "*tls_global_dynamic_64"
15343 [(set (match_operand:DI 0 "register_operand" "=a")
15344 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15345 (match_operand:DI 3 "" "")))
15346 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15349 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15350 [(set_attr "type" "multi")
15351 (set_attr "length" "16")])
15353 (define_expand "tls_global_dynamic_64"
15354 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15355 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15356 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15360 if (TARGET_GNU2_TLS)
15362 emit_insn (gen_tls_dynamic_gnu2_64
15363 (operands[0], operands[1]));
15366 operands[2] = ix86_tls_get_addr ();
15369 (define_insn "*tls_local_dynamic_base_32_gnu"
15370 [(set (match_operand:SI 0 "register_operand" "=a")
15371 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15372 (match_operand:SI 2 "call_insn_operand" "")]
15373 UNSPEC_TLS_LD_BASE))
15374 (clobber (match_scratch:SI 3 "=d"))
15375 (clobber (match_scratch:SI 4 "=c"))
15376 (clobber (reg:CC FLAGS_REG))]
15377 "!TARGET_64BIT && TARGET_GNU_TLS"
15378 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15379 [(set_attr "type" "multi")
15380 (set_attr "length" "11")])
15382 (define_insn "*tls_local_dynamic_base_32_sun"
15383 [(set (match_operand:SI 0 "register_operand" "=a")
15384 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15385 (match_operand:SI 2 "call_insn_operand" "")]
15386 UNSPEC_TLS_LD_BASE))
15387 (clobber (match_scratch:SI 3 "=d"))
15388 (clobber (match_scratch:SI 4 "=c"))
15389 (clobber (reg:CC FLAGS_REG))]
15390 "!TARGET_64BIT && TARGET_SUN_TLS"
15391 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15392 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15393 [(set_attr "type" "multi")
15394 (set_attr "length" "13")])
15396 (define_expand "tls_local_dynamic_base_32"
15397 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15398 (unspec:SI [(match_dup 1) (match_dup 2)]
15399 UNSPEC_TLS_LD_BASE))
15400 (clobber (match_scratch:SI 3 ""))
15401 (clobber (match_scratch:SI 4 ""))
15402 (clobber (reg:CC FLAGS_REG))])]
15406 operands[1] = pic_offset_table_rtx;
15409 operands[1] = gen_reg_rtx (Pmode);
15410 emit_insn (gen_set_got (operands[1]));
15412 if (TARGET_GNU2_TLS)
15414 emit_insn (gen_tls_dynamic_gnu2_32
15415 (operands[0], ix86_tls_module_base (), operands[1]));
15418 operands[2] = ix86_tls_get_addr ();
15421 (define_insn "*tls_local_dynamic_base_64"
15422 [(set (match_operand:DI 0 "register_operand" "=a")
15423 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15424 (match_operand:DI 2 "" "")))
15425 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15427 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15428 [(set_attr "type" "multi")
15429 (set_attr "length" "12")])
15431 (define_expand "tls_local_dynamic_base_64"
15432 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15433 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15434 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15437 if (TARGET_GNU2_TLS)
15439 emit_insn (gen_tls_dynamic_gnu2_64
15440 (operands[0], ix86_tls_module_base ()));
15443 operands[1] = ix86_tls_get_addr ();
15446 ;; Local dynamic of a single variable is a lose. Show combine how
15447 ;; to convert that back to global dynamic.
15449 (define_insn_and_split "*tls_local_dynamic_32_once"
15450 [(set (match_operand:SI 0 "register_operand" "=a")
15451 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15452 (match_operand:SI 2 "call_insn_operand" "")]
15453 UNSPEC_TLS_LD_BASE)
15454 (const:SI (unspec:SI
15455 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15457 (clobber (match_scratch:SI 4 "=d"))
15458 (clobber (match_scratch:SI 5 "=c"))
15459 (clobber (reg:CC FLAGS_REG))]
15463 [(parallel [(set (match_dup 0)
15464 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15466 (clobber (match_dup 4))
15467 (clobber (match_dup 5))
15468 (clobber (reg:CC FLAGS_REG))])]
15471 ;; Load and add the thread base pointer from %gs:0.
15473 (define_insn "*load_tp_si"
15474 [(set (match_operand:SI 0 "register_operand" "=r")
15475 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15477 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15478 [(set_attr "type" "imov")
15479 (set_attr "modrm" "0")
15480 (set_attr "length" "7")
15481 (set_attr "memory" "load")
15482 (set_attr "imm_disp" "false")])
15484 (define_insn "*add_tp_si"
15485 [(set (match_operand:SI 0 "register_operand" "=r")
15486 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15487 (match_operand:SI 1 "register_operand" "0")))
15488 (clobber (reg:CC FLAGS_REG))]
15490 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15491 [(set_attr "type" "alu")
15492 (set_attr "modrm" "0")
15493 (set_attr "length" "7")
15494 (set_attr "memory" "load")
15495 (set_attr "imm_disp" "false")])
15497 (define_insn "*load_tp_di"
15498 [(set (match_operand:DI 0 "register_operand" "=r")
15499 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15501 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15502 [(set_attr "type" "imov")
15503 (set_attr "modrm" "0")
15504 (set_attr "length" "7")
15505 (set_attr "memory" "load")
15506 (set_attr "imm_disp" "false")])
15508 (define_insn "*add_tp_di"
15509 [(set (match_operand:DI 0 "register_operand" "=r")
15510 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15511 (match_operand:DI 1 "register_operand" "0")))
15512 (clobber (reg:CC FLAGS_REG))]
15514 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15515 [(set_attr "type" "alu")
15516 (set_attr "modrm" "0")
15517 (set_attr "length" "7")
15518 (set_attr "memory" "load")
15519 (set_attr "imm_disp" "false")])
15521 ;; GNU2 TLS patterns can be split.
15523 (define_expand "tls_dynamic_gnu2_32"
15524 [(set (match_dup 3)
15525 (plus:SI (match_operand:SI 2 "register_operand" "")
15527 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15530 [(set (match_operand:SI 0 "register_operand" "")
15531 (unspec:SI [(match_dup 1) (match_dup 3)
15532 (match_dup 2) (reg:SI SP_REG)]
15534 (clobber (reg:CC FLAGS_REG))])]
15535 "!TARGET_64BIT && TARGET_GNU2_TLS"
15537 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15538 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15541 (define_insn "*tls_dynamic_lea_32"
15542 [(set (match_operand:SI 0 "register_operand" "=r")
15543 (plus:SI (match_operand:SI 1 "register_operand" "b")
15545 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15546 UNSPEC_TLSDESC))))]
15547 "!TARGET_64BIT && TARGET_GNU2_TLS"
15548 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15549 [(set_attr "type" "lea")
15550 (set_attr "mode" "SI")
15551 (set_attr "length" "6")
15552 (set_attr "length_address" "4")])
15554 (define_insn "*tls_dynamic_call_32"
15555 [(set (match_operand:SI 0 "register_operand" "=a")
15556 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15557 (match_operand:SI 2 "register_operand" "0")
15558 ;; we have to make sure %ebx still points to the GOT
15559 (match_operand:SI 3 "register_operand" "b")
15562 (clobber (reg:CC FLAGS_REG))]
15563 "!TARGET_64BIT && TARGET_GNU2_TLS"
15564 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15565 [(set_attr "type" "call")
15566 (set_attr "length" "2")
15567 (set_attr "length_address" "0")])
15569 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15570 [(set (match_operand:SI 0 "register_operand" "=&a")
15572 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15573 (match_operand:SI 4 "" "")
15574 (match_operand:SI 2 "register_operand" "b")
15577 (const:SI (unspec:SI
15578 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15580 (clobber (reg:CC FLAGS_REG))]
15581 "!TARGET_64BIT && TARGET_GNU2_TLS"
15584 [(set (match_dup 0) (match_dup 5))]
15586 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15587 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15590 (define_expand "tls_dynamic_gnu2_64"
15591 [(set (match_dup 2)
15592 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15595 [(set (match_operand:DI 0 "register_operand" "")
15596 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15598 (clobber (reg:CC FLAGS_REG))])]
15599 "TARGET_64BIT && TARGET_GNU2_TLS"
15601 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15602 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15605 (define_insn "*tls_dynamic_lea_64"
15606 [(set (match_operand:DI 0 "register_operand" "=r")
15607 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15609 "TARGET_64BIT && TARGET_GNU2_TLS"
15610 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15611 [(set_attr "type" "lea")
15612 (set_attr "mode" "DI")
15613 (set_attr "length" "7")
15614 (set_attr "length_address" "4")])
15616 (define_insn "*tls_dynamic_call_64"
15617 [(set (match_operand:DI 0 "register_operand" "=a")
15618 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15619 (match_operand:DI 2 "register_operand" "0")
15622 (clobber (reg:CC FLAGS_REG))]
15623 "TARGET_64BIT && TARGET_GNU2_TLS"
15624 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15625 [(set_attr "type" "call")
15626 (set_attr "length" "2")
15627 (set_attr "length_address" "0")])
15629 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15630 [(set (match_operand:DI 0 "register_operand" "=&a")
15632 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15633 (match_operand:DI 3 "" "")
15636 (const:DI (unspec:DI
15637 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15639 (clobber (reg:CC FLAGS_REG))]
15640 "TARGET_64BIT && TARGET_GNU2_TLS"
15643 [(set (match_dup 0) (match_dup 4))]
15645 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15646 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15651 ;; These patterns match the binary 387 instructions for addM3, subM3,
15652 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15653 ;; SFmode. The first is the normal insn, the second the same insn but
15654 ;; with one operand a conversion, and the third the same insn but with
15655 ;; the other operand a conversion. The conversion may be SFmode or
15656 ;; SImode if the target mode DFmode, but only SImode if the target mode
15659 ;; Gcc is slightly more smart about handling normal two address instructions
15660 ;; so use special patterns for add and mull.
15662 (define_insn "*fop_sf_comm_mixed"
15663 [(set (match_operand:SF 0 "register_operand" "=f,x")
15664 (match_operator:SF 3 "binary_fp_operator"
15665 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15666 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15667 "TARGET_MIX_SSE_I387
15668 && COMMUTATIVE_ARITH_P (operands[3])
15669 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15670 "* return output_387_binary_op (insn, operands);"
15671 [(set (attr "type")
15672 (if_then_else (eq_attr "alternative" "1")
15673 (if_then_else (match_operand:SF 3 "mult_operator" "")
15674 (const_string "ssemul")
15675 (const_string "sseadd"))
15676 (if_then_else (match_operand:SF 3 "mult_operator" "")
15677 (const_string "fmul")
15678 (const_string "fop"))))
15679 (set_attr "mode" "SF")])
15681 (define_insn "*fop_sf_comm_sse"
15682 [(set (match_operand:SF 0 "register_operand" "=x")
15683 (match_operator:SF 3 "binary_fp_operator"
15684 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15685 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15687 && COMMUTATIVE_ARITH_P (operands[3])
15688 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15689 "* return output_387_binary_op (insn, operands);"
15690 [(set (attr "type")
15691 (if_then_else (match_operand:SF 3 "mult_operator" "")
15692 (const_string "ssemul")
15693 (const_string "sseadd")))
15694 (set_attr "mode" "SF")])
15696 (define_insn "*fop_sf_comm_i387"
15697 [(set (match_operand:SF 0 "register_operand" "=f")
15698 (match_operator:SF 3 "binary_fp_operator"
15699 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15700 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15702 && COMMUTATIVE_ARITH_P (operands[3])
15703 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15704 "* return output_387_binary_op (insn, operands);"
15705 [(set (attr "type")
15706 (if_then_else (match_operand:SF 3 "mult_operator" "")
15707 (const_string "fmul")
15708 (const_string "fop")))
15709 (set_attr "mode" "SF")])
15711 (define_insn "*fop_sf_1_mixed"
15712 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15713 (match_operator:SF 3 "binary_fp_operator"
15714 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15715 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15716 "TARGET_MIX_SSE_I387
15717 && !COMMUTATIVE_ARITH_P (operands[3])
15718 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15719 "* return output_387_binary_op (insn, operands);"
15720 [(set (attr "type")
15721 (cond [(and (eq_attr "alternative" "2")
15722 (match_operand:SF 3 "mult_operator" ""))
15723 (const_string "ssemul")
15724 (and (eq_attr "alternative" "2")
15725 (match_operand:SF 3 "div_operator" ""))
15726 (const_string "ssediv")
15727 (eq_attr "alternative" "2")
15728 (const_string "sseadd")
15729 (match_operand:SF 3 "mult_operator" "")
15730 (const_string "fmul")
15731 (match_operand:SF 3 "div_operator" "")
15732 (const_string "fdiv")
15734 (const_string "fop")))
15735 (set_attr "mode" "SF")])
15737 (define_insn "*fop_sf_1_sse"
15738 [(set (match_operand:SF 0 "register_operand" "=x")
15739 (match_operator:SF 3 "binary_fp_operator"
15740 [(match_operand:SF 1 "register_operand" "0")
15741 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15743 && !COMMUTATIVE_ARITH_P (operands[3])"
15744 "* return output_387_binary_op (insn, operands);"
15745 [(set (attr "type")
15746 (cond [(match_operand:SF 3 "mult_operator" "")
15747 (const_string "ssemul")
15748 (match_operand:SF 3 "div_operator" "")
15749 (const_string "ssediv")
15751 (const_string "sseadd")))
15752 (set_attr "mode" "SF")])
15754 ;; This pattern is not fully shadowed by the pattern above.
15755 (define_insn "*fop_sf_1_i387"
15756 [(set (match_operand:SF 0 "register_operand" "=f,f")
15757 (match_operator:SF 3 "binary_fp_operator"
15758 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15759 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15760 "TARGET_80387 && !TARGET_SSE_MATH
15761 && !COMMUTATIVE_ARITH_P (operands[3])
15762 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15763 "* return output_387_binary_op (insn, operands);"
15764 [(set (attr "type")
15765 (cond [(match_operand:SF 3 "mult_operator" "")
15766 (const_string "fmul")
15767 (match_operand:SF 3 "div_operator" "")
15768 (const_string "fdiv")
15770 (const_string "fop")))
15771 (set_attr "mode" "SF")])
15773 ;; ??? Add SSE splitters for these!
15774 (define_insn "*fop_sf_2<mode>_i387"
15775 [(set (match_operand:SF 0 "register_operand" "=f,f")
15776 (match_operator:SF 3 "binary_fp_operator"
15777 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15778 (match_operand:SF 2 "register_operand" "0,0")]))]
15779 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15780 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15781 [(set (attr "type")
15782 (cond [(match_operand:SF 3 "mult_operator" "")
15783 (const_string "fmul")
15784 (match_operand:SF 3 "div_operator" "")
15785 (const_string "fdiv")
15787 (const_string "fop")))
15788 (set_attr "fp_int_src" "true")
15789 (set_attr "mode" "<MODE>")])
15791 (define_insn "*fop_sf_3<mode>_i387"
15792 [(set (match_operand:SF 0 "register_operand" "=f,f")
15793 (match_operator:SF 3 "binary_fp_operator"
15794 [(match_operand:SF 1 "register_operand" "0,0")
15795 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15796 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15797 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15798 [(set (attr "type")
15799 (cond [(match_operand:SF 3 "mult_operator" "")
15800 (const_string "fmul")
15801 (match_operand:SF 3 "div_operator" "")
15802 (const_string "fdiv")
15804 (const_string "fop")))
15805 (set_attr "fp_int_src" "true")
15806 (set_attr "mode" "<MODE>")])
15808 (define_insn "*fop_df_comm_mixed"
15809 [(set (match_operand:DF 0 "register_operand" "=f,x")
15810 (match_operator:DF 3 "binary_fp_operator"
15811 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15812 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15813 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15814 && COMMUTATIVE_ARITH_P (operands[3])
15815 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15816 "* return output_387_binary_op (insn, operands);"
15817 [(set (attr "type")
15818 (if_then_else (eq_attr "alternative" "1")
15819 (if_then_else (match_operand:DF 3 "mult_operator" "")
15820 (const_string "ssemul")
15821 (const_string "sseadd"))
15822 (if_then_else (match_operand:DF 3 "mult_operator" "")
15823 (const_string "fmul")
15824 (const_string "fop"))))
15825 (set_attr "mode" "DF")])
15827 (define_insn "*fop_df_comm_sse"
15828 [(set (match_operand:DF 0 "register_operand" "=x")
15829 (match_operator:DF 3 "binary_fp_operator"
15830 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15831 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15832 "TARGET_SSE2 && TARGET_SSE_MATH
15833 && COMMUTATIVE_ARITH_P (operands[3])
15834 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15835 "* return output_387_binary_op (insn, operands);"
15836 [(set (attr "type")
15837 (if_then_else (match_operand:DF 3 "mult_operator" "")
15838 (const_string "ssemul")
15839 (const_string "sseadd")))
15840 (set_attr "mode" "DF")])
15842 (define_insn "*fop_df_comm_i387"
15843 [(set (match_operand:DF 0 "register_operand" "=f")
15844 (match_operator:DF 3 "binary_fp_operator"
15845 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15846 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15848 && COMMUTATIVE_ARITH_P (operands[3])
15849 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15850 "* return output_387_binary_op (insn, operands);"
15851 [(set (attr "type")
15852 (if_then_else (match_operand:DF 3 "mult_operator" "")
15853 (const_string "fmul")
15854 (const_string "fop")))
15855 (set_attr "mode" "DF")])
15857 (define_insn "*fop_df_1_mixed"
15858 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15859 (match_operator:DF 3 "binary_fp_operator"
15860 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15861 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15862 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15863 && !COMMUTATIVE_ARITH_P (operands[3])
15864 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15865 "* return output_387_binary_op (insn, operands);"
15866 [(set (attr "type")
15867 (cond [(and (eq_attr "alternative" "2")
15868 (match_operand:DF 3 "mult_operator" ""))
15869 (const_string "ssemul")
15870 (and (eq_attr "alternative" "2")
15871 (match_operand:DF 3 "div_operator" ""))
15872 (const_string "ssediv")
15873 (eq_attr "alternative" "2")
15874 (const_string "sseadd")
15875 (match_operand:DF 3 "mult_operator" "")
15876 (const_string "fmul")
15877 (match_operand:DF 3 "div_operator" "")
15878 (const_string "fdiv")
15880 (const_string "fop")))
15881 (set_attr "mode" "DF")])
15883 (define_insn "*fop_df_1_sse"
15884 [(set (match_operand:DF 0 "register_operand" "=x")
15885 (match_operator:DF 3 "binary_fp_operator"
15886 [(match_operand:DF 1 "register_operand" "0")
15887 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15888 "TARGET_SSE2 && TARGET_SSE_MATH
15889 && !COMMUTATIVE_ARITH_P (operands[3])"
15890 "* return output_387_binary_op (insn, operands);"
15891 [(set_attr "mode" "DF")
15893 (cond [(match_operand:DF 3 "mult_operator" "")
15894 (const_string "ssemul")
15895 (match_operand:DF 3 "div_operator" "")
15896 (const_string "ssediv")
15898 (const_string "sseadd")))])
15900 ;; This pattern is not fully shadowed by the pattern above.
15901 (define_insn "*fop_df_1_i387"
15902 [(set (match_operand:DF 0 "register_operand" "=f,f")
15903 (match_operator:DF 3 "binary_fp_operator"
15904 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15905 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15906 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15907 && !COMMUTATIVE_ARITH_P (operands[3])
15908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15909 "* return output_387_binary_op (insn, operands);"
15910 [(set (attr "type")
15911 (cond [(match_operand:DF 3 "mult_operator" "")
15912 (const_string "fmul")
15913 (match_operand:DF 3 "div_operator" "")
15914 (const_string "fdiv")
15916 (const_string "fop")))
15917 (set_attr "mode" "DF")])
15919 ;; ??? Add SSE splitters for these!
15920 (define_insn "*fop_df_2<mode>_i387"
15921 [(set (match_operand:DF 0 "register_operand" "=f,f")
15922 (match_operator:DF 3 "binary_fp_operator"
15923 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15924 (match_operand:DF 2 "register_operand" "0,0")]))]
15925 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15926 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15927 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15928 [(set (attr "type")
15929 (cond [(match_operand:DF 3 "mult_operator" "")
15930 (const_string "fmul")
15931 (match_operand:DF 3 "div_operator" "")
15932 (const_string "fdiv")
15934 (const_string "fop")))
15935 (set_attr "fp_int_src" "true")
15936 (set_attr "mode" "<MODE>")])
15938 (define_insn "*fop_df_3<mode>_i387"
15939 [(set (match_operand:DF 0 "register_operand" "=f,f")
15940 (match_operator:DF 3 "binary_fp_operator"
15941 [(match_operand:DF 1 "register_operand" "0,0")
15942 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15943 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15944 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15945 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15946 [(set (attr "type")
15947 (cond [(match_operand:DF 3 "mult_operator" "")
15948 (const_string "fmul")
15949 (match_operand:DF 3 "div_operator" "")
15950 (const_string "fdiv")
15952 (const_string "fop")))
15953 (set_attr "fp_int_src" "true")
15954 (set_attr "mode" "<MODE>")])
15956 (define_insn "*fop_df_4_i387"
15957 [(set (match_operand:DF 0 "register_operand" "=f,f")
15958 (match_operator:DF 3 "binary_fp_operator"
15959 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15960 (match_operand:DF 2 "register_operand" "0,f")]))]
15961 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15963 "* return output_387_binary_op (insn, operands);"
15964 [(set (attr "type")
15965 (cond [(match_operand:DF 3 "mult_operator" "")
15966 (const_string "fmul")
15967 (match_operand:DF 3 "div_operator" "")
15968 (const_string "fdiv")
15970 (const_string "fop")))
15971 (set_attr "mode" "SF")])
15973 (define_insn "*fop_df_5_i387"
15974 [(set (match_operand:DF 0 "register_operand" "=f,f")
15975 (match_operator:DF 3 "binary_fp_operator"
15976 [(match_operand:DF 1 "register_operand" "0,f")
15978 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15979 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15980 "* return output_387_binary_op (insn, operands);"
15981 [(set (attr "type")
15982 (cond [(match_operand:DF 3 "mult_operator" "")
15983 (const_string "fmul")
15984 (match_operand:DF 3 "div_operator" "")
15985 (const_string "fdiv")
15987 (const_string "fop")))
15988 (set_attr "mode" "SF")])
15990 (define_insn "*fop_df_6_i387"
15991 [(set (match_operand:DF 0 "register_operand" "=f,f")
15992 (match_operator:DF 3 "binary_fp_operator"
15994 (match_operand:SF 1 "register_operand" "0,f"))
15996 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15997 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15998 "* return output_387_binary_op (insn, operands);"
15999 [(set (attr "type")
16000 (cond [(match_operand:DF 3 "mult_operator" "")
16001 (const_string "fmul")
16002 (match_operand:DF 3 "div_operator" "")
16003 (const_string "fdiv")
16005 (const_string "fop")))
16006 (set_attr "mode" "SF")])
16008 (define_insn "*fop_xf_comm_i387"
16009 [(set (match_operand:XF 0 "register_operand" "=f")
16010 (match_operator:XF 3 "binary_fp_operator"
16011 [(match_operand:XF 1 "register_operand" "%0")
16012 (match_operand:XF 2 "register_operand" "f")]))]
16014 && COMMUTATIVE_ARITH_P (operands[3])"
16015 "* return output_387_binary_op (insn, operands);"
16016 [(set (attr "type")
16017 (if_then_else (match_operand:XF 3 "mult_operator" "")
16018 (const_string "fmul")
16019 (const_string "fop")))
16020 (set_attr "mode" "XF")])
16022 (define_insn "*fop_xf_1_i387"
16023 [(set (match_operand:XF 0 "register_operand" "=f,f")
16024 (match_operator:XF 3 "binary_fp_operator"
16025 [(match_operand:XF 1 "register_operand" "0,f")
16026 (match_operand:XF 2 "register_operand" "f,0")]))]
16028 && !COMMUTATIVE_ARITH_P (operands[3])"
16029 "* return output_387_binary_op (insn, operands);"
16030 [(set (attr "type")
16031 (cond [(match_operand:XF 3 "mult_operator" "")
16032 (const_string "fmul")
16033 (match_operand:XF 3 "div_operator" "")
16034 (const_string "fdiv")
16036 (const_string "fop")))
16037 (set_attr "mode" "XF")])
16039 (define_insn "*fop_xf_2<mode>_i387"
16040 [(set (match_operand:XF 0 "register_operand" "=f,f")
16041 (match_operator:XF 3 "binary_fp_operator"
16042 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16043 (match_operand:XF 2 "register_operand" "0,0")]))]
16044 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16045 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16046 [(set (attr "type")
16047 (cond [(match_operand:XF 3 "mult_operator" "")
16048 (const_string "fmul")
16049 (match_operand:XF 3 "div_operator" "")
16050 (const_string "fdiv")
16052 (const_string "fop")))
16053 (set_attr "fp_int_src" "true")
16054 (set_attr "mode" "<MODE>")])
16056 (define_insn "*fop_xf_3<mode>_i387"
16057 [(set (match_operand:XF 0 "register_operand" "=f,f")
16058 (match_operator:XF 3 "binary_fp_operator"
16059 [(match_operand:XF 1 "register_operand" "0,0")
16060 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16061 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16062 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16063 [(set (attr "type")
16064 (cond [(match_operand:XF 3 "mult_operator" "")
16065 (const_string "fmul")
16066 (match_operand:XF 3 "div_operator" "")
16067 (const_string "fdiv")
16069 (const_string "fop")))
16070 (set_attr "fp_int_src" "true")
16071 (set_attr "mode" "<MODE>")])
16073 (define_insn "*fop_xf_4_i387"
16074 [(set (match_operand:XF 0 "register_operand" "=f,f")
16075 (match_operator:XF 3 "binary_fp_operator"
16077 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16078 (match_operand:XF 2 "register_operand" "0,f")]))]
16080 "* return output_387_binary_op (insn, operands);"
16081 [(set (attr "type")
16082 (cond [(match_operand:XF 3 "mult_operator" "")
16083 (const_string "fmul")
16084 (match_operand:XF 3 "div_operator" "")
16085 (const_string "fdiv")
16087 (const_string "fop")))
16088 (set_attr "mode" "SF")])
16090 (define_insn "*fop_xf_5_i387"
16091 [(set (match_operand:XF 0 "register_operand" "=f,f")
16092 (match_operator:XF 3 "binary_fp_operator"
16093 [(match_operand:XF 1 "register_operand" "0,f")
16095 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16097 "* return output_387_binary_op (insn, operands);"
16098 [(set (attr "type")
16099 (cond [(match_operand:XF 3 "mult_operator" "")
16100 (const_string "fmul")
16101 (match_operand:XF 3 "div_operator" "")
16102 (const_string "fdiv")
16104 (const_string "fop")))
16105 (set_attr "mode" "SF")])
16107 (define_insn "*fop_xf_6_i387"
16108 [(set (match_operand:XF 0 "register_operand" "=f,f")
16109 (match_operator:XF 3 "binary_fp_operator"
16111 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16113 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16115 "* return output_387_binary_op (insn, operands);"
16116 [(set (attr "type")
16117 (cond [(match_operand:XF 3 "mult_operator" "")
16118 (const_string "fmul")
16119 (match_operand:XF 3 "div_operator" "")
16120 (const_string "fdiv")
16122 (const_string "fop")))
16123 (set_attr "mode" "SF")])
16126 [(set (match_operand 0 "register_operand" "")
16127 (match_operator 3 "binary_fp_operator"
16128 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16129 (match_operand 2 "register_operand" "")]))]
16130 "TARGET_80387 && reload_completed
16131 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16134 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16135 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16136 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16137 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16138 GET_MODE (operands[3]),
16141 ix86_free_from_memory (GET_MODE (operands[1]));
16146 [(set (match_operand 0 "register_operand" "")
16147 (match_operator 3 "binary_fp_operator"
16148 [(match_operand 1 "register_operand" "")
16149 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16150 "TARGET_80387 && reload_completed
16151 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16154 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16155 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16156 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16157 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16158 GET_MODE (operands[3]),
16161 ix86_free_from_memory (GET_MODE (operands[2]));
16165 ;; FPU special functions.
16167 ;; This pattern implements a no-op XFmode truncation for
16168 ;; all fancy i386 XFmode math functions.
16170 (define_insn "truncxf<mode>2_i387_noop_unspec"
16171 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16172 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16173 UNSPEC_TRUNC_NOOP))]
16174 "TARGET_USE_FANCY_MATH_387"
16175 "* return output_387_reg_move (insn, operands);"
16176 [(set_attr "type" "fmov")
16177 (set_attr "mode" "<MODE>")])
16179 (define_insn "sqrtxf2"
16180 [(set (match_operand:XF 0 "register_operand" "=f")
16181 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16182 "TARGET_USE_FANCY_MATH_387"
16184 [(set_attr "type" "fpspc")
16185 (set_attr "mode" "XF")
16186 (set_attr "athlon_decode" "direct")
16187 (set_attr "amdfam10_decode" "direct")])
16189 (define_insn "sqrt_extend<mode>xf2_i387"
16190 [(set (match_operand:XF 0 "register_operand" "=f")
16193 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16194 "TARGET_USE_FANCY_MATH_387"
16196 [(set_attr "type" "fpspc")
16197 (set_attr "mode" "XF")
16198 (set_attr "athlon_decode" "direct")
16199 (set_attr "amdfam10_decode" "direct")])
16201 (define_insn "*sqrt<mode>2_sse"
16202 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16204 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16205 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16206 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16207 [(set_attr "type" "sse")
16208 (set_attr "mode" "<MODE>")
16209 (set_attr "athlon_decode" "*")
16210 (set_attr "amdfam10_decode" "*")])
16212 (define_expand "sqrt<mode>2"
16213 [(set (match_operand:X87MODEF12 0 "register_operand" "")
16215 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16216 "TARGET_USE_FANCY_MATH_387
16217 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16219 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16221 rtx op0 = gen_reg_rtx (XFmode);
16222 rtx op1 = force_reg (<MODE>mode, operands[1]);
16224 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16225 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16230 (define_insn "fpremxf4_i387"
16231 [(set (match_operand:XF 0 "register_operand" "=f")
16232 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16233 (match_operand:XF 3 "register_operand" "1")]
16235 (set (match_operand:XF 1 "register_operand" "=u")
16236 (unspec:XF [(match_dup 2) (match_dup 3)]
16238 (set (reg:CCFP FPSR_REG)
16239 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16240 "TARGET_USE_FANCY_MATH_387"
16242 [(set_attr "type" "fpspc")
16243 (set_attr "mode" "XF")])
16245 (define_expand "fmodxf3"
16246 [(use (match_operand:XF 0 "register_operand" ""))
16247 (use (match_operand:XF 1 "register_operand" ""))
16248 (use (match_operand:XF 2 "register_operand" ""))]
16249 "TARGET_USE_FANCY_MATH_387"
16251 rtx label = gen_label_rtx ();
16253 emit_label (label);
16255 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16256 operands[1], operands[2]));
16257 ix86_emit_fp_unordered_jump (label);
16259 emit_move_insn (operands[0], operands[1]);
16263 (define_expand "fmod<mode>3"
16264 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16265 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16266 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16267 "TARGET_USE_FANCY_MATH_387"
16269 rtx label = gen_label_rtx ();
16271 rtx op1 = gen_reg_rtx (XFmode);
16272 rtx op2 = gen_reg_rtx (XFmode);
16274 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16275 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16277 emit_label (label);
16278 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16279 ix86_emit_fp_unordered_jump (label);
16281 /* Truncate the result properly for strict SSE math. */
16282 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16283 && !TARGET_MIX_SSE_I387)
16284 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16286 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16291 (define_insn "fprem1xf4_i387"
16292 [(set (match_operand:XF 0 "register_operand" "=f")
16293 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16294 (match_operand:XF 3 "register_operand" "1")]
16296 (set (match_operand:XF 1 "register_operand" "=u")
16297 (unspec:XF [(match_dup 2) (match_dup 3)]
16299 (set (reg:CCFP FPSR_REG)
16300 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16301 "TARGET_USE_FANCY_MATH_387"
16303 [(set_attr "type" "fpspc")
16304 (set_attr "mode" "XF")])
16306 (define_expand "remainderxf3"
16307 [(use (match_operand:XF 0 "register_operand" ""))
16308 (use (match_operand:XF 1 "register_operand" ""))
16309 (use (match_operand:XF 2 "register_operand" ""))]
16310 "TARGET_USE_FANCY_MATH_387"
16312 rtx label = gen_label_rtx ();
16314 emit_label (label);
16316 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16317 operands[1], operands[2]));
16318 ix86_emit_fp_unordered_jump (label);
16320 emit_move_insn (operands[0], operands[1]);
16324 (define_expand "remainder<mode>3"
16325 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16326 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16327 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16328 "TARGET_USE_FANCY_MATH_387"
16330 rtx label = gen_label_rtx ();
16332 rtx op1 = gen_reg_rtx (XFmode);
16333 rtx op2 = gen_reg_rtx (XFmode);
16335 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16336 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16338 emit_label (label);
16340 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16341 ix86_emit_fp_unordered_jump (label);
16343 /* Truncate the result properly for strict SSE math. */
16344 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16345 && !TARGET_MIX_SSE_I387)
16346 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16348 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16353 (define_insn "*sinxf2_i387"
16354 [(set (match_operand:XF 0 "register_operand" "=f")
16355 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16356 "TARGET_USE_FANCY_MATH_387
16357 && flag_unsafe_math_optimizations"
16359 [(set_attr "type" "fpspc")
16360 (set_attr "mode" "XF")])
16362 (define_insn "*sin_extend<mode>xf2_i387"
16363 [(set (match_operand:XF 0 "register_operand" "=f")
16364 (unspec:XF [(float_extend:XF
16365 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16367 "TARGET_USE_FANCY_MATH_387
16368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16369 || TARGET_MIX_SSE_I387)
16370 && flag_unsafe_math_optimizations"
16372 [(set_attr "type" "fpspc")
16373 (set_attr "mode" "XF")])
16375 (define_insn "*cosxf2_i387"
16376 [(set (match_operand:XF 0 "register_operand" "=f")
16377 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16378 "TARGET_USE_FANCY_MATH_387
16379 && flag_unsafe_math_optimizations"
16381 [(set_attr "type" "fpspc")
16382 (set_attr "mode" "XF")])
16384 (define_insn "*cos_extend<mode>xf2_i387"
16385 [(set (match_operand:XF 0 "register_operand" "=f")
16386 (unspec:XF [(float_extend:XF
16387 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16389 "TARGET_USE_FANCY_MATH_387
16390 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16391 || TARGET_MIX_SSE_I387)
16392 && flag_unsafe_math_optimizations"
16394 [(set_attr "type" "fpspc")
16395 (set_attr "mode" "XF")])
16397 ;; When sincos pattern is defined, sin and cos builtin functions will be
16398 ;; expanded to sincos pattern with one of its outputs left unused.
16399 ;; CSE pass will figure out if two sincos patterns can be combined,
16400 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16401 ;; depending on the unused output.
16403 (define_insn "sincosxf3"
16404 [(set (match_operand:XF 0 "register_operand" "=f")
16405 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16406 UNSPEC_SINCOS_COS))
16407 (set (match_operand:XF 1 "register_operand" "=u")
16408 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16409 "TARGET_USE_FANCY_MATH_387
16410 && flag_unsafe_math_optimizations"
16412 [(set_attr "type" "fpspc")
16413 (set_attr "mode" "XF")])
16416 [(set (match_operand:XF 0 "register_operand" "")
16417 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16418 UNSPEC_SINCOS_COS))
16419 (set (match_operand:XF 1 "register_operand" "")
16420 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16421 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16422 && !reload_completed && !reload_in_progress"
16423 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16427 [(set (match_operand:XF 0 "register_operand" "")
16428 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16429 UNSPEC_SINCOS_COS))
16430 (set (match_operand:XF 1 "register_operand" "")
16431 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16432 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16433 && !reload_completed && !reload_in_progress"
16434 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16437 (define_insn "sincos_extend<mode>xf3_i387"
16438 [(set (match_operand:XF 0 "register_operand" "=f")
16439 (unspec:XF [(float_extend:XF
16440 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16441 UNSPEC_SINCOS_COS))
16442 (set (match_operand:XF 1 "register_operand" "=u")
16443 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16444 "TARGET_USE_FANCY_MATH_387
16445 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16446 || TARGET_MIX_SSE_I387)
16447 && flag_unsafe_math_optimizations"
16449 [(set_attr "type" "fpspc")
16450 (set_attr "mode" "XF")])
16453 [(set (match_operand:XF 0 "register_operand" "")
16454 (unspec:XF [(float_extend:XF
16455 (match_operand:X87MODEF12 2 "register_operand" ""))]
16456 UNSPEC_SINCOS_COS))
16457 (set (match_operand:XF 1 "register_operand" "")
16458 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16459 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16460 && !reload_completed && !reload_in_progress"
16461 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16465 [(set (match_operand:XF 0 "register_operand" "")
16466 (unspec:XF [(float_extend:XF
16467 (match_operand:X87MODEF12 2 "register_operand" ""))]
16468 UNSPEC_SINCOS_COS))
16469 (set (match_operand:XF 1 "register_operand" "")
16470 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16471 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16472 && !reload_completed && !reload_in_progress"
16473 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16476 (define_expand "sincos<mode>3"
16477 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16478 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16479 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16480 "TARGET_USE_FANCY_MATH_387
16481 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16482 || TARGET_MIX_SSE_I387)
16483 && flag_unsafe_math_optimizations"
16485 rtx op0 = gen_reg_rtx (XFmode);
16486 rtx op1 = gen_reg_rtx (XFmode);
16488 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16489 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16490 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16494 (define_insn "fptanxf4_i387"
16495 [(set (match_operand:XF 0 "register_operand" "=f")
16496 (match_operand:XF 3 "const_double_operand" "F"))
16497 (set (match_operand:XF 1 "register_operand" "=u")
16498 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16500 "TARGET_USE_FANCY_MATH_387
16501 && flag_unsafe_math_optimizations
16502 && standard_80387_constant_p (operands[3]) == 2"
16504 [(set_attr "type" "fpspc")
16505 (set_attr "mode" "XF")])
16507 (define_insn "fptan_extend<mode>xf4_i387"
16508 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16509 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16510 (set (match_operand:XF 1 "register_operand" "=u")
16511 (unspec:XF [(float_extend:XF
16512 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16514 "TARGET_USE_FANCY_MATH_387
16515 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16516 || TARGET_MIX_SSE_I387)
16517 && flag_unsafe_math_optimizations
16518 && standard_80387_constant_p (operands[3]) == 2"
16520 [(set_attr "type" "fpspc")
16521 (set_attr "mode" "XF")])
16523 (define_expand "tanxf2"
16524 [(use (match_operand:XF 0 "register_operand" ""))
16525 (use (match_operand:XF 1 "register_operand" ""))]
16526 "TARGET_USE_FANCY_MATH_387
16527 && flag_unsafe_math_optimizations"
16529 rtx one = gen_reg_rtx (XFmode);
16530 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16532 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16536 (define_expand "tan<mode>2"
16537 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16538 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16539 "TARGET_USE_FANCY_MATH_387
16540 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16541 || TARGET_MIX_SSE_I387)
16542 && flag_unsafe_math_optimizations"
16544 rtx op0 = gen_reg_rtx (XFmode);
16546 rtx one = gen_reg_rtx (<MODE>mode);
16547 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16549 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16550 operands[1], op2));
16551 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16555 (define_insn "*fpatanxf3_i387"
16556 [(set (match_operand:XF 0 "register_operand" "=f")
16557 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16558 (match_operand:XF 2 "register_operand" "u")]
16560 (clobber (match_scratch:XF 3 "=2"))]
16561 "TARGET_USE_FANCY_MATH_387
16562 && flag_unsafe_math_optimizations"
16564 [(set_attr "type" "fpspc")
16565 (set_attr "mode" "XF")])
16567 (define_insn "fpatan_extend<mode>xf3_i387"
16568 [(set (match_operand:XF 0 "register_operand" "=f")
16569 (unspec:XF [(float_extend:XF
16570 (match_operand:X87MODEF12 1 "register_operand" "0"))
16572 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16574 (clobber (match_scratch:XF 3 "=2"))]
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 (define_expand "atan2xf3"
16584 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16585 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16586 (match_operand:XF 1 "register_operand" "")]
16588 (clobber (match_scratch:XF 3 ""))])]
16589 "TARGET_USE_FANCY_MATH_387
16590 && flag_unsafe_math_optimizations"
16593 (define_expand "atan2<mode>3"
16594 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16595 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16596 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16597 "TARGET_USE_FANCY_MATH_387
16598 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16599 || TARGET_MIX_SSE_I387)
16600 && flag_unsafe_math_optimizations"
16602 rtx op0 = gen_reg_rtx (XFmode);
16604 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16605 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16609 (define_expand "atanxf2"
16610 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16611 (unspec:XF [(match_dup 2)
16612 (match_operand:XF 1 "register_operand" "")]
16614 (clobber (match_scratch:XF 3 ""))])]
16615 "TARGET_USE_FANCY_MATH_387
16616 && flag_unsafe_math_optimizations"
16618 operands[2] = gen_reg_rtx (XFmode);
16619 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16622 (define_expand "atan<mode>2"
16623 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16624 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16625 "TARGET_USE_FANCY_MATH_387
16626 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16627 || TARGET_MIX_SSE_I387)
16628 && flag_unsafe_math_optimizations"
16630 rtx op0 = gen_reg_rtx (XFmode);
16632 rtx op2 = gen_reg_rtx (<MODE>mode);
16633 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16635 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16636 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16640 (define_expand "asinxf2"
16641 [(set (match_dup 2)
16642 (mult:XF (match_operand:XF 1 "register_operand" "")
16644 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16645 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16646 (parallel [(set (match_operand:XF 0 "register_operand" "")
16647 (unspec:XF [(match_dup 5) (match_dup 1)]
16649 (clobber (match_scratch:XF 6 ""))])]
16650 "TARGET_USE_FANCY_MATH_387
16651 && flag_unsafe_math_optimizations && !optimize_size"
16655 for (i = 2; i < 6; i++)
16656 operands[i] = gen_reg_rtx (XFmode);
16658 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16661 (define_expand "asin<mode>2"
16662 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16663 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16664 "TARGET_USE_FANCY_MATH_387
16665 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16666 || TARGET_MIX_SSE_I387)
16667 && flag_unsafe_math_optimizations && !optimize_size"
16669 rtx op0 = gen_reg_rtx (XFmode);
16670 rtx op1 = gen_reg_rtx (XFmode);
16672 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16673 emit_insn (gen_asinxf2 (op0, op1));
16674 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16678 (define_expand "acosxf2"
16679 [(set (match_dup 2)
16680 (mult:XF (match_operand:XF 1 "register_operand" "")
16682 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16683 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16684 (parallel [(set (match_operand:XF 0 "register_operand" "")
16685 (unspec:XF [(match_dup 1) (match_dup 5)]
16687 (clobber (match_scratch:XF 6 ""))])]
16688 "TARGET_USE_FANCY_MATH_387
16689 && flag_unsafe_math_optimizations && !optimize_size"
16693 for (i = 2; i < 6; i++)
16694 operands[i] = gen_reg_rtx (XFmode);
16696 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16699 (define_expand "acos<mode>2"
16700 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16701 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16702 "TARGET_USE_FANCY_MATH_387
16703 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16704 || TARGET_MIX_SSE_I387)
16705 && flag_unsafe_math_optimizations && !optimize_size"
16707 rtx op0 = gen_reg_rtx (XFmode);
16708 rtx op1 = gen_reg_rtx (XFmode);
16710 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16711 emit_insn (gen_acosxf2 (op0, op1));
16712 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16716 (define_insn "fyl2xxf3_i387"
16717 [(set (match_operand:XF 0 "register_operand" "=f")
16718 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16719 (match_operand:XF 2 "register_operand" "u")]
16721 (clobber (match_scratch:XF 3 "=2"))]
16722 "TARGET_USE_FANCY_MATH_387
16723 && flag_unsafe_math_optimizations"
16725 [(set_attr "type" "fpspc")
16726 (set_attr "mode" "XF")])
16728 (define_insn "fyl2x_extend<mode>xf3_i387"
16729 [(set (match_operand:XF 0 "register_operand" "=f")
16730 (unspec:XF [(float_extend:XF
16731 (match_operand:X87MODEF12 1 "register_operand" "0"))
16732 (match_operand:XF 2 "register_operand" "u")]
16734 (clobber (match_scratch:XF 3 "=2"))]
16735 "TARGET_USE_FANCY_MATH_387
16736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16737 || TARGET_MIX_SSE_I387)
16738 && flag_unsafe_math_optimizations"
16740 [(set_attr "type" "fpspc")
16741 (set_attr "mode" "XF")])
16743 (define_expand "logxf2"
16744 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16745 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16746 (match_dup 2)] UNSPEC_FYL2X))
16747 (clobber (match_scratch:XF 3 ""))])]
16748 "TARGET_USE_FANCY_MATH_387
16749 && flag_unsafe_math_optimizations"
16751 operands[2] = gen_reg_rtx (XFmode);
16752 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16755 (define_expand "log<mode>2"
16756 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16757 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16758 "TARGET_USE_FANCY_MATH_387
16759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16760 || TARGET_MIX_SSE_I387)
16761 && flag_unsafe_math_optimizations"
16763 rtx op0 = gen_reg_rtx (XFmode);
16765 rtx op2 = gen_reg_rtx (XFmode);
16766 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16768 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16769 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16773 (define_expand "log10xf2"
16774 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16775 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16776 (match_dup 2)] UNSPEC_FYL2X))
16777 (clobber (match_scratch:XF 3 ""))])]
16778 "TARGET_USE_FANCY_MATH_387
16779 && flag_unsafe_math_optimizations"
16781 operands[2] = gen_reg_rtx (XFmode);
16782 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16785 (define_expand "log10<mode>2"
16786 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16787 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16788 "TARGET_USE_FANCY_MATH_387
16789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16790 || TARGET_MIX_SSE_I387)
16791 && flag_unsafe_math_optimizations"
16793 rtx op0 = gen_reg_rtx (XFmode);
16795 rtx op2 = gen_reg_rtx (XFmode);
16796 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16798 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16803 (define_expand "log2xf2"
16804 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16805 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16806 (match_dup 2)] UNSPEC_FYL2X))
16807 (clobber (match_scratch:XF 3 ""))])]
16808 "TARGET_USE_FANCY_MATH_387
16809 && flag_unsafe_math_optimizations"
16811 operands[2] = gen_reg_rtx (XFmode);
16812 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16815 (define_expand "log2<mode>2"
16816 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16817 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16818 "TARGET_USE_FANCY_MATH_387
16819 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16820 || TARGET_MIX_SSE_I387)
16821 && flag_unsafe_math_optimizations"
16823 rtx op0 = gen_reg_rtx (XFmode);
16825 rtx op2 = gen_reg_rtx (XFmode);
16826 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16828 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16829 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16833 (define_insn "fyl2xp1xf3_i387"
16834 [(set (match_operand:XF 0 "register_operand" "=f")
16835 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16836 (match_operand:XF 2 "register_operand" "u")]
16838 (clobber (match_scratch:XF 3 "=2"))]
16839 "TARGET_USE_FANCY_MATH_387
16840 && flag_unsafe_math_optimizations"
16842 [(set_attr "type" "fpspc")
16843 (set_attr "mode" "XF")])
16845 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16846 [(set (match_operand:XF 0 "register_operand" "=f")
16847 (unspec:XF [(float_extend:XF
16848 (match_operand:X87MODEF12 1 "register_operand" "0"))
16849 (match_operand:XF 2 "register_operand" "u")]
16851 (clobber (match_scratch:XF 3 "=2"))]
16852 "TARGET_USE_FANCY_MATH_387
16853 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16854 || TARGET_MIX_SSE_I387)
16855 && flag_unsafe_math_optimizations"
16857 [(set_attr "type" "fpspc")
16858 (set_attr "mode" "XF")])
16860 (define_expand "log1pxf2"
16861 [(use (match_operand:XF 0 "register_operand" ""))
16862 (use (match_operand:XF 1 "register_operand" ""))]
16863 "TARGET_USE_FANCY_MATH_387
16864 && flag_unsafe_math_optimizations && !optimize_size"
16866 ix86_emit_i387_log1p (operands[0], operands[1]);
16870 (define_expand "log1p<mode>2"
16871 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16872 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16873 "TARGET_USE_FANCY_MATH_387
16874 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16875 || TARGET_MIX_SSE_I387)
16876 && flag_unsafe_math_optimizations && !optimize_size"
16878 rtx op0 = gen_reg_rtx (XFmode);
16880 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16882 ix86_emit_i387_log1p (op0, operands[1]);
16883 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16887 (define_insn "fxtractxf3_i387"
16888 [(set (match_operand:XF 0 "register_operand" "=f")
16889 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16890 UNSPEC_XTRACT_FRACT))
16891 (set (match_operand:XF 1 "register_operand" "=u")
16892 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16893 "TARGET_USE_FANCY_MATH_387
16894 && flag_unsafe_math_optimizations"
16896 [(set_attr "type" "fpspc")
16897 (set_attr "mode" "XF")])
16899 (define_insn "fxtract_extend<mode>xf3_i387"
16900 [(set (match_operand:XF 0 "register_operand" "=f")
16901 (unspec:XF [(float_extend:XF
16902 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16903 UNSPEC_XTRACT_FRACT))
16904 (set (match_operand:XF 1 "register_operand" "=u")
16905 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16906 "TARGET_USE_FANCY_MATH_387
16907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16908 || TARGET_MIX_SSE_I387)
16909 && flag_unsafe_math_optimizations"
16911 [(set_attr "type" "fpspc")
16912 (set_attr "mode" "XF")])
16914 (define_expand "logbxf2"
16915 [(parallel [(set (match_dup 2)
16916 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16917 UNSPEC_XTRACT_FRACT))
16918 (set (match_operand:XF 0 "register_operand" "")
16919 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16920 "TARGET_USE_FANCY_MATH_387
16921 && flag_unsafe_math_optimizations"
16923 operands[2] = gen_reg_rtx (XFmode);
16926 (define_expand "logb<mode>2"
16927 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16928 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16929 "TARGET_USE_FANCY_MATH_387
16930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16931 || TARGET_MIX_SSE_I387)
16932 && flag_unsafe_math_optimizations"
16934 rtx op0 = gen_reg_rtx (XFmode);
16935 rtx op1 = gen_reg_rtx (XFmode);
16937 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16938 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16942 (define_expand "ilogbxf2"
16943 [(use (match_operand:SI 0 "register_operand" ""))
16944 (use (match_operand:XF 1 "register_operand" ""))]
16945 "TARGET_USE_FANCY_MATH_387
16946 && flag_unsafe_math_optimizations && !optimize_size"
16948 rtx op0 = gen_reg_rtx (XFmode);
16949 rtx op1 = gen_reg_rtx (XFmode);
16951 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16952 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16956 (define_expand "ilogb<mode>2"
16957 [(use (match_operand:SI 0 "register_operand" ""))
16958 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16959 "TARGET_USE_FANCY_MATH_387
16960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16961 || TARGET_MIX_SSE_I387)
16962 && flag_unsafe_math_optimizations && !optimize_size"
16964 rtx op0 = gen_reg_rtx (XFmode);
16965 rtx op1 = gen_reg_rtx (XFmode);
16967 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16968 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16972 (define_insn "*f2xm1xf2_i387"
16973 [(set (match_operand:XF 0 "register_operand" "=f")
16974 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16976 "TARGET_USE_FANCY_MATH_387
16977 && flag_unsafe_math_optimizations"
16979 [(set_attr "type" "fpspc")
16980 (set_attr "mode" "XF")])
16982 (define_insn "*fscalexf4_i387"
16983 [(set (match_operand:XF 0 "register_operand" "=f")
16984 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16985 (match_operand:XF 3 "register_operand" "1")]
16986 UNSPEC_FSCALE_FRACT))
16987 (set (match_operand:XF 1 "register_operand" "=u")
16988 (unspec:XF [(match_dup 2) (match_dup 3)]
16989 UNSPEC_FSCALE_EXP))]
16990 "TARGET_USE_FANCY_MATH_387
16991 && flag_unsafe_math_optimizations"
16993 [(set_attr "type" "fpspc")
16994 (set_attr "mode" "XF")])
16996 (define_expand "expNcorexf3"
16997 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16998 (match_operand:XF 2 "register_operand" "")))
16999 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17000 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17001 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17002 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17003 (parallel [(set (match_operand:XF 0 "register_operand" "")
17004 (unspec:XF [(match_dup 8) (match_dup 4)]
17005 UNSPEC_FSCALE_FRACT))
17007 (unspec:XF [(match_dup 8) (match_dup 4)]
17008 UNSPEC_FSCALE_EXP))])]
17009 "TARGET_USE_FANCY_MATH_387
17010 && flag_unsafe_math_optimizations && !optimize_size"
17014 for (i = 3; i < 10; i++)
17015 operands[i] = gen_reg_rtx (XFmode);
17017 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17020 (define_expand "expxf2"
17021 [(use (match_operand:XF 0 "register_operand" ""))
17022 (use (match_operand:XF 1 "register_operand" ""))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && flag_unsafe_math_optimizations && !optimize_size"
17026 rtx op2 = gen_reg_rtx (XFmode);
17027 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17029 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17033 (define_expand "exp<mode>2"
17034 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17035 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17036 "TARGET_USE_FANCY_MATH_387
17037 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17038 || TARGET_MIX_SSE_I387)
17039 && flag_unsafe_math_optimizations && !optimize_size"
17041 rtx op0 = gen_reg_rtx (XFmode);
17042 rtx op1 = gen_reg_rtx (XFmode);
17044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17045 emit_insn (gen_expxf2 (op0, op1));
17046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17050 (define_expand "exp10xf2"
17051 [(use (match_operand:XF 0 "register_operand" ""))
17052 (use (match_operand:XF 1 "register_operand" ""))]
17053 "TARGET_USE_FANCY_MATH_387
17054 && flag_unsafe_math_optimizations && !optimize_size"
17056 rtx op2 = gen_reg_rtx (XFmode);
17057 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17059 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17063 (define_expand "exp10<mode>2"
17064 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17065 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17066 "TARGET_USE_FANCY_MATH_387
17067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17068 || TARGET_MIX_SSE_I387)
17069 && flag_unsafe_math_optimizations && !optimize_size"
17071 rtx op0 = gen_reg_rtx (XFmode);
17072 rtx op1 = gen_reg_rtx (XFmode);
17074 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17075 emit_insn (gen_exp10xf2 (op0, op1));
17076 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17080 (define_expand "exp2xf2"
17081 [(use (match_operand:XF 0 "register_operand" ""))
17082 (use (match_operand:XF 1 "register_operand" ""))]
17083 "TARGET_USE_FANCY_MATH_387
17084 && flag_unsafe_math_optimizations && !optimize_size"
17086 rtx op2 = gen_reg_rtx (XFmode);
17087 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17089 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17093 (define_expand "exp2<mode>2"
17094 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17095 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17096 "TARGET_USE_FANCY_MATH_387
17097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17098 || TARGET_MIX_SSE_I387)
17099 && flag_unsafe_math_optimizations && !optimize_size"
17101 rtx op0 = gen_reg_rtx (XFmode);
17102 rtx op1 = gen_reg_rtx (XFmode);
17104 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17105 emit_insn (gen_exp2xf2 (op0, op1));
17106 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17110 (define_expand "expm1xf2"
17111 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17113 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17114 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17115 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17116 (parallel [(set (match_dup 7)
17117 (unspec:XF [(match_dup 6) (match_dup 4)]
17118 UNSPEC_FSCALE_FRACT))
17120 (unspec:XF [(match_dup 6) (match_dup 4)]
17121 UNSPEC_FSCALE_EXP))])
17122 (parallel [(set (match_dup 10)
17123 (unspec:XF [(match_dup 9) (match_dup 8)]
17124 UNSPEC_FSCALE_FRACT))
17125 (set (match_dup 11)
17126 (unspec:XF [(match_dup 9) (match_dup 8)]
17127 UNSPEC_FSCALE_EXP))])
17128 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17129 (set (match_operand:XF 0 "register_operand" "")
17130 (plus:XF (match_dup 12) (match_dup 7)))]
17131 "TARGET_USE_FANCY_MATH_387
17132 && flag_unsafe_math_optimizations && !optimize_size"
17136 for (i = 2; i < 13; i++)
17137 operands[i] = gen_reg_rtx (XFmode);
17139 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17140 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17143 (define_expand "expm1<mode>2"
17144 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17145 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17146 "TARGET_USE_FANCY_MATH_387
17147 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17148 || TARGET_MIX_SSE_I387)
17149 && flag_unsafe_math_optimizations && !optimize_size"
17151 rtx op0 = gen_reg_rtx (XFmode);
17152 rtx op1 = gen_reg_rtx (XFmode);
17154 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17155 emit_insn (gen_expm1xf2 (op0, op1));
17156 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17160 (define_expand "ldexpxf3"
17161 [(set (match_dup 3)
17162 (float:XF (match_operand:SI 2 "register_operand" "")))
17163 (parallel [(set (match_operand:XF 0 " register_operand" "")
17164 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17166 UNSPEC_FSCALE_FRACT))
17168 (unspec:XF [(match_dup 1) (match_dup 3)]
17169 UNSPEC_FSCALE_EXP))])]
17170 "TARGET_USE_FANCY_MATH_387
17171 && flag_unsafe_math_optimizations && !optimize_size"
17173 operands[3] = gen_reg_rtx (XFmode);
17174 operands[4] = gen_reg_rtx (XFmode);
17177 (define_expand "ldexp<mode>3"
17178 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17179 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17180 (use (match_operand:SI 2 "register_operand" ""))]
17181 "TARGET_USE_FANCY_MATH_387
17182 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17183 || TARGET_MIX_SSE_I387)
17184 && flag_unsafe_math_optimizations && !optimize_size"
17186 rtx op0 = gen_reg_rtx (XFmode);
17187 rtx op1 = gen_reg_rtx (XFmode);
17189 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17190 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17191 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17196 (define_insn "frndintxf2"
17197 [(set (match_operand:XF 0 "register_operand" "=f")
17198 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17200 "TARGET_USE_FANCY_MATH_387
17201 && flag_unsafe_math_optimizations"
17203 [(set_attr "type" "fpspc")
17204 (set_attr "mode" "XF")])
17206 (define_expand "rintdf2"
17207 [(use (match_operand:DF 0 "register_operand" ""))
17208 (use (match_operand:DF 1 "register_operand" ""))]
17209 "(TARGET_USE_FANCY_MATH_387
17210 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17211 && flag_unsafe_math_optimizations)
17212 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17213 && !flag_trapping_math
17214 && !optimize_size)"
17216 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17217 && !flag_trapping_math
17219 ix86_expand_rint (operand0, operand1);
17222 rtx op0 = gen_reg_rtx (XFmode);
17223 rtx op1 = gen_reg_rtx (XFmode);
17225 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17226 emit_insn (gen_frndintxf2 (op0, op1));
17228 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17233 (define_expand "rintsf2"
17234 [(use (match_operand:SF 0 "register_operand" ""))
17235 (use (match_operand:SF 1 "register_operand" ""))]
17236 "(TARGET_USE_FANCY_MATH_387
17237 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17238 && flag_unsafe_math_optimizations)
17239 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17240 && !flag_trapping_math
17241 && !optimize_size)"
17243 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17244 && !flag_trapping_math
17246 ix86_expand_rint (operand0, operand1);
17249 rtx op0 = gen_reg_rtx (XFmode);
17250 rtx op1 = gen_reg_rtx (XFmode);
17252 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17253 emit_insn (gen_frndintxf2 (op0, op1));
17255 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17260 (define_expand "rintxf2"
17261 [(use (match_operand:XF 0 "register_operand" ""))
17262 (use (match_operand:XF 1 "register_operand" ""))]
17263 "TARGET_USE_FANCY_MATH_387
17264 && flag_unsafe_math_optimizations && !optimize_size"
17266 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17270 (define_expand "roundsf2"
17271 [(match_operand:SF 0 "register_operand" "")
17272 (match_operand:SF 1 "nonimmediate_operand" "")]
17273 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17274 && !flag_trapping_math && !flag_rounding_math
17277 ix86_expand_round (operand0, operand1);
17281 (define_expand "rounddf2"
17282 [(match_operand:DF 0 "register_operand" "")
17283 (match_operand:DF 1 "nonimmediate_operand" "")]
17284 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17285 && !flag_trapping_math && !flag_rounding_math
17289 ix86_expand_round (operand0, operand1);
17291 ix86_expand_rounddf_32 (operand0, operand1);
17295 (define_insn_and_split "*fistdi2_1"
17296 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17297 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17299 "TARGET_USE_FANCY_MATH_387
17300 && !(reload_completed || reload_in_progress)"
17305 if (memory_operand (operands[0], VOIDmode))
17306 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17309 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17310 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17315 [(set_attr "type" "fpspc")
17316 (set_attr "mode" "DI")])
17318 (define_insn "fistdi2"
17319 [(set (match_operand:DI 0 "memory_operand" "=m")
17320 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17322 (clobber (match_scratch:XF 2 "=&1f"))]
17323 "TARGET_USE_FANCY_MATH_387"
17324 "* return output_fix_trunc (insn, operands, 0);"
17325 [(set_attr "type" "fpspc")
17326 (set_attr "mode" "DI")])
17328 (define_insn "fistdi2_with_temp"
17329 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17330 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17332 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17333 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17334 "TARGET_USE_FANCY_MATH_387"
17336 [(set_attr "type" "fpspc")
17337 (set_attr "mode" "DI")])
17340 [(set (match_operand:DI 0 "register_operand" "")
17341 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17343 (clobber (match_operand:DI 2 "memory_operand" ""))
17344 (clobber (match_scratch 3 ""))]
17346 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17347 (clobber (match_dup 3))])
17348 (set (match_dup 0) (match_dup 2))]
17352 [(set (match_operand:DI 0 "memory_operand" "")
17353 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17355 (clobber (match_operand:DI 2 "memory_operand" ""))
17356 (clobber (match_scratch 3 ""))]
17358 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17359 (clobber (match_dup 3))])]
17362 (define_insn_and_split "*fist<mode>2_1"
17363 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17364 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17366 "TARGET_USE_FANCY_MATH_387
17367 && !(reload_completed || reload_in_progress)"
17372 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17373 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17377 [(set_attr "type" "fpspc")
17378 (set_attr "mode" "<MODE>")])
17380 (define_insn "fist<mode>2"
17381 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17382 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17384 "TARGET_USE_FANCY_MATH_387"
17385 "* return output_fix_trunc (insn, operands, 0);"
17386 [(set_attr "type" "fpspc")
17387 (set_attr "mode" "<MODE>")])
17389 (define_insn "fist<mode>2_with_temp"
17390 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17391 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17393 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17394 "TARGET_USE_FANCY_MATH_387"
17396 [(set_attr "type" "fpspc")
17397 (set_attr "mode" "<MODE>")])
17400 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17401 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17403 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17405 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17407 (set (match_dup 0) (match_dup 2))]
17411 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17412 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17414 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17416 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17420 (define_expand "lrintxf<mode>2"
17421 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17422 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17424 "TARGET_USE_FANCY_MATH_387"
17427 (define_expand "lrint<mode>di2"
17428 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17429 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17430 UNSPEC_FIX_NOTRUNC))]
17431 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17434 (define_expand "lrint<mode>si2"
17435 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17436 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17437 UNSPEC_FIX_NOTRUNC))]
17438 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17441 (define_expand "lround<mode>di2"
17442 [(match_operand:DI 0 "nonimmediate_operand" "")
17443 (match_operand:SSEMODEF 1 "register_operand" "")]
17444 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17445 && !flag_trapping_math && !flag_rounding_math
17448 ix86_expand_lround (operand0, operand1);
17452 (define_expand "lround<mode>si2"
17453 [(match_operand:SI 0 "nonimmediate_operand" "")
17454 (match_operand:SSEMODEF 1 "register_operand" "")]
17455 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17456 && !flag_trapping_math && !flag_rounding_math
17459 ix86_expand_lround (operand0, operand1);
17463 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17464 (define_insn_and_split "frndintxf2_floor"
17465 [(set (match_operand:XF 0 "register_operand" "=f")
17466 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17467 UNSPEC_FRNDINT_FLOOR))
17468 (clobber (reg:CC FLAGS_REG))]
17469 "TARGET_USE_FANCY_MATH_387
17470 && flag_unsafe_math_optimizations
17471 && !(reload_completed || reload_in_progress)"
17476 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17478 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17479 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17481 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17482 operands[2], operands[3]));
17485 [(set_attr "type" "frndint")
17486 (set_attr "i387_cw" "floor")
17487 (set_attr "mode" "XF")])
17489 (define_insn "frndintxf2_floor_i387"
17490 [(set (match_operand:XF 0 "register_operand" "=f")
17491 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17492 UNSPEC_FRNDINT_FLOOR))
17493 (use (match_operand:HI 2 "memory_operand" "m"))
17494 (use (match_operand:HI 3 "memory_operand" "m"))]
17495 "TARGET_USE_FANCY_MATH_387
17496 && flag_unsafe_math_optimizations"
17497 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17498 [(set_attr "type" "frndint")
17499 (set_attr "i387_cw" "floor")
17500 (set_attr "mode" "XF")])
17502 (define_expand "floorxf2"
17503 [(use (match_operand:XF 0 "register_operand" ""))
17504 (use (match_operand:XF 1 "register_operand" ""))]
17505 "TARGET_USE_FANCY_MATH_387
17506 && flag_unsafe_math_optimizations && !optimize_size"
17508 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17512 (define_expand "floordf2"
17513 [(use (match_operand:DF 0 "register_operand" ""))
17514 (use (match_operand:DF 1 "register_operand" ""))]
17515 "((TARGET_USE_FANCY_MATH_387
17516 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17517 && flag_unsafe_math_optimizations)
17518 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17519 && !flag_trapping_math))
17522 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17523 && !flag_trapping_math)
17526 ix86_expand_floorceil (operand0, operand1, true);
17528 ix86_expand_floorceildf_32 (operand0, operand1, true);
17532 rtx op0 = gen_reg_rtx (XFmode);
17533 rtx op1 = gen_reg_rtx (XFmode);
17535 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17536 emit_insn (gen_frndintxf2_floor (op0, op1));
17538 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17543 (define_expand "floorsf2"
17544 [(use (match_operand:SF 0 "register_operand" ""))
17545 (use (match_operand:SF 1 "register_operand" ""))]
17546 "((TARGET_USE_FANCY_MATH_387
17547 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17548 && flag_unsafe_math_optimizations)
17549 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17550 && !flag_trapping_math))
17553 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17554 && !flag_trapping_math)
17555 ix86_expand_floorceil (operand0, operand1, true);
17558 rtx op0 = gen_reg_rtx (XFmode);
17559 rtx op1 = gen_reg_rtx (XFmode);
17561 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17562 emit_insn (gen_frndintxf2_floor (op0, op1));
17564 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17569 (define_insn_and_split "*fist<mode>2_floor_1"
17570 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17571 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17572 UNSPEC_FIST_FLOOR))
17573 (clobber (reg:CC FLAGS_REG))]
17574 "TARGET_USE_FANCY_MATH_387
17575 && flag_unsafe_math_optimizations
17576 && !(reload_completed || reload_in_progress)"
17581 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17583 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17584 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17585 if (memory_operand (operands[0], VOIDmode))
17586 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17587 operands[2], operands[3]));
17590 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17591 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17592 operands[2], operands[3],
17597 [(set_attr "type" "fistp")
17598 (set_attr "i387_cw" "floor")
17599 (set_attr "mode" "<MODE>")])
17601 (define_insn "fistdi2_floor"
17602 [(set (match_operand:DI 0 "memory_operand" "=m")
17603 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17604 UNSPEC_FIST_FLOOR))
17605 (use (match_operand:HI 2 "memory_operand" "m"))
17606 (use (match_operand:HI 3 "memory_operand" "m"))
17607 (clobber (match_scratch:XF 4 "=&1f"))]
17608 "TARGET_USE_FANCY_MATH_387
17609 && flag_unsafe_math_optimizations"
17610 "* return output_fix_trunc (insn, operands, 0);"
17611 [(set_attr "type" "fistp")
17612 (set_attr "i387_cw" "floor")
17613 (set_attr "mode" "DI")])
17615 (define_insn "fistdi2_floor_with_temp"
17616 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17617 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17618 UNSPEC_FIST_FLOOR))
17619 (use (match_operand:HI 2 "memory_operand" "m,m"))
17620 (use (match_operand:HI 3 "memory_operand" "m,m"))
17621 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17622 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17623 "TARGET_USE_FANCY_MATH_387
17624 && flag_unsafe_math_optimizations"
17626 [(set_attr "type" "fistp")
17627 (set_attr "i387_cw" "floor")
17628 (set_attr "mode" "DI")])
17631 [(set (match_operand:DI 0 "register_operand" "")
17632 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17633 UNSPEC_FIST_FLOOR))
17634 (use (match_operand:HI 2 "memory_operand" ""))
17635 (use (match_operand:HI 3 "memory_operand" ""))
17636 (clobber (match_operand:DI 4 "memory_operand" ""))
17637 (clobber (match_scratch 5 ""))]
17639 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17640 (use (match_dup 2))
17641 (use (match_dup 3))
17642 (clobber (match_dup 5))])
17643 (set (match_dup 0) (match_dup 4))]
17647 [(set (match_operand:DI 0 "memory_operand" "")
17648 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17649 UNSPEC_FIST_FLOOR))
17650 (use (match_operand:HI 2 "memory_operand" ""))
17651 (use (match_operand:HI 3 "memory_operand" ""))
17652 (clobber (match_operand:DI 4 "memory_operand" ""))
17653 (clobber (match_scratch 5 ""))]
17655 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17656 (use (match_dup 2))
17657 (use (match_dup 3))
17658 (clobber (match_dup 5))])]
17661 (define_insn "fist<mode>2_floor"
17662 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17663 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17664 UNSPEC_FIST_FLOOR))
17665 (use (match_operand:HI 2 "memory_operand" "m"))
17666 (use (match_operand:HI 3 "memory_operand" "m"))]
17667 "TARGET_USE_FANCY_MATH_387
17668 && flag_unsafe_math_optimizations"
17669 "* return output_fix_trunc (insn, operands, 0);"
17670 [(set_attr "type" "fistp")
17671 (set_attr "i387_cw" "floor")
17672 (set_attr "mode" "<MODE>")])
17674 (define_insn "fist<mode>2_floor_with_temp"
17675 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17676 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17677 UNSPEC_FIST_FLOOR))
17678 (use (match_operand:HI 2 "memory_operand" "m,m"))
17679 (use (match_operand:HI 3 "memory_operand" "m,m"))
17680 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17681 "TARGET_USE_FANCY_MATH_387
17682 && flag_unsafe_math_optimizations"
17684 [(set_attr "type" "fistp")
17685 (set_attr "i387_cw" "floor")
17686 (set_attr "mode" "<MODE>")])
17689 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17690 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17691 UNSPEC_FIST_FLOOR))
17692 (use (match_operand:HI 2 "memory_operand" ""))
17693 (use (match_operand:HI 3 "memory_operand" ""))
17694 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17696 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17697 UNSPEC_FIST_FLOOR))
17698 (use (match_dup 2))
17699 (use (match_dup 3))])
17700 (set (match_dup 0) (match_dup 4))]
17704 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17705 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17706 UNSPEC_FIST_FLOOR))
17707 (use (match_operand:HI 2 "memory_operand" ""))
17708 (use (match_operand:HI 3 "memory_operand" ""))
17709 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17711 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17712 UNSPEC_FIST_FLOOR))
17713 (use (match_dup 2))
17714 (use (match_dup 3))])]
17717 (define_expand "lfloorxf<mode>2"
17718 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17719 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17720 UNSPEC_FIST_FLOOR))
17721 (clobber (reg:CC FLAGS_REG))])]
17722 "TARGET_USE_FANCY_MATH_387
17723 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17724 && flag_unsafe_math_optimizations"
17727 (define_expand "lfloor<mode>di2"
17728 [(match_operand:DI 0 "nonimmediate_operand" "")
17729 (match_operand:SSEMODEF 1 "register_operand" "")]
17730 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17731 && !flag_trapping_math
17734 ix86_expand_lfloorceil (operand0, operand1, true);
17738 (define_expand "lfloor<mode>si2"
17739 [(match_operand:SI 0 "nonimmediate_operand" "")
17740 (match_operand:SSEMODEF 1 "register_operand" "")]
17741 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17742 && !flag_trapping_math
17743 && (!optimize_size || !TARGET_64BIT)"
17745 ix86_expand_lfloorceil (operand0, operand1, true);
17749 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17750 (define_insn_and_split "frndintxf2_ceil"
17751 [(set (match_operand:XF 0 "register_operand" "=f")
17752 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17753 UNSPEC_FRNDINT_CEIL))
17754 (clobber (reg:CC FLAGS_REG))]
17755 "TARGET_USE_FANCY_MATH_387
17756 && flag_unsafe_math_optimizations
17757 && !(reload_completed || reload_in_progress)"
17762 ix86_optimize_mode_switching[I387_CEIL] = 1;
17764 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17765 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17767 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17768 operands[2], operands[3]));
17771 [(set_attr "type" "frndint")
17772 (set_attr "i387_cw" "ceil")
17773 (set_attr "mode" "XF")])
17775 (define_insn "frndintxf2_ceil_i387"
17776 [(set (match_operand:XF 0 "register_operand" "=f")
17777 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17778 UNSPEC_FRNDINT_CEIL))
17779 (use (match_operand:HI 2 "memory_operand" "m"))
17780 (use (match_operand:HI 3 "memory_operand" "m"))]
17781 "TARGET_USE_FANCY_MATH_387
17782 && flag_unsafe_math_optimizations"
17783 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17784 [(set_attr "type" "frndint")
17785 (set_attr "i387_cw" "ceil")
17786 (set_attr "mode" "XF")])
17788 (define_expand "ceilxf2"
17789 [(use (match_operand:XF 0 "register_operand" ""))
17790 (use (match_operand:XF 1 "register_operand" ""))]
17791 "TARGET_USE_FANCY_MATH_387
17792 && flag_unsafe_math_optimizations && !optimize_size"
17794 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17798 (define_expand "ceildf2"
17799 [(use (match_operand:DF 0 "register_operand" ""))
17800 (use (match_operand:DF 1 "register_operand" ""))]
17801 "((TARGET_USE_FANCY_MATH_387
17802 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17803 && flag_unsafe_math_optimizations)
17804 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17805 && !flag_trapping_math))
17808 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17809 && !flag_trapping_math)
17812 ix86_expand_floorceil (operand0, operand1, false);
17814 ix86_expand_floorceildf_32 (operand0, operand1, false);
17818 rtx op0 = gen_reg_rtx (XFmode);
17819 rtx op1 = gen_reg_rtx (XFmode);
17821 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17822 emit_insn (gen_frndintxf2_ceil (op0, op1));
17824 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17829 (define_expand "ceilsf2"
17830 [(use (match_operand:SF 0 "register_operand" ""))
17831 (use (match_operand:SF 1 "register_operand" ""))]
17832 "((TARGET_USE_FANCY_MATH_387
17833 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17834 && flag_unsafe_math_optimizations)
17835 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17836 && !flag_trapping_math))
17839 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17840 && !flag_trapping_math)
17841 ix86_expand_floorceil (operand0, operand1, false);
17844 rtx op0 = gen_reg_rtx (XFmode);
17845 rtx op1 = gen_reg_rtx (XFmode);
17847 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17848 emit_insn (gen_frndintxf2_ceil (op0, op1));
17850 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17855 (define_insn_and_split "*fist<mode>2_ceil_1"
17856 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17857 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17859 (clobber (reg:CC FLAGS_REG))]
17860 "TARGET_USE_FANCY_MATH_387
17861 && flag_unsafe_math_optimizations
17862 && !(reload_completed || reload_in_progress)"
17867 ix86_optimize_mode_switching[I387_CEIL] = 1;
17869 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17870 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17871 if (memory_operand (operands[0], VOIDmode))
17872 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17873 operands[2], operands[3]));
17876 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17877 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17878 operands[2], operands[3],
17883 [(set_attr "type" "fistp")
17884 (set_attr "i387_cw" "ceil")
17885 (set_attr "mode" "<MODE>")])
17887 (define_insn "fistdi2_ceil"
17888 [(set (match_operand:DI 0 "memory_operand" "=m")
17889 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17891 (use (match_operand:HI 2 "memory_operand" "m"))
17892 (use (match_operand:HI 3 "memory_operand" "m"))
17893 (clobber (match_scratch:XF 4 "=&1f"))]
17894 "TARGET_USE_FANCY_MATH_387
17895 && flag_unsafe_math_optimizations"
17896 "* return output_fix_trunc (insn, operands, 0);"
17897 [(set_attr "type" "fistp")
17898 (set_attr "i387_cw" "ceil")
17899 (set_attr "mode" "DI")])
17901 (define_insn "fistdi2_ceil_with_temp"
17902 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17903 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17905 (use (match_operand:HI 2 "memory_operand" "m,m"))
17906 (use (match_operand:HI 3 "memory_operand" "m,m"))
17907 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17908 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17909 "TARGET_USE_FANCY_MATH_387
17910 && flag_unsafe_math_optimizations"
17912 [(set_attr "type" "fistp")
17913 (set_attr "i387_cw" "ceil")
17914 (set_attr "mode" "DI")])
17917 [(set (match_operand:DI 0 "register_operand" "")
17918 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17920 (use (match_operand:HI 2 "memory_operand" ""))
17921 (use (match_operand:HI 3 "memory_operand" ""))
17922 (clobber (match_operand:DI 4 "memory_operand" ""))
17923 (clobber (match_scratch 5 ""))]
17925 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17926 (use (match_dup 2))
17927 (use (match_dup 3))
17928 (clobber (match_dup 5))])
17929 (set (match_dup 0) (match_dup 4))]
17933 [(set (match_operand:DI 0 "memory_operand" "")
17934 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17936 (use (match_operand:HI 2 "memory_operand" ""))
17937 (use (match_operand:HI 3 "memory_operand" ""))
17938 (clobber (match_operand:DI 4 "memory_operand" ""))
17939 (clobber (match_scratch 5 ""))]
17941 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17942 (use (match_dup 2))
17943 (use (match_dup 3))
17944 (clobber (match_dup 5))])]
17947 (define_insn "fist<mode>2_ceil"
17948 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17949 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17951 (use (match_operand:HI 2 "memory_operand" "m"))
17952 (use (match_operand:HI 3 "memory_operand" "m"))]
17953 "TARGET_USE_FANCY_MATH_387
17954 && flag_unsafe_math_optimizations"
17955 "* return output_fix_trunc (insn, operands, 0);"
17956 [(set_attr "type" "fistp")
17957 (set_attr "i387_cw" "ceil")
17958 (set_attr "mode" "<MODE>")])
17960 (define_insn "fist<mode>2_ceil_with_temp"
17961 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17962 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17964 (use (match_operand:HI 2 "memory_operand" "m,m"))
17965 (use (match_operand:HI 3 "memory_operand" "m,m"))
17966 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17967 "TARGET_USE_FANCY_MATH_387
17968 && flag_unsafe_math_optimizations"
17970 [(set_attr "type" "fistp")
17971 (set_attr "i387_cw" "ceil")
17972 (set_attr "mode" "<MODE>")])
17975 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17976 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17978 (use (match_operand:HI 2 "memory_operand" ""))
17979 (use (match_operand:HI 3 "memory_operand" ""))
17980 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17982 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17984 (use (match_dup 2))
17985 (use (match_dup 3))])
17986 (set (match_dup 0) (match_dup 4))]
17990 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17991 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17993 (use (match_operand:HI 2 "memory_operand" ""))
17994 (use (match_operand:HI 3 "memory_operand" ""))
17995 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17997 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17999 (use (match_dup 2))
18000 (use (match_dup 3))])]
18003 (define_expand "lceilxf<mode>2"
18004 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18005 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18007 (clobber (reg:CC FLAGS_REG))])]
18008 "TARGET_USE_FANCY_MATH_387
18009 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18010 && flag_unsafe_math_optimizations"
18013 (define_expand "lceil<mode>di2"
18014 [(match_operand:DI 0 "nonimmediate_operand" "")
18015 (match_operand:SSEMODEF 1 "register_operand" "")]
18016 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18017 && !flag_trapping_math"
18019 ix86_expand_lfloorceil (operand0, operand1, false);
18023 (define_expand "lceil<mode>si2"
18024 [(match_operand:SI 0 "nonimmediate_operand" "")
18025 (match_operand:SSEMODEF 1 "register_operand" "")]
18026 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18027 && !flag_trapping_math"
18029 ix86_expand_lfloorceil (operand0, operand1, false);
18033 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18034 (define_insn_and_split "frndintxf2_trunc"
18035 [(set (match_operand:XF 0 "register_operand" "=f")
18036 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18037 UNSPEC_FRNDINT_TRUNC))
18038 (clobber (reg:CC FLAGS_REG))]
18039 "TARGET_USE_FANCY_MATH_387
18040 && flag_unsafe_math_optimizations
18041 && !(reload_completed || reload_in_progress)"
18046 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18048 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18049 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18051 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18052 operands[2], operands[3]));
18055 [(set_attr "type" "frndint")
18056 (set_attr "i387_cw" "trunc")
18057 (set_attr "mode" "XF")])
18059 (define_insn "frndintxf2_trunc_i387"
18060 [(set (match_operand:XF 0 "register_operand" "=f")
18061 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18062 UNSPEC_FRNDINT_TRUNC))
18063 (use (match_operand:HI 2 "memory_operand" "m"))
18064 (use (match_operand:HI 3 "memory_operand" "m"))]
18065 "TARGET_USE_FANCY_MATH_387
18066 && flag_unsafe_math_optimizations"
18067 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18068 [(set_attr "type" "frndint")
18069 (set_attr "i387_cw" "trunc")
18070 (set_attr "mode" "XF")])
18072 (define_expand "btruncxf2"
18073 [(use (match_operand:XF 0 "register_operand" ""))
18074 (use (match_operand:XF 1 "register_operand" ""))]
18075 "TARGET_USE_FANCY_MATH_387
18076 && flag_unsafe_math_optimizations && !optimize_size"
18078 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18082 (define_expand "btruncdf2"
18083 [(use (match_operand:DF 0 "register_operand" ""))
18084 (use (match_operand:DF 1 "register_operand" ""))]
18085 "((TARGET_USE_FANCY_MATH_387
18086 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18087 && flag_unsafe_math_optimizations)
18088 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18089 && !flag_trapping_math))
18092 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18093 && !flag_trapping_math)
18096 ix86_expand_trunc (operand0, operand1);
18098 ix86_expand_truncdf_32 (operand0, operand1);
18102 rtx op0 = gen_reg_rtx (XFmode);
18103 rtx op1 = gen_reg_rtx (XFmode);
18105 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18106 emit_insn (gen_frndintxf2_trunc (op0, op1));
18108 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18113 (define_expand "btruncsf2"
18114 [(use (match_operand:SF 0 "register_operand" ""))
18115 (use (match_operand:SF 1 "register_operand" ""))]
18116 "((TARGET_USE_FANCY_MATH_387
18117 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18118 && flag_unsafe_math_optimizations)
18119 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18120 && !flag_trapping_math))
18123 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18124 && !flag_trapping_math)
18125 ix86_expand_trunc (operand0, operand1);
18128 rtx op0 = gen_reg_rtx (XFmode);
18129 rtx op1 = gen_reg_rtx (XFmode);
18131 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18132 emit_insn (gen_frndintxf2_trunc (op0, op1));
18134 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18139 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18140 (define_insn_and_split "frndintxf2_mask_pm"
18141 [(set (match_operand:XF 0 "register_operand" "=f")
18142 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18143 UNSPEC_FRNDINT_MASK_PM))
18144 (clobber (reg:CC FLAGS_REG))]
18145 "TARGET_USE_FANCY_MATH_387
18146 && flag_unsafe_math_optimizations
18147 && !(reload_completed || reload_in_progress)"
18152 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18154 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18155 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18157 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18158 operands[2], operands[3]));
18161 [(set_attr "type" "frndint")
18162 (set_attr "i387_cw" "mask_pm")
18163 (set_attr "mode" "XF")])
18165 (define_insn "frndintxf2_mask_pm_i387"
18166 [(set (match_operand:XF 0 "register_operand" "=f")
18167 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18168 UNSPEC_FRNDINT_MASK_PM))
18169 (use (match_operand:HI 2 "memory_operand" "m"))
18170 (use (match_operand:HI 3 "memory_operand" "m"))]
18171 "TARGET_USE_FANCY_MATH_387
18172 && flag_unsafe_math_optimizations"
18173 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18174 [(set_attr "type" "frndint")
18175 (set_attr "i387_cw" "mask_pm")
18176 (set_attr "mode" "XF")])
18178 (define_expand "nearbyintxf2"
18179 [(use (match_operand:XF 0 "register_operand" ""))
18180 (use (match_operand:XF 1 "register_operand" ""))]
18181 "TARGET_USE_FANCY_MATH_387
18182 && flag_unsafe_math_optimizations"
18184 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18189 (define_expand "nearbyintdf2"
18190 [(use (match_operand:DF 0 "register_operand" ""))
18191 (use (match_operand:DF 1 "register_operand" ""))]
18192 "TARGET_USE_FANCY_MATH_387
18193 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18194 && flag_unsafe_math_optimizations"
18196 rtx op0 = gen_reg_rtx (XFmode);
18197 rtx op1 = gen_reg_rtx (XFmode);
18199 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18200 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18202 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18206 (define_expand "nearbyintsf2"
18207 [(use (match_operand:SF 0 "register_operand" ""))
18208 (use (match_operand:SF 1 "register_operand" ""))]
18209 "TARGET_USE_FANCY_MATH_387
18210 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18211 && flag_unsafe_math_optimizations"
18213 rtx op0 = gen_reg_rtx (XFmode);
18214 rtx op1 = gen_reg_rtx (XFmode);
18216 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18217 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18219 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18223 (define_insn "fxam<mode>2_i387"
18224 [(set (match_operand:HI 0 "register_operand" "=a")
18226 [(match_operand:X87MODEF 1 "register_operand" "f")]
18228 "TARGET_USE_FANCY_MATH_387"
18229 "fxam\n\tfnstsw\t%0"
18230 [(set_attr "type" "multi")
18231 (set_attr "unit" "i387")
18232 (set_attr "mode" "<MODE>")])
18234 (define_expand "isinf<mode>2"
18235 [(use (match_operand:SI 0 "register_operand" ""))
18236 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18237 "TARGET_USE_FANCY_MATH_387
18238 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18239 || TARGET_MIX_SSE_I387)"
18241 rtx mask = GEN_INT (0x45);
18242 rtx val = GEN_INT (0x05);
18246 rtx scratch = gen_reg_rtx (HImode);
18247 rtx res = gen_reg_rtx (QImode);
18249 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18250 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18251 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18252 cond = gen_rtx_fmt_ee (EQ, QImode,
18253 gen_rtx_REG (CCmode, FLAGS_REG),
18255 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18256 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18261 ;; Block operation instructions
18263 (define_expand "movmemsi"
18264 [(use (match_operand:BLK 0 "memory_operand" ""))
18265 (use (match_operand:BLK 1 "memory_operand" ""))
18266 (use (match_operand:SI 2 "nonmemory_operand" ""))
18267 (use (match_operand:SI 3 "const_int_operand" ""))
18268 (use (match_operand:SI 4 "const_int_operand" ""))
18269 (use (match_operand:SI 5 "const_int_operand" ""))]
18272 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18273 operands[4], operands[5]))
18279 (define_expand "movmemdi"
18280 [(use (match_operand:BLK 0 "memory_operand" ""))
18281 (use (match_operand:BLK 1 "memory_operand" ""))
18282 (use (match_operand:DI 2 "nonmemory_operand" ""))
18283 (use (match_operand:DI 3 "const_int_operand" ""))
18284 (use (match_operand:SI 4 "const_int_operand" ""))
18285 (use (match_operand:SI 5 "const_int_operand" ""))]
18288 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18289 operands[4], operands[5]))
18295 ;; Most CPUs don't like single string operations
18296 ;; Handle this case here to simplify previous expander.
18298 (define_expand "strmov"
18299 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18300 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18301 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18302 (clobber (reg:CC FLAGS_REG))])
18303 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18304 (clobber (reg:CC FLAGS_REG))])]
18307 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18309 /* If .md ever supports :P for Pmode, these can be directly
18310 in the pattern above. */
18311 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18312 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18314 if (TARGET_SINGLE_STRINGOP || optimize_size)
18316 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18317 operands[2], operands[3],
18318 operands[5], operands[6]));
18322 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18325 (define_expand "strmov_singleop"
18326 [(parallel [(set (match_operand 1 "memory_operand" "")
18327 (match_operand 3 "memory_operand" ""))
18328 (set (match_operand 0 "register_operand" "")
18329 (match_operand 4 "" ""))
18330 (set (match_operand 2 "register_operand" "")
18331 (match_operand 5 "" ""))])]
18332 "TARGET_SINGLE_STRINGOP || optimize_size"
18335 (define_insn "*strmovdi_rex_1"
18336 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18337 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18338 (set (match_operand:DI 0 "register_operand" "=D")
18339 (plus:DI (match_dup 2)
18341 (set (match_operand:DI 1 "register_operand" "=S")
18342 (plus:DI (match_dup 3)
18344 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18346 [(set_attr "type" "str")
18347 (set_attr "mode" "DI")
18348 (set_attr "memory" "both")])
18350 (define_insn "*strmovsi_1"
18351 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18352 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18353 (set (match_operand:SI 0 "register_operand" "=D")
18354 (plus:SI (match_dup 2)
18356 (set (match_operand:SI 1 "register_operand" "=S")
18357 (plus:SI (match_dup 3)
18359 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18361 [(set_attr "type" "str")
18362 (set_attr "mode" "SI")
18363 (set_attr "memory" "both")])
18365 (define_insn "*strmovsi_rex_1"
18366 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18367 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18368 (set (match_operand:DI 0 "register_operand" "=D")
18369 (plus:DI (match_dup 2)
18371 (set (match_operand:DI 1 "register_operand" "=S")
18372 (plus:DI (match_dup 3)
18374 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18376 [(set_attr "type" "str")
18377 (set_attr "mode" "SI")
18378 (set_attr "memory" "both")])
18380 (define_insn "*strmovhi_1"
18381 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18382 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18383 (set (match_operand:SI 0 "register_operand" "=D")
18384 (plus:SI (match_dup 2)
18386 (set (match_operand:SI 1 "register_operand" "=S")
18387 (plus:SI (match_dup 3)
18389 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18391 [(set_attr "type" "str")
18392 (set_attr "memory" "both")
18393 (set_attr "mode" "HI")])
18395 (define_insn "*strmovhi_rex_1"
18396 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18397 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18398 (set (match_operand:DI 0 "register_operand" "=D")
18399 (plus:DI (match_dup 2)
18401 (set (match_operand:DI 1 "register_operand" "=S")
18402 (plus:DI (match_dup 3)
18404 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18406 [(set_attr "type" "str")
18407 (set_attr "memory" "both")
18408 (set_attr "mode" "HI")])
18410 (define_insn "*strmovqi_1"
18411 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18412 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18413 (set (match_operand:SI 0 "register_operand" "=D")
18414 (plus:SI (match_dup 2)
18416 (set (match_operand:SI 1 "register_operand" "=S")
18417 (plus:SI (match_dup 3)
18419 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18421 [(set_attr "type" "str")
18422 (set_attr "memory" "both")
18423 (set_attr "mode" "QI")])
18425 (define_insn "*strmovqi_rex_1"
18426 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18427 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18428 (set (match_operand:DI 0 "register_operand" "=D")
18429 (plus:DI (match_dup 2)
18431 (set (match_operand:DI 1 "register_operand" "=S")
18432 (plus:DI (match_dup 3)
18434 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18436 [(set_attr "type" "str")
18437 (set_attr "memory" "both")
18438 (set_attr "mode" "QI")])
18440 (define_expand "rep_mov"
18441 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18442 (set (match_operand 0 "register_operand" "")
18443 (match_operand 5 "" ""))
18444 (set (match_operand 2 "register_operand" "")
18445 (match_operand 6 "" ""))
18446 (set (match_operand 1 "memory_operand" "")
18447 (match_operand 3 "memory_operand" ""))
18448 (use (match_dup 4))])]
18452 (define_insn "*rep_movdi_rex64"
18453 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18454 (set (match_operand:DI 0 "register_operand" "=D")
18455 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18457 (match_operand:DI 3 "register_operand" "0")))
18458 (set (match_operand:DI 1 "register_operand" "=S")
18459 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18460 (match_operand:DI 4 "register_operand" "1")))
18461 (set (mem:BLK (match_dup 3))
18462 (mem:BLK (match_dup 4)))
18463 (use (match_dup 5))]
18465 "{rep\;movsq|rep movsq}"
18466 [(set_attr "type" "str")
18467 (set_attr "prefix_rep" "1")
18468 (set_attr "memory" "both")
18469 (set_attr "mode" "DI")])
18471 (define_insn "*rep_movsi"
18472 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18473 (set (match_operand:SI 0 "register_operand" "=D")
18474 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18476 (match_operand:SI 3 "register_operand" "0")))
18477 (set (match_operand:SI 1 "register_operand" "=S")
18478 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18479 (match_operand:SI 4 "register_operand" "1")))
18480 (set (mem:BLK (match_dup 3))
18481 (mem:BLK (match_dup 4)))
18482 (use (match_dup 5))]
18484 "{rep\;movsl|rep movsd}"
18485 [(set_attr "type" "str")
18486 (set_attr "prefix_rep" "1")
18487 (set_attr "memory" "both")
18488 (set_attr "mode" "SI")])
18490 (define_insn "*rep_movsi_rex64"
18491 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18492 (set (match_operand:DI 0 "register_operand" "=D")
18493 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18495 (match_operand:DI 3 "register_operand" "0")))
18496 (set (match_operand:DI 1 "register_operand" "=S")
18497 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18498 (match_operand:DI 4 "register_operand" "1")))
18499 (set (mem:BLK (match_dup 3))
18500 (mem:BLK (match_dup 4)))
18501 (use (match_dup 5))]
18503 "{rep\;movsl|rep movsd}"
18504 [(set_attr "type" "str")
18505 (set_attr "prefix_rep" "1")
18506 (set_attr "memory" "both")
18507 (set_attr "mode" "SI")])
18509 (define_insn "*rep_movqi"
18510 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18511 (set (match_operand:SI 0 "register_operand" "=D")
18512 (plus:SI (match_operand:SI 3 "register_operand" "0")
18513 (match_operand:SI 5 "register_operand" "2")))
18514 (set (match_operand:SI 1 "register_operand" "=S")
18515 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18516 (set (mem:BLK (match_dup 3))
18517 (mem:BLK (match_dup 4)))
18518 (use (match_dup 5))]
18520 "{rep\;movsb|rep movsb}"
18521 [(set_attr "type" "str")
18522 (set_attr "prefix_rep" "1")
18523 (set_attr "memory" "both")
18524 (set_attr "mode" "SI")])
18526 (define_insn "*rep_movqi_rex64"
18527 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18528 (set (match_operand:DI 0 "register_operand" "=D")
18529 (plus:DI (match_operand:DI 3 "register_operand" "0")
18530 (match_operand:DI 5 "register_operand" "2")))
18531 (set (match_operand:DI 1 "register_operand" "=S")
18532 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18533 (set (mem:BLK (match_dup 3))
18534 (mem:BLK (match_dup 4)))
18535 (use (match_dup 5))]
18537 "{rep\;movsb|rep movsb}"
18538 [(set_attr "type" "str")
18539 (set_attr "prefix_rep" "1")
18540 (set_attr "memory" "both")
18541 (set_attr "mode" "SI")])
18543 (define_expand "setmemsi"
18544 [(use (match_operand:BLK 0 "memory_operand" ""))
18545 (use (match_operand:SI 1 "nonmemory_operand" ""))
18546 (use (match_operand 2 "const_int_operand" ""))
18547 (use (match_operand 3 "const_int_operand" ""))
18548 (use (match_operand:SI 4 "const_int_operand" ""))
18549 (use (match_operand:SI 5 "const_int_operand" ""))]
18552 if (ix86_expand_setmem (operands[0], operands[1],
18553 operands[2], operands[3],
18554 operands[4], operands[5]))
18560 (define_expand "setmemdi"
18561 [(use (match_operand:BLK 0 "memory_operand" ""))
18562 (use (match_operand:DI 1 "nonmemory_operand" ""))
18563 (use (match_operand 2 "const_int_operand" ""))
18564 (use (match_operand 3 "const_int_operand" ""))
18565 (use (match_operand 4 "const_int_operand" ""))
18566 (use (match_operand 5 "const_int_operand" ""))]
18569 if (ix86_expand_setmem (operands[0], operands[1],
18570 operands[2], operands[3],
18571 operands[4], operands[5]))
18577 ;; Most CPUs don't like single string operations
18578 ;; Handle this case here to simplify previous expander.
18580 (define_expand "strset"
18581 [(set (match_operand 1 "memory_operand" "")
18582 (match_operand 2 "register_operand" ""))
18583 (parallel [(set (match_operand 0 "register_operand" "")
18585 (clobber (reg:CC FLAGS_REG))])]
18588 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18589 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18591 /* If .md ever supports :P for Pmode, this can be directly
18592 in the pattern above. */
18593 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18594 GEN_INT (GET_MODE_SIZE (GET_MODE
18596 if (TARGET_SINGLE_STRINGOP || optimize_size)
18598 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18604 (define_expand "strset_singleop"
18605 [(parallel [(set (match_operand 1 "memory_operand" "")
18606 (match_operand 2 "register_operand" ""))
18607 (set (match_operand 0 "register_operand" "")
18608 (match_operand 3 "" ""))])]
18609 "TARGET_SINGLE_STRINGOP || optimize_size"
18612 (define_insn "*strsetdi_rex_1"
18613 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18614 (match_operand:DI 2 "register_operand" "a"))
18615 (set (match_operand:DI 0 "register_operand" "=D")
18616 (plus:DI (match_dup 1)
18618 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18620 [(set_attr "type" "str")
18621 (set_attr "memory" "store")
18622 (set_attr "mode" "DI")])
18624 (define_insn "*strsetsi_1"
18625 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18626 (match_operand:SI 2 "register_operand" "a"))
18627 (set (match_operand:SI 0 "register_operand" "=D")
18628 (plus:SI (match_dup 1)
18630 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18632 [(set_attr "type" "str")
18633 (set_attr "memory" "store")
18634 (set_attr "mode" "SI")])
18636 (define_insn "*strsetsi_rex_1"
18637 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18638 (match_operand:SI 2 "register_operand" "a"))
18639 (set (match_operand:DI 0 "register_operand" "=D")
18640 (plus:DI (match_dup 1)
18642 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18644 [(set_attr "type" "str")
18645 (set_attr "memory" "store")
18646 (set_attr "mode" "SI")])
18648 (define_insn "*strsethi_1"
18649 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18650 (match_operand:HI 2 "register_operand" "a"))
18651 (set (match_operand:SI 0 "register_operand" "=D")
18652 (plus:SI (match_dup 1)
18654 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18656 [(set_attr "type" "str")
18657 (set_attr "memory" "store")
18658 (set_attr "mode" "HI")])
18660 (define_insn "*strsethi_rex_1"
18661 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18662 (match_operand:HI 2 "register_operand" "a"))
18663 (set (match_operand:DI 0 "register_operand" "=D")
18664 (plus:DI (match_dup 1)
18666 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18668 [(set_attr "type" "str")
18669 (set_attr "memory" "store")
18670 (set_attr "mode" "HI")])
18672 (define_insn "*strsetqi_1"
18673 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18674 (match_operand:QI 2 "register_operand" "a"))
18675 (set (match_operand:SI 0 "register_operand" "=D")
18676 (plus:SI (match_dup 1)
18678 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18680 [(set_attr "type" "str")
18681 (set_attr "memory" "store")
18682 (set_attr "mode" "QI")])
18684 (define_insn "*strsetqi_rex_1"
18685 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18686 (match_operand:QI 2 "register_operand" "a"))
18687 (set (match_operand:DI 0 "register_operand" "=D")
18688 (plus:DI (match_dup 1)
18690 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18692 [(set_attr "type" "str")
18693 (set_attr "memory" "store")
18694 (set_attr "mode" "QI")])
18696 (define_expand "rep_stos"
18697 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18698 (set (match_operand 0 "register_operand" "")
18699 (match_operand 4 "" ""))
18700 (set (match_operand 2 "memory_operand" "") (const_int 0))
18701 (use (match_operand 3 "register_operand" ""))
18702 (use (match_dup 1))])]
18706 (define_insn "*rep_stosdi_rex64"
18707 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18708 (set (match_operand:DI 0 "register_operand" "=D")
18709 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18711 (match_operand:DI 3 "register_operand" "0")))
18712 (set (mem:BLK (match_dup 3))
18714 (use (match_operand:DI 2 "register_operand" "a"))
18715 (use (match_dup 4))]
18717 "{rep\;stosq|rep stosq}"
18718 [(set_attr "type" "str")
18719 (set_attr "prefix_rep" "1")
18720 (set_attr "memory" "store")
18721 (set_attr "mode" "DI")])
18723 (define_insn "*rep_stossi"
18724 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18725 (set (match_operand:SI 0 "register_operand" "=D")
18726 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18728 (match_operand:SI 3 "register_operand" "0")))
18729 (set (mem:BLK (match_dup 3))
18731 (use (match_operand:SI 2 "register_operand" "a"))
18732 (use (match_dup 4))]
18734 "{rep\;stosl|rep stosd}"
18735 [(set_attr "type" "str")
18736 (set_attr "prefix_rep" "1")
18737 (set_attr "memory" "store")
18738 (set_attr "mode" "SI")])
18740 (define_insn "*rep_stossi_rex64"
18741 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18742 (set (match_operand:DI 0 "register_operand" "=D")
18743 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18745 (match_operand:DI 3 "register_operand" "0")))
18746 (set (mem:BLK (match_dup 3))
18748 (use (match_operand:SI 2 "register_operand" "a"))
18749 (use (match_dup 4))]
18751 "{rep\;stosl|rep stosd}"
18752 [(set_attr "type" "str")
18753 (set_attr "prefix_rep" "1")
18754 (set_attr "memory" "store")
18755 (set_attr "mode" "SI")])
18757 (define_insn "*rep_stosqi"
18758 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18759 (set (match_operand:SI 0 "register_operand" "=D")
18760 (plus:SI (match_operand:SI 3 "register_operand" "0")
18761 (match_operand:SI 4 "register_operand" "1")))
18762 (set (mem:BLK (match_dup 3))
18764 (use (match_operand:QI 2 "register_operand" "a"))
18765 (use (match_dup 4))]
18767 "{rep\;stosb|rep stosb}"
18768 [(set_attr "type" "str")
18769 (set_attr "prefix_rep" "1")
18770 (set_attr "memory" "store")
18771 (set_attr "mode" "QI")])
18773 (define_insn "*rep_stosqi_rex64"
18774 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18775 (set (match_operand:DI 0 "register_operand" "=D")
18776 (plus:DI (match_operand:DI 3 "register_operand" "0")
18777 (match_operand:DI 4 "register_operand" "1")))
18778 (set (mem:BLK (match_dup 3))
18780 (use (match_operand:QI 2 "register_operand" "a"))
18781 (use (match_dup 4))]
18783 "{rep\;stosb|rep stosb}"
18784 [(set_attr "type" "str")
18785 (set_attr "prefix_rep" "1")
18786 (set_attr "memory" "store")
18787 (set_attr "mode" "QI")])
18789 (define_expand "cmpstrnsi"
18790 [(set (match_operand:SI 0 "register_operand" "")
18791 (compare:SI (match_operand:BLK 1 "general_operand" "")
18792 (match_operand:BLK 2 "general_operand" "")))
18793 (use (match_operand 3 "general_operand" ""))
18794 (use (match_operand 4 "immediate_operand" ""))]
18795 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18797 rtx addr1, addr2, out, outlow, count, countreg, align;
18799 /* Can't use this if the user has appropriated esi or edi. */
18800 if (global_regs[4] || global_regs[5])
18805 out = gen_reg_rtx (SImode);
18807 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18808 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18809 if (addr1 != XEXP (operands[1], 0))
18810 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18811 if (addr2 != XEXP (operands[2], 0))
18812 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18814 count = operands[3];
18815 countreg = ix86_zero_extend_to_Pmode (count);
18817 /* %%% Iff we are testing strict equality, we can use known alignment
18818 to good advantage. This may be possible with combine, particularly
18819 once cc0 is dead. */
18820 align = operands[4];
18822 if (CONST_INT_P (count))
18824 if (INTVAL (count) == 0)
18826 emit_move_insn (operands[0], const0_rtx);
18829 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18830 operands[1], operands[2]));
18835 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18837 emit_insn (gen_cmpsi_1 (countreg, countreg));
18838 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18839 operands[1], operands[2]));
18842 outlow = gen_lowpart (QImode, out);
18843 emit_insn (gen_cmpintqi (outlow));
18844 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18846 if (operands[0] != out)
18847 emit_move_insn (operands[0], out);
18852 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18854 (define_expand "cmpintqi"
18855 [(set (match_dup 1)
18856 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18858 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18859 (parallel [(set (match_operand:QI 0 "register_operand" "")
18860 (minus:QI (match_dup 1)
18862 (clobber (reg:CC FLAGS_REG))])]
18864 "operands[1] = gen_reg_rtx (QImode);
18865 operands[2] = gen_reg_rtx (QImode);")
18867 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18868 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18870 (define_expand "cmpstrnqi_nz_1"
18871 [(parallel [(set (reg:CC FLAGS_REG)
18872 (compare:CC (match_operand 4 "memory_operand" "")
18873 (match_operand 5 "memory_operand" "")))
18874 (use (match_operand 2 "register_operand" ""))
18875 (use (match_operand:SI 3 "immediate_operand" ""))
18876 (clobber (match_operand 0 "register_operand" ""))
18877 (clobber (match_operand 1 "register_operand" ""))
18878 (clobber (match_dup 2))])]
18882 (define_insn "*cmpstrnqi_nz_1"
18883 [(set (reg:CC FLAGS_REG)
18884 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18885 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18886 (use (match_operand:SI 6 "register_operand" "2"))
18887 (use (match_operand:SI 3 "immediate_operand" "i"))
18888 (clobber (match_operand:SI 0 "register_operand" "=S"))
18889 (clobber (match_operand:SI 1 "register_operand" "=D"))
18890 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18893 [(set_attr "type" "str")
18894 (set_attr "mode" "QI")
18895 (set_attr "prefix_rep" "1")])
18897 (define_insn "*cmpstrnqi_nz_rex_1"
18898 [(set (reg:CC FLAGS_REG)
18899 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18900 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18901 (use (match_operand:DI 6 "register_operand" "2"))
18902 (use (match_operand:SI 3 "immediate_operand" "i"))
18903 (clobber (match_operand:DI 0 "register_operand" "=S"))
18904 (clobber (match_operand:DI 1 "register_operand" "=D"))
18905 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18908 [(set_attr "type" "str")
18909 (set_attr "mode" "QI")
18910 (set_attr "prefix_rep" "1")])
18912 ;; The same, but the count is not known to not be zero.
18914 (define_expand "cmpstrnqi_1"
18915 [(parallel [(set (reg:CC FLAGS_REG)
18916 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18918 (compare:CC (match_operand 4 "memory_operand" "")
18919 (match_operand 5 "memory_operand" ""))
18921 (use (match_operand:SI 3 "immediate_operand" ""))
18922 (use (reg:CC FLAGS_REG))
18923 (clobber (match_operand 0 "register_operand" ""))
18924 (clobber (match_operand 1 "register_operand" ""))
18925 (clobber (match_dup 2))])]
18929 (define_insn "*cmpstrnqi_1"
18930 [(set (reg:CC FLAGS_REG)
18931 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18933 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18934 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18936 (use (match_operand:SI 3 "immediate_operand" "i"))
18937 (use (reg:CC FLAGS_REG))
18938 (clobber (match_operand:SI 0 "register_operand" "=S"))
18939 (clobber (match_operand:SI 1 "register_operand" "=D"))
18940 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18943 [(set_attr "type" "str")
18944 (set_attr "mode" "QI")
18945 (set_attr "prefix_rep" "1")])
18947 (define_insn "*cmpstrnqi_rex_1"
18948 [(set (reg:CC FLAGS_REG)
18949 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18951 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18952 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18954 (use (match_operand:SI 3 "immediate_operand" "i"))
18955 (use (reg:CC FLAGS_REG))
18956 (clobber (match_operand:DI 0 "register_operand" "=S"))
18957 (clobber (match_operand:DI 1 "register_operand" "=D"))
18958 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18961 [(set_attr "type" "str")
18962 (set_attr "mode" "QI")
18963 (set_attr "prefix_rep" "1")])
18965 (define_expand "strlensi"
18966 [(set (match_operand:SI 0 "register_operand" "")
18967 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18968 (match_operand:QI 2 "immediate_operand" "")
18969 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18972 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18978 (define_expand "strlendi"
18979 [(set (match_operand:DI 0 "register_operand" "")
18980 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18981 (match_operand:QI 2 "immediate_operand" "")
18982 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18985 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18991 (define_expand "strlenqi_1"
18992 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18993 (clobber (match_operand 1 "register_operand" ""))
18994 (clobber (reg:CC FLAGS_REG))])]
18998 (define_insn "*strlenqi_1"
18999 [(set (match_operand:SI 0 "register_operand" "=&c")
19000 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19001 (match_operand:QI 2 "register_operand" "a")
19002 (match_operand:SI 3 "immediate_operand" "i")
19003 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19004 (clobber (match_operand:SI 1 "register_operand" "=D"))
19005 (clobber (reg:CC FLAGS_REG))]
19008 [(set_attr "type" "str")
19009 (set_attr "mode" "QI")
19010 (set_attr "prefix_rep" "1")])
19012 (define_insn "*strlenqi_rex_1"
19013 [(set (match_operand:DI 0 "register_operand" "=&c")
19014 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19015 (match_operand:QI 2 "register_operand" "a")
19016 (match_operand:DI 3 "immediate_operand" "i")
19017 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19018 (clobber (match_operand:DI 1 "register_operand" "=D"))
19019 (clobber (reg:CC FLAGS_REG))]
19022 [(set_attr "type" "str")
19023 (set_attr "mode" "QI")
19024 (set_attr "prefix_rep" "1")])
19026 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19027 ;; handled in combine, but it is not currently up to the task.
19028 ;; When used for their truth value, the cmpstrn* expanders generate
19037 ;; The intermediate three instructions are unnecessary.
19039 ;; This one handles cmpstrn*_nz_1...
19042 (set (reg:CC FLAGS_REG)
19043 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19044 (mem:BLK (match_operand 5 "register_operand" ""))))
19045 (use (match_operand 6 "register_operand" ""))
19046 (use (match_operand:SI 3 "immediate_operand" ""))
19047 (clobber (match_operand 0 "register_operand" ""))
19048 (clobber (match_operand 1 "register_operand" ""))
19049 (clobber (match_operand 2 "register_operand" ""))])
19050 (set (match_operand:QI 7 "register_operand" "")
19051 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19052 (set (match_operand:QI 8 "register_operand" "")
19053 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19054 (set (reg FLAGS_REG)
19055 (compare (match_dup 7) (match_dup 8)))
19057 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19059 (set (reg:CC FLAGS_REG)
19060 (compare:CC (mem:BLK (match_dup 4))
19061 (mem:BLK (match_dup 5))))
19062 (use (match_dup 6))
19063 (use (match_dup 3))
19064 (clobber (match_dup 0))
19065 (clobber (match_dup 1))
19066 (clobber (match_dup 2))])]
19069 ;; ...and this one handles cmpstrn*_1.
19072 (set (reg:CC FLAGS_REG)
19073 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19075 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19076 (mem:BLK (match_operand 5 "register_operand" "")))
19078 (use (match_operand:SI 3 "immediate_operand" ""))
19079 (use (reg:CC FLAGS_REG))
19080 (clobber (match_operand 0 "register_operand" ""))
19081 (clobber (match_operand 1 "register_operand" ""))
19082 (clobber (match_operand 2 "register_operand" ""))])
19083 (set (match_operand:QI 7 "register_operand" "")
19084 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19085 (set (match_operand:QI 8 "register_operand" "")
19086 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19087 (set (reg FLAGS_REG)
19088 (compare (match_dup 7) (match_dup 8)))
19090 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19092 (set (reg:CC FLAGS_REG)
19093 (if_then_else:CC (ne (match_dup 6)
19095 (compare:CC (mem:BLK (match_dup 4))
19096 (mem:BLK (match_dup 5)))
19098 (use (match_dup 3))
19099 (use (reg:CC FLAGS_REG))
19100 (clobber (match_dup 0))
19101 (clobber (match_dup 1))
19102 (clobber (match_dup 2))])]
19107 ;; Conditional move instructions.
19109 (define_expand "movdicc"
19110 [(set (match_operand:DI 0 "register_operand" "")
19111 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19112 (match_operand:DI 2 "general_operand" "")
19113 (match_operand:DI 3 "general_operand" "")))]
19115 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19117 (define_insn "x86_movdicc_0_m1_rex64"
19118 [(set (match_operand:DI 0 "register_operand" "=r")
19119 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19122 (clobber (reg:CC FLAGS_REG))]
19125 ; Since we don't have the proper number of operands for an alu insn,
19126 ; fill in all the blanks.
19127 [(set_attr "type" "alu")
19128 (set_attr "pent_pair" "pu")
19129 (set_attr "memory" "none")
19130 (set_attr "imm_disp" "false")
19131 (set_attr "mode" "DI")
19132 (set_attr "length_immediate" "0")])
19134 (define_insn "*movdicc_c_rex64"
19135 [(set (match_operand:DI 0 "register_operand" "=r,r")
19136 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19137 [(reg FLAGS_REG) (const_int 0)])
19138 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19139 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19140 "TARGET_64BIT && TARGET_CMOVE
19141 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19143 cmov%O2%C1\t{%2, %0|%0, %2}
19144 cmov%O2%c1\t{%3, %0|%0, %3}"
19145 [(set_attr "type" "icmov")
19146 (set_attr "mode" "DI")])
19148 (define_expand "movsicc"
19149 [(set (match_operand:SI 0 "register_operand" "")
19150 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19151 (match_operand:SI 2 "general_operand" "")
19152 (match_operand:SI 3 "general_operand" "")))]
19154 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19156 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19157 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19158 ;; So just document what we're doing explicitly.
19160 (define_insn "x86_movsicc_0_m1"
19161 [(set (match_operand:SI 0 "register_operand" "=r")
19162 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19165 (clobber (reg:CC FLAGS_REG))]
19168 ; Since we don't have the proper number of operands for an alu insn,
19169 ; fill in all the blanks.
19170 [(set_attr "type" "alu")
19171 (set_attr "pent_pair" "pu")
19172 (set_attr "memory" "none")
19173 (set_attr "imm_disp" "false")
19174 (set_attr "mode" "SI")
19175 (set_attr "length_immediate" "0")])
19177 (define_insn "*movsicc_noc"
19178 [(set (match_operand:SI 0 "register_operand" "=r,r")
19179 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19180 [(reg FLAGS_REG) (const_int 0)])
19181 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19182 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19184 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19186 cmov%O2%C1\t{%2, %0|%0, %2}
19187 cmov%O2%c1\t{%3, %0|%0, %3}"
19188 [(set_attr "type" "icmov")
19189 (set_attr "mode" "SI")])
19191 (define_expand "movhicc"
19192 [(set (match_operand:HI 0 "register_operand" "")
19193 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19194 (match_operand:HI 2 "general_operand" "")
19195 (match_operand:HI 3 "general_operand" "")))]
19196 "TARGET_HIMODE_MATH"
19197 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19199 (define_insn "*movhicc_noc"
19200 [(set (match_operand:HI 0 "register_operand" "=r,r")
19201 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19202 [(reg FLAGS_REG) (const_int 0)])
19203 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19204 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19206 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19208 cmov%O2%C1\t{%2, %0|%0, %2}
19209 cmov%O2%c1\t{%3, %0|%0, %3}"
19210 [(set_attr "type" "icmov")
19211 (set_attr "mode" "HI")])
19213 (define_expand "movqicc"
19214 [(set (match_operand:QI 0 "register_operand" "")
19215 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19216 (match_operand:QI 2 "general_operand" "")
19217 (match_operand:QI 3 "general_operand" "")))]
19218 "TARGET_QIMODE_MATH"
19219 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19221 (define_insn_and_split "*movqicc_noc"
19222 [(set (match_operand:QI 0 "register_operand" "=r,r")
19223 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19224 [(match_operand 4 "flags_reg_operand" "")
19226 (match_operand:QI 2 "register_operand" "r,0")
19227 (match_operand:QI 3 "register_operand" "0,r")))]
19228 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19230 "&& reload_completed"
19231 [(set (match_dup 0)
19232 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19235 "operands[0] = gen_lowpart (SImode, operands[0]);
19236 operands[2] = gen_lowpart (SImode, operands[2]);
19237 operands[3] = gen_lowpart (SImode, operands[3]);"
19238 [(set_attr "type" "icmov")
19239 (set_attr "mode" "SI")])
19241 (define_expand "movsfcc"
19242 [(set (match_operand:SF 0 "register_operand" "")
19243 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19244 (match_operand:SF 2 "register_operand" "")
19245 (match_operand:SF 3 "register_operand" "")))]
19246 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19247 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19249 (define_insn "*movsfcc_1_387"
19250 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19251 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19252 [(reg FLAGS_REG) (const_int 0)])
19253 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19254 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19255 "TARGET_80387 && TARGET_CMOVE
19256 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19258 fcmov%F1\t{%2, %0|%0, %2}
19259 fcmov%f1\t{%3, %0|%0, %3}
19260 cmov%O2%C1\t{%2, %0|%0, %2}
19261 cmov%O2%c1\t{%3, %0|%0, %3}"
19262 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19263 (set_attr "mode" "SF,SF,SI,SI")])
19265 (define_expand "movdfcc"
19266 [(set (match_operand:DF 0 "register_operand" "")
19267 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19268 (match_operand:DF 2 "register_operand" "")
19269 (match_operand:DF 3 "register_operand" "")))]
19270 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19271 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19273 (define_insn "*movdfcc_1"
19274 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19275 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19276 [(reg FLAGS_REG) (const_int 0)])
19277 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19278 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19279 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19280 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19282 fcmov%F1\t{%2, %0|%0, %2}
19283 fcmov%f1\t{%3, %0|%0, %3}
19286 [(set_attr "type" "fcmov,fcmov,multi,multi")
19287 (set_attr "mode" "DF")])
19289 (define_insn "*movdfcc_1_rex64"
19290 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19291 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19292 [(reg FLAGS_REG) (const_int 0)])
19293 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19294 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19295 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19296 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19298 fcmov%F1\t{%2, %0|%0, %2}
19299 fcmov%f1\t{%3, %0|%0, %3}
19300 cmov%O2%C1\t{%2, %0|%0, %2}
19301 cmov%O2%c1\t{%3, %0|%0, %3}"
19302 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19303 (set_attr "mode" "DF")])
19306 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19307 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19308 [(match_operand 4 "flags_reg_operand" "")
19310 (match_operand:DF 2 "nonimmediate_operand" "")
19311 (match_operand:DF 3 "nonimmediate_operand" "")))]
19312 "!TARGET_64BIT && reload_completed"
19313 [(set (match_dup 2)
19314 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19318 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19321 "split_di (operands+2, 1, operands+5, operands+6);
19322 split_di (operands+3, 1, operands+7, operands+8);
19323 split_di (operands, 1, operands+2, operands+3);")
19325 (define_expand "movxfcc"
19326 [(set (match_operand:XF 0 "register_operand" "")
19327 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19328 (match_operand:XF 2 "register_operand" "")
19329 (match_operand:XF 3 "register_operand" "")))]
19330 "TARGET_80387 && TARGET_CMOVE"
19331 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19333 (define_insn "*movxfcc_1"
19334 [(set (match_operand:XF 0 "register_operand" "=f,f")
19335 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19336 [(reg FLAGS_REG) (const_int 0)])
19337 (match_operand:XF 2 "register_operand" "f,0")
19338 (match_operand:XF 3 "register_operand" "0,f")))]
19339 "TARGET_80387 && TARGET_CMOVE"
19341 fcmov%F1\t{%2, %0|%0, %2}
19342 fcmov%f1\t{%3, %0|%0, %3}"
19343 [(set_attr "type" "fcmov")
19344 (set_attr "mode" "XF")])
19346 ;; These versions of the min/max patterns are intentionally ignorant of
19347 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19348 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19349 ;; are undefined in this condition, we're certain this is correct.
19351 (define_insn "sminsf3"
19352 [(set (match_operand:SF 0 "register_operand" "=x")
19353 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19354 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19356 "minss\t{%2, %0|%0, %2}"
19357 [(set_attr "type" "sseadd")
19358 (set_attr "mode" "SF")])
19360 (define_insn "smaxsf3"
19361 [(set (match_operand:SF 0 "register_operand" "=x")
19362 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19363 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19365 "maxss\t{%2, %0|%0, %2}"
19366 [(set_attr "type" "sseadd")
19367 (set_attr "mode" "SF")])
19369 (define_insn "smindf3"
19370 [(set (match_operand:DF 0 "register_operand" "=x")
19371 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19372 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19373 "TARGET_SSE2 && TARGET_SSE_MATH"
19374 "minsd\t{%2, %0|%0, %2}"
19375 [(set_attr "type" "sseadd")
19376 (set_attr "mode" "DF")])
19378 (define_insn "smaxdf3"
19379 [(set (match_operand:DF 0 "register_operand" "=x")
19380 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19381 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19382 "TARGET_SSE2 && TARGET_SSE_MATH"
19383 "maxsd\t{%2, %0|%0, %2}"
19384 [(set_attr "type" "sseadd")
19385 (set_attr "mode" "DF")])
19387 ;; These versions of the min/max patterns implement exactly the operations
19388 ;; min = (op1 < op2 ? op1 : op2)
19389 ;; max = (!(op1 < op2) ? op1 : op2)
19390 ;; Their operands are not commutative, and thus they may be used in the
19391 ;; presence of -0.0 and NaN.
19393 (define_insn "*ieee_sminsf3"
19394 [(set (match_operand:SF 0 "register_operand" "=x")
19395 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19396 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19399 "minss\t{%2, %0|%0, %2}"
19400 [(set_attr "type" "sseadd")
19401 (set_attr "mode" "SF")])
19403 (define_insn "*ieee_smaxsf3"
19404 [(set (match_operand:SF 0 "register_operand" "=x")
19405 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19406 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19409 "maxss\t{%2, %0|%0, %2}"
19410 [(set_attr "type" "sseadd")
19411 (set_attr "mode" "SF")])
19413 (define_insn "*ieee_smindf3"
19414 [(set (match_operand:DF 0 "register_operand" "=x")
19415 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19416 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19418 "TARGET_SSE2 && TARGET_SSE_MATH"
19419 "minsd\t{%2, %0|%0, %2}"
19420 [(set_attr "type" "sseadd")
19421 (set_attr "mode" "DF")])
19423 (define_insn "*ieee_smaxdf3"
19424 [(set (match_operand:DF 0 "register_operand" "=x")
19425 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19426 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19428 "TARGET_SSE2 && TARGET_SSE_MATH"
19429 "maxsd\t{%2, %0|%0, %2}"
19430 [(set_attr "type" "sseadd")
19431 (set_attr "mode" "DF")])
19433 ;; Make two stack loads independent:
19435 ;; fld %st(0) -> fld bb
19436 ;; fmul bb fmul %st(1), %st
19438 ;; Actually we only match the last two instructions for simplicity.
19440 [(set (match_operand 0 "fp_register_operand" "")
19441 (match_operand 1 "fp_register_operand" ""))
19443 (match_operator 2 "binary_fp_operator"
19445 (match_operand 3 "memory_operand" "")]))]
19446 "REGNO (operands[0]) != REGNO (operands[1])"
19447 [(set (match_dup 0) (match_dup 3))
19448 (set (match_dup 0) (match_dup 4))]
19450 ;; The % modifier is not operational anymore in peephole2's, so we have to
19451 ;; swap the operands manually in the case of addition and multiplication.
19452 "if (COMMUTATIVE_ARITH_P (operands[2]))
19453 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19454 operands[0], operands[1]);
19456 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19457 operands[1], operands[0]);")
19459 ;; Conditional addition patterns
19460 (define_expand "addqicc"
19461 [(match_operand:QI 0 "register_operand" "")
19462 (match_operand 1 "comparison_operator" "")
19463 (match_operand:QI 2 "register_operand" "")
19464 (match_operand:QI 3 "const_int_operand" "")]
19466 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19468 (define_expand "addhicc"
19469 [(match_operand:HI 0 "register_operand" "")
19470 (match_operand 1 "comparison_operator" "")
19471 (match_operand:HI 2 "register_operand" "")
19472 (match_operand:HI 3 "const_int_operand" "")]
19474 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19476 (define_expand "addsicc"
19477 [(match_operand:SI 0 "register_operand" "")
19478 (match_operand 1 "comparison_operator" "")
19479 (match_operand:SI 2 "register_operand" "")
19480 (match_operand:SI 3 "const_int_operand" "")]
19482 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19484 (define_expand "adddicc"
19485 [(match_operand:DI 0 "register_operand" "")
19486 (match_operand 1 "comparison_operator" "")
19487 (match_operand:DI 2 "register_operand" "")
19488 (match_operand:DI 3 "const_int_operand" "")]
19490 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19493 ;; Misc patterns (?)
19495 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19496 ;; Otherwise there will be nothing to keep
19498 ;; [(set (reg ebp) (reg esp))]
19499 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19500 ;; (clobber (eflags)]
19501 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19503 ;; in proper program order.
19504 (define_insn "pro_epilogue_adjust_stack_1"
19505 [(set (match_operand:SI 0 "register_operand" "=r,r")
19506 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19507 (match_operand:SI 2 "immediate_operand" "i,i")))
19508 (clobber (reg:CC FLAGS_REG))
19509 (clobber (mem:BLK (scratch)))]
19512 switch (get_attr_type (insn))
19515 return "mov{l}\t{%1, %0|%0, %1}";
19518 if (CONST_INT_P (operands[2])
19519 && (INTVAL (operands[2]) == 128
19520 || (INTVAL (operands[2]) < 0
19521 && INTVAL (operands[2]) != -128)))
19523 operands[2] = GEN_INT (-INTVAL (operands[2]));
19524 return "sub{l}\t{%2, %0|%0, %2}";
19526 return "add{l}\t{%2, %0|%0, %2}";
19529 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19530 return "lea{l}\t{%a2, %0|%0, %a2}";
19533 gcc_unreachable ();
19536 [(set (attr "type")
19537 (cond [(eq_attr "alternative" "0")
19538 (const_string "alu")
19539 (match_operand:SI 2 "const0_operand" "")
19540 (const_string "imov")
19542 (const_string "lea")))
19543 (set_attr "mode" "SI")])
19545 (define_insn "pro_epilogue_adjust_stack_rex64"
19546 [(set (match_operand:DI 0 "register_operand" "=r,r")
19547 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19548 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19549 (clobber (reg:CC FLAGS_REG))
19550 (clobber (mem:BLK (scratch)))]
19553 switch (get_attr_type (insn))
19556 return "mov{q}\t{%1, %0|%0, %1}";
19559 if (CONST_INT_P (operands[2])
19560 /* Avoid overflows. */
19561 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19562 && (INTVAL (operands[2]) == 128
19563 || (INTVAL (operands[2]) < 0
19564 && INTVAL (operands[2]) != -128)))
19566 operands[2] = GEN_INT (-INTVAL (operands[2]));
19567 return "sub{q}\t{%2, %0|%0, %2}";
19569 return "add{q}\t{%2, %0|%0, %2}";
19572 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19573 return "lea{q}\t{%a2, %0|%0, %a2}";
19576 gcc_unreachable ();
19579 [(set (attr "type")
19580 (cond [(eq_attr "alternative" "0")
19581 (const_string "alu")
19582 (match_operand:DI 2 "const0_operand" "")
19583 (const_string "imov")
19585 (const_string "lea")))
19586 (set_attr "mode" "DI")])
19588 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19589 [(set (match_operand:DI 0 "register_operand" "=r,r")
19590 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19591 (match_operand:DI 3 "immediate_operand" "i,i")))
19592 (use (match_operand:DI 2 "register_operand" "r,r"))
19593 (clobber (reg:CC FLAGS_REG))
19594 (clobber (mem:BLK (scratch)))]
19597 switch (get_attr_type (insn))
19600 return "add{q}\t{%2, %0|%0, %2}";
19603 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19604 return "lea{q}\t{%a2, %0|%0, %a2}";
19607 gcc_unreachable ();
19610 [(set_attr "type" "alu,lea")
19611 (set_attr "mode" "DI")])
19613 (define_expand "allocate_stack_worker"
19614 [(match_operand:SI 0 "register_operand" "")]
19615 "TARGET_STACK_PROBE"
19617 if (reload_completed)
19620 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19622 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19627 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19629 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19634 (define_insn "allocate_stack_worker_1"
19635 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19636 UNSPECV_STACK_PROBE)
19637 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19638 (clobber (match_scratch:SI 1 "=0"))
19639 (clobber (reg:CC FLAGS_REG))]
19640 "!TARGET_64BIT && TARGET_STACK_PROBE"
19642 [(set_attr "type" "multi")
19643 (set_attr "length" "5")])
19645 (define_expand "allocate_stack_worker_postreload"
19646 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19647 UNSPECV_STACK_PROBE)
19648 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19649 (clobber (match_dup 0))
19650 (clobber (reg:CC FLAGS_REG))])]
19654 (define_insn "allocate_stack_worker_rex64"
19655 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19656 UNSPECV_STACK_PROBE)
19657 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19658 (clobber (match_scratch:DI 1 "=0"))
19659 (clobber (reg:CC FLAGS_REG))]
19660 "TARGET_64BIT && TARGET_STACK_PROBE"
19662 [(set_attr "type" "multi")
19663 (set_attr "length" "5")])
19665 (define_expand "allocate_stack_worker_rex64_postreload"
19666 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19667 UNSPECV_STACK_PROBE)
19668 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19669 (clobber (match_dup 0))
19670 (clobber (reg:CC FLAGS_REG))])]
19674 (define_expand "allocate_stack"
19675 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19676 (minus:SI (reg:SI SP_REG)
19677 (match_operand:SI 1 "general_operand" "")))
19678 (clobber (reg:CC FLAGS_REG))])
19679 (parallel [(set (reg:SI SP_REG)
19680 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19681 (clobber (reg:CC FLAGS_REG))])]
19682 "TARGET_STACK_PROBE"
19684 #ifdef CHECK_STACK_LIMIT
19685 if (CONST_INT_P (operands[1])
19686 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19687 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19691 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19694 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19698 (define_expand "builtin_setjmp_receiver"
19699 [(label_ref (match_operand 0 "" ""))]
19700 "!TARGET_64BIT && flag_pic"
19705 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19706 rtx label_rtx = gen_label_rtx ();
19707 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19708 xops[0] = xops[1] = picreg;
19709 xops[2] = gen_rtx_CONST (SImode,
19710 gen_rtx_MINUS (SImode,
19711 gen_rtx_LABEL_REF (SImode, label_rtx),
19712 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19713 ix86_expand_binary_operator (MINUS, SImode, xops);
19716 emit_insn (gen_set_got (pic_offset_table_rtx));
19720 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19723 [(set (match_operand 0 "register_operand" "")
19724 (match_operator 3 "promotable_binary_operator"
19725 [(match_operand 1 "register_operand" "")
19726 (match_operand 2 "aligned_operand" "")]))
19727 (clobber (reg:CC FLAGS_REG))]
19728 "! TARGET_PARTIAL_REG_STALL && reload_completed
19729 && ((GET_MODE (operands[0]) == HImode
19730 && ((!optimize_size && !TARGET_FAST_PREFIX)
19731 /* ??? next two lines just !satisfies_constraint_K (...) */
19732 || !CONST_INT_P (operands[2])
19733 || satisfies_constraint_K (operands[2])))
19734 || (GET_MODE (operands[0]) == QImode
19735 && (TARGET_PROMOTE_QImode || optimize_size)))"
19736 [(parallel [(set (match_dup 0)
19737 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19738 (clobber (reg:CC FLAGS_REG))])]
19739 "operands[0] = gen_lowpart (SImode, operands[0]);
19740 operands[1] = gen_lowpart (SImode, operands[1]);
19741 if (GET_CODE (operands[3]) != ASHIFT)
19742 operands[2] = gen_lowpart (SImode, operands[2]);
19743 PUT_MODE (operands[3], SImode);")
19745 ; Promote the QImode tests, as i386 has encoding of the AND
19746 ; instruction with 32-bit sign-extended immediate and thus the
19747 ; instruction size is unchanged, except in the %eax case for
19748 ; which it is increased by one byte, hence the ! optimize_size.
19750 [(set (match_operand 0 "flags_reg_operand" "")
19751 (match_operator 2 "compare_operator"
19752 [(and (match_operand 3 "aligned_operand" "")
19753 (match_operand 4 "const_int_operand" ""))
19755 (set (match_operand 1 "register_operand" "")
19756 (and (match_dup 3) (match_dup 4)))]
19757 "! TARGET_PARTIAL_REG_STALL && reload_completed
19758 /* Ensure that the operand will remain sign-extended immediate. */
19759 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19761 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19762 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19763 [(parallel [(set (match_dup 0)
19764 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19767 (and:SI (match_dup 3) (match_dup 4)))])]
19770 = gen_int_mode (INTVAL (operands[4])
19771 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19772 operands[1] = gen_lowpart (SImode, operands[1]);
19773 operands[3] = gen_lowpart (SImode, operands[3]);
19776 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19777 ; the TEST instruction with 32-bit sign-extended immediate and thus
19778 ; the instruction size would at least double, which is not what we
19779 ; want even with ! optimize_size.
19781 [(set (match_operand 0 "flags_reg_operand" "")
19782 (match_operator 1 "compare_operator"
19783 [(and (match_operand:HI 2 "aligned_operand" "")
19784 (match_operand:HI 3 "const_int_operand" ""))
19786 "! TARGET_PARTIAL_REG_STALL && reload_completed
19787 /* Ensure that the operand will remain sign-extended immediate. */
19788 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19789 && ! TARGET_FAST_PREFIX
19790 && ! optimize_size"
19791 [(set (match_dup 0)
19792 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19796 = gen_int_mode (INTVAL (operands[3])
19797 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19798 operands[2] = gen_lowpart (SImode, operands[2]);
19802 [(set (match_operand 0 "register_operand" "")
19803 (neg (match_operand 1 "register_operand" "")))
19804 (clobber (reg:CC FLAGS_REG))]
19805 "! TARGET_PARTIAL_REG_STALL && reload_completed
19806 && (GET_MODE (operands[0]) == HImode
19807 || (GET_MODE (operands[0]) == QImode
19808 && (TARGET_PROMOTE_QImode || optimize_size)))"
19809 [(parallel [(set (match_dup 0)
19810 (neg:SI (match_dup 1)))
19811 (clobber (reg:CC FLAGS_REG))])]
19812 "operands[0] = gen_lowpart (SImode, operands[0]);
19813 operands[1] = gen_lowpart (SImode, operands[1]);")
19816 [(set (match_operand 0 "register_operand" "")
19817 (not (match_operand 1 "register_operand" "")))]
19818 "! TARGET_PARTIAL_REG_STALL && reload_completed
19819 && (GET_MODE (operands[0]) == HImode
19820 || (GET_MODE (operands[0]) == QImode
19821 && (TARGET_PROMOTE_QImode || optimize_size)))"
19822 [(set (match_dup 0)
19823 (not:SI (match_dup 1)))]
19824 "operands[0] = gen_lowpart (SImode, operands[0]);
19825 operands[1] = gen_lowpart (SImode, operands[1]);")
19828 [(set (match_operand 0 "register_operand" "")
19829 (if_then_else (match_operator 1 "comparison_operator"
19830 [(reg FLAGS_REG) (const_int 0)])
19831 (match_operand 2 "register_operand" "")
19832 (match_operand 3 "register_operand" "")))]
19833 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19834 && (GET_MODE (operands[0]) == HImode
19835 || (GET_MODE (operands[0]) == QImode
19836 && (TARGET_PROMOTE_QImode || optimize_size)))"
19837 [(set (match_dup 0)
19838 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19839 "operands[0] = gen_lowpart (SImode, operands[0]);
19840 operands[2] = gen_lowpart (SImode, operands[2]);
19841 operands[3] = gen_lowpart (SImode, operands[3]);")
19844 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19845 ;; transform a complex memory operation into two memory to register operations.
19847 ;; Don't push memory operands
19849 [(set (match_operand:SI 0 "push_operand" "")
19850 (match_operand:SI 1 "memory_operand" ""))
19851 (match_scratch:SI 2 "r")]
19852 "!optimize_size && !TARGET_PUSH_MEMORY
19853 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19854 [(set (match_dup 2) (match_dup 1))
19855 (set (match_dup 0) (match_dup 2))]
19859 [(set (match_operand:DI 0 "push_operand" "")
19860 (match_operand:DI 1 "memory_operand" ""))
19861 (match_scratch:DI 2 "r")]
19862 "!optimize_size && !TARGET_PUSH_MEMORY
19863 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19864 [(set (match_dup 2) (match_dup 1))
19865 (set (match_dup 0) (match_dup 2))]
19868 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19871 [(set (match_operand:SF 0 "push_operand" "")
19872 (match_operand:SF 1 "memory_operand" ""))
19873 (match_scratch:SF 2 "r")]
19874 "!optimize_size && !TARGET_PUSH_MEMORY
19875 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19876 [(set (match_dup 2) (match_dup 1))
19877 (set (match_dup 0) (match_dup 2))]
19881 [(set (match_operand:HI 0 "push_operand" "")
19882 (match_operand:HI 1 "memory_operand" ""))
19883 (match_scratch:HI 2 "r")]
19884 "!optimize_size && !TARGET_PUSH_MEMORY
19885 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19886 [(set (match_dup 2) (match_dup 1))
19887 (set (match_dup 0) (match_dup 2))]
19891 [(set (match_operand:QI 0 "push_operand" "")
19892 (match_operand:QI 1 "memory_operand" ""))
19893 (match_scratch:QI 2 "q")]
19894 "!optimize_size && !TARGET_PUSH_MEMORY
19895 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19896 [(set (match_dup 2) (match_dup 1))
19897 (set (match_dup 0) (match_dup 2))]
19900 ;; Don't move an immediate directly to memory when the instruction
19903 [(match_scratch:SI 1 "r")
19904 (set (match_operand:SI 0 "memory_operand" "")
19907 && ! TARGET_USE_MOV0
19908 && TARGET_SPLIT_LONG_MOVES
19909 && get_attr_length (insn) >= ix86_cost->large_insn
19910 && peep2_regno_dead_p (0, FLAGS_REG)"
19911 [(parallel [(set (match_dup 1) (const_int 0))
19912 (clobber (reg:CC FLAGS_REG))])
19913 (set (match_dup 0) (match_dup 1))]
19917 [(match_scratch:HI 1 "r")
19918 (set (match_operand:HI 0 "memory_operand" "")
19921 && ! TARGET_USE_MOV0
19922 && TARGET_SPLIT_LONG_MOVES
19923 && get_attr_length (insn) >= ix86_cost->large_insn
19924 && peep2_regno_dead_p (0, FLAGS_REG)"
19925 [(parallel [(set (match_dup 2) (const_int 0))
19926 (clobber (reg:CC FLAGS_REG))])
19927 (set (match_dup 0) (match_dup 1))]
19928 "operands[2] = gen_lowpart (SImode, operands[1]);")
19931 [(match_scratch:QI 1 "q")
19932 (set (match_operand:QI 0 "memory_operand" "")
19935 && ! TARGET_USE_MOV0
19936 && TARGET_SPLIT_LONG_MOVES
19937 && get_attr_length (insn) >= ix86_cost->large_insn
19938 && peep2_regno_dead_p (0, FLAGS_REG)"
19939 [(parallel [(set (match_dup 2) (const_int 0))
19940 (clobber (reg:CC FLAGS_REG))])
19941 (set (match_dup 0) (match_dup 1))]
19942 "operands[2] = gen_lowpart (SImode, operands[1]);")
19945 [(match_scratch:SI 2 "r")
19946 (set (match_operand:SI 0 "memory_operand" "")
19947 (match_operand:SI 1 "immediate_operand" ""))]
19949 && get_attr_length (insn) >= ix86_cost->large_insn
19950 && TARGET_SPLIT_LONG_MOVES"
19951 [(set (match_dup 2) (match_dup 1))
19952 (set (match_dup 0) (match_dup 2))]
19956 [(match_scratch:HI 2 "r")
19957 (set (match_operand:HI 0 "memory_operand" "")
19958 (match_operand:HI 1 "immediate_operand" ""))]
19959 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19960 && TARGET_SPLIT_LONG_MOVES"
19961 [(set (match_dup 2) (match_dup 1))
19962 (set (match_dup 0) (match_dup 2))]
19966 [(match_scratch:QI 2 "q")
19967 (set (match_operand:QI 0 "memory_operand" "")
19968 (match_operand:QI 1 "immediate_operand" ""))]
19969 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19970 && TARGET_SPLIT_LONG_MOVES"
19971 [(set (match_dup 2) (match_dup 1))
19972 (set (match_dup 0) (match_dup 2))]
19975 ;; Don't compare memory with zero, load and use a test instead.
19977 [(set (match_operand 0 "flags_reg_operand" "")
19978 (match_operator 1 "compare_operator"
19979 [(match_operand:SI 2 "memory_operand" "")
19981 (match_scratch:SI 3 "r")]
19982 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19983 [(set (match_dup 3) (match_dup 2))
19984 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19987 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19988 ;; Don't split NOTs with a displacement operand, because resulting XOR
19989 ;; will not be pairable anyway.
19991 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19992 ;; represented using a modRM byte. The XOR replacement is long decoded,
19993 ;; so this split helps here as well.
19995 ;; Note: Can't do this as a regular split because we can't get proper
19996 ;; lifetime information then.
19999 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20000 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20002 && peep2_regno_dead_p (0, FLAGS_REG)
20003 && ((TARGET_PENTIUM
20004 && (!MEM_P (operands[0])
20005 || !memory_displacement_operand (operands[0], SImode)))
20006 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20007 [(parallel [(set (match_dup 0)
20008 (xor:SI (match_dup 1) (const_int -1)))
20009 (clobber (reg:CC FLAGS_REG))])]
20013 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20014 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20016 && peep2_regno_dead_p (0, FLAGS_REG)
20017 && ((TARGET_PENTIUM
20018 && (!MEM_P (operands[0])
20019 || !memory_displacement_operand (operands[0], HImode)))
20020 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20021 [(parallel [(set (match_dup 0)
20022 (xor:HI (match_dup 1) (const_int -1)))
20023 (clobber (reg:CC FLAGS_REG))])]
20027 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20028 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20030 && peep2_regno_dead_p (0, FLAGS_REG)
20031 && ((TARGET_PENTIUM
20032 && (!MEM_P (operands[0])
20033 || !memory_displacement_operand (operands[0], QImode)))
20034 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20035 [(parallel [(set (match_dup 0)
20036 (xor:QI (match_dup 1) (const_int -1)))
20037 (clobber (reg:CC FLAGS_REG))])]
20040 ;; Non pairable "test imm, reg" instructions can be translated to
20041 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20042 ;; byte opcode instead of two, have a short form for byte operands),
20043 ;; so do it for other CPUs as well. Given that the value was dead,
20044 ;; this should not create any new dependencies. Pass on the sub-word
20045 ;; versions if we're concerned about partial register stalls.
20048 [(set (match_operand 0 "flags_reg_operand" "")
20049 (match_operator 1 "compare_operator"
20050 [(and:SI (match_operand:SI 2 "register_operand" "")
20051 (match_operand:SI 3 "immediate_operand" ""))
20053 "ix86_match_ccmode (insn, CCNOmode)
20054 && (true_regnum (operands[2]) != 0
20055 || satisfies_constraint_K (operands[3]))
20056 && peep2_reg_dead_p (1, operands[2])"
20058 [(set (match_dup 0)
20059 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20062 (and:SI (match_dup 2) (match_dup 3)))])]
20065 ;; We don't need to handle HImode case, because it will be promoted to SImode
20066 ;; on ! TARGET_PARTIAL_REG_STALL
20069 [(set (match_operand 0 "flags_reg_operand" "")
20070 (match_operator 1 "compare_operator"
20071 [(and:QI (match_operand:QI 2 "register_operand" "")
20072 (match_operand:QI 3 "immediate_operand" ""))
20074 "! TARGET_PARTIAL_REG_STALL
20075 && ix86_match_ccmode (insn, CCNOmode)
20076 && true_regnum (operands[2]) != 0
20077 && peep2_reg_dead_p (1, operands[2])"
20079 [(set (match_dup 0)
20080 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20083 (and:QI (match_dup 2) (match_dup 3)))])]
20087 [(set (match_operand 0 "flags_reg_operand" "")
20088 (match_operator 1 "compare_operator"
20091 (match_operand 2 "ext_register_operand" "")
20094 (match_operand 3 "const_int_operand" ""))
20096 "! TARGET_PARTIAL_REG_STALL
20097 && ix86_match_ccmode (insn, CCNOmode)
20098 && true_regnum (operands[2]) != 0
20099 && peep2_reg_dead_p (1, operands[2])"
20100 [(parallel [(set (match_dup 0)
20109 (set (zero_extract:SI (match_dup 2)
20120 ;; Don't do logical operations with memory inputs.
20122 [(match_scratch:SI 2 "r")
20123 (parallel [(set (match_operand:SI 0 "register_operand" "")
20124 (match_operator:SI 3 "arith_or_logical_operator"
20126 (match_operand:SI 1 "memory_operand" "")]))
20127 (clobber (reg:CC FLAGS_REG))])]
20128 "! optimize_size && ! TARGET_READ_MODIFY"
20129 [(set (match_dup 2) (match_dup 1))
20130 (parallel [(set (match_dup 0)
20131 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20132 (clobber (reg:CC FLAGS_REG))])]
20136 [(match_scratch:SI 2 "r")
20137 (parallel [(set (match_operand:SI 0 "register_operand" "")
20138 (match_operator:SI 3 "arith_or_logical_operator"
20139 [(match_operand:SI 1 "memory_operand" "")
20141 (clobber (reg:CC FLAGS_REG))])]
20142 "! optimize_size && ! TARGET_READ_MODIFY"
20143 [(set (match_dup 2) (match_dup 1))
20144 (parallel [(set (match_dup 0)
20145 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20146 (clobber (reg:CC FLAGS_REG))])]
20149 ; Don't do logical operations with memory outputs
20151 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20152 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20153 ; the same decoder scheduling characteristics as the original.
20156 [(match_scratch:SI 2 "r")
20157 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20158 (match_operator:SI 3 "arith_or_logical_operator"
20160 (match_operand:SI 1 "nonmemory_operand" "")]))
20161 (clobber (reg:CC FLAGS_REG))])]
20162 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20163 [(set (match_dup 2) (match_dup 0))
20164 (parallel [(set (match_dup 2)
20165 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20166 (clobber (reg:CC FLAGS_REG))])
20167 (set (match_dup 0) (match_dup 2))]
20171 [(match_scratch:SI 2 "r")
20172 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20173 (match_operator:SI 3 "arith_or_logical_operator"
20174 [(match_operand:SI 1 "nonmemory_operand" "")
20176 (clobber (reg:CC FLAGS_REG))])]
20177 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20178 [(set (match_dup 2) (match_dup 0))
20179 (parallel [(set (match_dup 2)
20180 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20181 (clobber (reg:CC FLAGS_REG))])
20182 (set (match_dup 0) (match_dup 2))]
20185 ;; Attempt to always use XOR for zeroing registers.
20187 [(set (match_operand 0 "register_operand" "")
20188 (match_operand 1 "const0_operand" ""))]
20189 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20190 && (! TARGET_USE_MOV0 || optimize_size)
20191 && GENERAL_REG_P (operands[0])
20192 && peep2_regno_dead_p (0, FLAGS_REG)"
20193 [(parallel [(set (match_dup 0) (const_int 0))
20194 (clobber (reg:CC FLAGS_REG))])]
20196 operands[0] = gen_lowpart (word_mode, operands[0]);
20200 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20202 "(GET_MODE (operands[0]) == QImode
20203 || GET_MODE (operands[0]) == HImode)
20204 && (! TARGET_USE_MOV0 || optimize_size)
20205 && peep2_regno_dead_p (0, FLAGS_REG)"
20206 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20207 (clobber (reg:CC FLAGS_REG))])])
20209 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20211 [(set (match_operand 0 "register_operand" "")
20213 "(GET_MODE (operands[0]) == HImode
20214 || GET_MODE (operands[0]) == SImode
20215 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20216 && (optimize_size || TARGET_PENTIUM)
20217 && peep2_regno_dead_p (0, FLAGS_REG)"
20218 [(parallel [(set (match_dup 0) (const_int -1))
20219 (clobber (reg:CC FLAGS_REG))])]
20220 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20223 ;; Attempt to convert simple leas to adds. These can be created by
20226 [(set (match_operand:SI 0 "register_operand" "")
20227 (plus:SI (match_dup 0)
20228 (match_operand:SI 1 "nonmemory_operand" "")))]
20229 "peep2_regno_dead_p (0, FLAGS_REG)"
20230 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20231 (clobber (reg:CC FLAGS_REG))])]
20235 [(set (match_operand:SI 0 "register_operand" "")
20236 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20237 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20238 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20239 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20240 (clobber (reg:CC FLAGS_REG))])]
20241 "operands[2] = gen_lowpart (SImode, operands[2]);")
20244 [(set (match_operand:DI 0 "register_operand" "")
20245 (plus:DI (match_dup 0)
20246 (match_operand:DI 1 "x86_64_general_operand" "")))]
20247 "peep2_regno_dead_p (0, FLAGS_REG)"
20248 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20249 (clobber (reg:CC FLAGS_REG))])]
20253 [(set (match_operand:SI 0 "register_operand" "")
20254 (mult:SI (match_dup 0)
20255 (match_operand:SI 1 "const_int_operand" "")))]
20256 "exact_log2 (INTVAL (operands[1])) >= 0
20257 && peep2_regno_dead_p (0, FLAGS_REG)"
20258 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20259 (clobber (reg:CC FLAGS_REG))])]
20260 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20263 [(set (match_operand:DI 0 "register_operand" "")
20264 (mult:DI (match_dup 0)
20265 (match_operand:DI 1 "const_int_operand" "")))]
20266 "exact_log2 (INTVAL (operands[1])) >= 0
20267 && peep2_regno_dead_p (0, FLAGS_REG)"
20268 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20269 (clobber (reg:CC FLAGS_REG))])]
20270 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20273 [(set (match_operand:SI 0 "register_operand" "")
20274 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20275 (match_operand:DI 2 "const_int_operand" "")) 0))]
20276 "exact_log2 (INTVAL (operands[2])) >= 0
20277 && REGNO (operands[0]) == REGNO (operands[1])
20278 && peep2_regno_dead_p (0, FLAGS_REG)"
20279 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20280 (clobber (reg:CC FLAGS_REG))])]
20281 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20283 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20284 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20285 ;; many CPUs it is also faster, since special hardware to avoid esp
20286 ;; dependencies is present.
20288 ;; While some of these conversions may be done using splitters, we use peepholes
20289 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20291 ;; Convert prologue esp subtractions to push.
20292 ;; We need register to push. In order to keep verify_flow_info happy we have
20294 ;; - use scratch and clobber it in order to avoid dependencies
20295 ;; - use already live register
20296 ;; We can't use the second way right now, since there is no reliable way how to
20297 ;; verify that given register is live. First choice will also most likely in
20298 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20299 ;; call clobbered registers are dead. We may want to use base pointer as an
20300 ;; alternative when no register is available later.
20303 [(match_scratch:SI 0 "r")
20304 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20305 (clobber (reg:CC FLAGS_REG))
20306 (clobber (mem:BLK (scratch)))])]
20307 "optimize_size || !TARGET_SUB_ESP_4"
20308 [(clobber (match_dup 0))
20309 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20310 (clobber (mem:BLK (scratch)))])])
20313 [(match_scratch:SI 0 "r")
20314 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20315 (clobber (reg:CC FLAGS_REG))
20316 (clobber (mem:BLK (scratch)))])]
20317 "optimize_size || !TARGET_SUB_ESP_8"
20318 [(clobber (match_dup 0))
20319 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20320 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20321 (clobber (mem:BLK (scratch)))])])
20323 ;; Convert esp subtractions to push.
20325 [(match_scratch:SI 0 "r")
20326 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20327 (clobber (reg:CC FLAGS_REG))])]
20328 "optimize_size || !TARGET_SUB_ESP_4"
20329 [(clobber (match_dup 0))
20330 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20333 [(match_scratch:SI 0 "r")
20334 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20335 (clobber (reg:CC FLAGS_REG))])]
20336 "optimize_size || !TARGET_SUB_ESP_8"
20337 [(clobber (match_dup 0))
20338 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20339 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20341 ;; Convert epilogue deallocator to pop.
20343 [(match_scratch:SI 0 "r")
20344 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20345 (clobber (reg:CC FLAGS_REG))
20346 (clobber (mem:BLK (scratch)))])]
20347 "optimize_size || !TARGET_ADD_ESP_4"
20348 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20349 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20350 (clobber (mem:BLK (scratch)))])]
20353 ;; Two pops case is tricky, since pop causes dependency on destination register.
20354 ;; We use two registers if available.
20356 [(match_scratch:SI 0 "r")
20357 (match_scratch:SI 1 "r")
20358 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20359 (clobber (reg:CC FLAGS_REG))
20360 (clobber (mem:BLK (scratch)))])]
20361 "optimize_size || !TARGET_ADD_ESP_8"
20362 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20363 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20364 (clobber (mem:BLK (scratch)))])
20365 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20366 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20370 [(match_scratch:SI 0 "r")
20371 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20372 (clobber (reg:CC FLAGS_REG))
20373 (clobber (mem:BLK (scratch)))])]
20375 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20376 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20377 (clobber (mem:BLK (scratch)))])
20378 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20379 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20382 ;; Convert esp additions to pop.
20384 [(match_scratch:SI 0 "r")
20385 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20386 (clobber (reg:CC FLAGS_REG))])]
20388 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20389 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20392 ;; Two pops case is tricky, since pop causes dependency on destination register.
20393 ;; We use two registers if available.
20395 [(match_scratch:SI 0 "r")
20396 (match_scratch:SI 1 "r")
20397 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20398 (clobber (reg:CC FLAGS_REG))])]
20400 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20401 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20402 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20403 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20407 [(match_scratch:SI 0 "r")
20408 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20409 (clobber (reg:CC FLAGS_REG))])]
20411 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20412 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20413 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20414 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20417 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20418 ;; required and register dies. Similarly for 128 to plus -128.
20420 [(set (match_operand 0 "flags_reg_operand" "")
20421 (match_operator 1 "compare_operator"
20422 [(match_operand 2 "register_operand" "")
20423 (match_operand 3 "const_int_operand" "")]))]
20424 "(INTVAL (operands[3]) == -1
20425 || INTVAL (operands[3]) == 1
20426 || INTVAL (operands[3]) == 128)
20427 && ix86_match_ccmode (insn, CCGCmode)
20428 && peep2_reg_dead_p (1, operands[2])"
20429 [(parallel [(set (match_dup 0)
20430 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20431 (clobber (match_dup 2))])]
20435 [(match_scratch:DI 0 "r")
20436 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20437 (clobber (reg:CC FLAGS_REG))
20438 (clobber (mem:BLK (scratch)))])]
20439 "optimize_size || !TARGET_SUB_ESP_4"
20440 [(clobber (match_dup 0))
20441 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20442 (clobber (mem:BLK (scratch)))])])
20445 [(match_scratch:DI 0 "r")
20446 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20447 (clobber (reg:CC FLAGS_REG))
20448 (clobber (mem:BLK (scratch)))])]
20449 "optimize_size || !TARGET_SUB_ESP_8"
20450 [(clobber (match_dup 0))
20451 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20452 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20453 (clobber (mem:BLK (scratch)))])])
20455 ;; Convert esp subtractions to push.
20457 [(match_scratch:DI 0 "r")
20458 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20459 (clobber (reg:CC FLAGS_REG))])]
20460 "optimize_size || !TARGET_SUB_ESP_4"
20461 [(clobber (match_dup 0))
20462 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20465 [(match_scratch:DI 0 "r")
20466 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20467 (clobber (reg:CC FLAGS_REG))])]
20468 "optimize_size || !TARGET_SUB_ESP_8"
20469 [(clobber (match_dup 0))
20470 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20471 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20473 ;; Convert epilogue deallocator to pop.
20475 [(match_scratch:DI 0 "r")
20476 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20477 (clobber (reg:CC FLAGS_REG))
20478 (clobber (mem:BLK (scratch)))])]
20479 "optimize_size || !TARGET_ADD_ESP_4"
20480 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20481 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20482 (clobber (mem:BLK (scratch)))])]
20485 ;; Two pops case is tricky, since pop causes dependency on destination register.
20486 ;; We use two registers if available.
20488 [(match_scratch:DI 0 "r")
20489 (match_scratch:DI 1 "r")
20490 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20491 (clobber (reg:CC FLAGS_REG))
20492 (clobber (mem:BLK (scratch)))])]
20493 "optimize_size || !TARGET_ADD_ESP_8"
20494 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20495 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20496 (clobber (mem:BLK (scratch)))])
20497 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20498 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20502 [(match_scratch:DI 0 "r")
20503 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20504 (clobber (reg:CC FLAGS_REG))
20505 (clobber (mem:BLK (scratch)))])]
20507 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20508 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20509 (clobber (mem:BLK (scratch)))])
20510 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20511 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20514 ;; Convert esp additions to pop.
20516 [(match_scratch:DI 0 "r")
20517 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20518 (clobber (reg:CC FLAGS_REG))])]
20520 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20521 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20524 ;; Two pops case is tricky, since pop causes dependency on destination register.
20525 ;; We use two registers if available.
20527 [(match_scratch:DI 0 "r")
20528 (match_scratch:DI 1 "r")
20529 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20530 (clobber (reg:CC FLAGS_REG))])]
20532 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20533 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20534 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20535 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20539 [(match_scratch:DI 0 "r")
20540 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20541 (clobber (reg:CC FLAGS_REG))])]
20543 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20544 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20545 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20546 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20549 ;; Convert imul by three, five and nine into lea
20552 [(set (match_operand:SI 0 "register_operand" "")
20553 (mult:SI (match_operand:SI 1 "register_operand" "")
20554 (match_operand:SI 2 "const_int_operand" "")))
20555 (clobber (reg:CC FLAGS_REG))])]
20556 "INTVAL (operands[2]) == 3
20557 || INTVAL (operands[2]) == 5
20558 || INTVAL (operands[2]) == 9"
20559 [(set (match_dup 0)
20560 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20562 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20566 [(set (match_operand:SI 0 "register_operand" "")
20567 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20568 (match_operand:SI 2 "const_int_operand" "")))
20569 (clobber (reg:CC FLAGS_REG))])]
20571 && (INTVAL (operands[2]) == 3
20572 || INTVAL (operands[2]) == 5
20573 || INTVAL (operands[2]) == 9)"
20574 [(set (match_dup 0) (match_dup 1))
20576 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20578 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20582 [(set (match_operand:DI 0 "register_operand" "")
20583 (mult:DI (match_operand:DI 1 "register_operand" "")
20584 (match_operand:DI 2 "const_int_operand" "")))
20585 (clobber (reg:CC FLAGS_REG))])]
20587 && (INTVAL (operands[2]) == 3
20588 || INTVAL (operands[2]) == 5
20589 || INTVAL (operands[2]) == 9)"
20590 [(set (match_dup 0)
20591 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20593 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20597 [(set (match_operand:DI 0 "register_operand" "")
20598 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20599 (match_operand:DI 2 "const_int_operand" "")))
20600 (clobber (reg:CC FLAGS_REG))])]
20603 && (INTVAL (operands[2]) == 3
20604 || INTVAL (operands[2]) == 5
20605 || INTVAL (operands[2]) == 9)"
20606 [(set (match_dup 0) (match_dup 1))
20608 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20610 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20612 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20613 ;; imul $32bit_imm, reg, reg is direct decoded.
20615 [(match_scratch:DI 3 "r")
20616 (parallel [(set (match_operand:DI 0 "register_operand" "")
20617 (mult:DI (match_operand:DI 1 "memory_operand" "")
20618 (match_operand:DI 2 "immediate_operand" "")))
20619 (clobber (reg:CC FLAGS_REG))])]
20620 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20621 && !satisfies_constraint_K (operands[2])"
20622 [(set (match_dup 3) (match_dup 1))
20623 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20624 (clobber (reg:CC FLAGS_REG))])]
20628 [(match_scratch:SI 3 "r")
20629 (parallel [(set (match_operand:SI 0 "register_operand" "")
20630 (mult:SI (match_operand:SI 1 "memory_operand" "")
20631 (match_operand:SI 2 "immediate_operand" "")))
20632 (clobber (reg:CC FLAGS_REG))])]
20633 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20634 && !satisfies_constraint_K (operands[2])"
20635 [(set (match_dup 3) (match_dup 1))
20636 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20637 (clobber (reg:CC FLAGS_REG))])]
20641 [(match_scratch:SI 3 "r")
20642 (parallel [(set (match_operand:DI 0 "register_operand" "")
20644 (mult:SI (match_operand:SI 1 "memory_operand" "")
20645 (match_operand:SI 2 "immediate_operand" ""))))
20646 (clobber (reg:CC FLAGS_REG))])]
20647 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20648 && !satisfies_constraint_K (operands[2])"
20649 [(set (match_dup 3) (match_dup 1))
20650 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20651 (clobber (reg:CC FLAGS_REG))])]
20654 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20655 ;; Convert it into imul reg, reg
20656 ;; It would be better to force assembler to encode instruction using long
20657 ;; immediate, but there is apparently no way to do so.
20659 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20660 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20661 (match_operand:DI 2 "const_int_operand" "")))
20662 (clobber (reg:CC FLAGS_REG))])
20663 (match_scratch:DI 3 "r")]
20664 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20665 && satisfies_constraint_K (operands[2])"
20666 [(set (match_dup 3) (match_dup 2))
20667 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20668 (clobber (reg:CC FLAGS_REG))])]
20670 if (!rtx_equal_p (operands[0], operands[1]))
20671 emit_move_insn (operands[0], operands[1]);
20675 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20676 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20677 (match_operand:SI 2 "const_int_operand" "")))
20678 (clobber (reg:CC FLAGS_REG))])
20679 (match_scratch:SI 3 "r")]
20680 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20681 && satisfies_constraint_K (operands[2])"
20682 [(set (match_dup 3) (match_dup 2))
20683 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20684 (clobber (reg:CC FLAGS_REG))])]
20686 if (!rtx_equal_p (operands[0], operands[1]))
20687 emit_move_insn (operands[0], operands[1]);
20691 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20692 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20693 (match_operand:HI 2 "immediate_operand" "")))
20694 (clobber (reg:CC FLAGS_REG))])
20695 (match_scratch:HI 3 "r")]
20696 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20697 [(set (match_dup 3) (match_dup 2))
20698 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20699 (clobber (reg:CC FLAGS_REG))])]
20701 if (!rtx_equal_p (operands[0], operands[1]))
20702 emit_move_insn (operands[0], operands[1]);
20705 ;; After splitting up read-modify operations, array accesses with memory
20706 ;; operands might end up in form:
20708 ;; movl 4(%esp), %edx
20710 ;; instead of pre-splitting:
20712 ;; addl 4(%esp), %eax
20714 ;; movl 4(%esp), %edx
20715 ;; leal (%edx,%eax,4), %eax
20718 [(parallel [(set (match_operand 0 "register_operand" "")
20719 (ashift (match_operand 1 "register_operand" "")
20720 (match_operand 2 "const_int_operand" "")))
20721 (clobber (reg:CC FLAGS_REG))])
20722 (set (match_operand 3 "register_operand")
20723 (match_operand 4 "x86_64_general_operand" ""))
20724 (parallel [(set (match_operand 5 "register_operand" "")
20725 (plus (match_operand 6 "register_operand" "")
20726 (match_operand 7 "register_operand" "")))
20727 (clobber (reg:CC FLAGS_REG))])]
20728 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20729 /* Validate MODE for lea. */
20730 && ((!TARGET_PARTIAL_REG_STALL
20731 && (GET_MODE (operands[0]) == QImode
20732 || GET_MODE (operands[0]) == HImode))
20733 || GET_MODE (operands[0]) == SImode
20734 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20735 /* We reorder load and the shift. */
20736 && !rtx_equal_p (operands[1], operands[3])
20737 && !reg_overlap_mentioned_p (operands[0], operands[4])
20738 /* Last PLUS must consist of operand 0 and 3. */
20739 && !rtx_equal_p (operands[0], operands[3])
20740 && (rtx_equal_p (operands[3], operands[6])
20741 || rtx_equal_p (operands[3], operands[7]))
20742 && (rtx_equal_p (operands[0], operands[6])
20743 || rtx_equal_p (operands[0], operands[7]))
20744 /* The intermediate operand 0 must die or be same as output. */
20745 && (rtx_equal_p (operands[0], operands[5])
20746 || peep2_reg_dead_p (3, operands[0]))"
20747 [(set (match_dup 3) (match_dup 4))
20748 (set (match_dup 0) (match_dup 1))]
20750 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20751 int scale = 1 << INTVAL (operands[2]);
20752 rtx index = gen_lowpart (Pmode, operands[1]);
20753 rtx base = gen_lowpart (Pmode, operands[3]);
20754 rtx dest = gen_lowpart (mode, operands[5]);
20756 operands[1] = gen_rtx_PLUS (Pmode, base,
20757 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20759 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20760 operands[0] = dest;
20763 ;; Call-value patterns last so that the wildcard operand does not
20764 ;; disrupt insn-recog's switch tables.
20766 (define_insn "*call_value_pop_0"
20767 [(set (match_operand 0 "" "")
20768 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20769 (match_operand:SI 2 "" "")))
20770 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20771 (match_operand:SI 3 "immediate_operand" "")))]
20774 if (SIBLING_CALL_P (insn))
20777 return "call\t%P1";
20779 [(set_attr "type" "callv")])
20781 (define_insn "*call_value_pop_1"
20782 [(set (match_operand 0 "" "")
20783 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20784 (match_operand:SI 2 "" "")))
20785 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20786 (match_operand:SI 3 "immediate_operand" "i")))]
20789 if (constant_call_address_operand (operands[1], Pmode))
20791 if (SIBLING_CALL_P (insn))
20794 return "call\t%P1";
20796 if (SIBLING_CALL_P (insn))
20799 return "call\t%A1";
20801 [(set_attr "type" "callv")])
20803 (define_insn "*call_value_0"
20804 [(set (match_operand 0 "" "")
20805 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20806 (match_operand:SI 2 "" "")))]
20809 if (SIBLING_CALL_P (insn))
20812 return "call\t%P1";
20814 [(set_attr "type" "callv")])
20816 (define_insn "*call_value_0_rex64"
20817 [(set (match_operand 0 "" "")
20818 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20819 (match_operand:DI 2 "const_int_operand" "")))]
20822 if (SIBLING_CALL_P (insn))
20825 return "call\t%P1";
20827 [(set_attr "type" "callv")])
20829 (define_insn "*call_value_1"
20830 [(set (match_operand 0 "" "")
20831 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20832 (match_operand:SI 2 "" "")))]
20833 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20835 if (constant_call_address_operand (operands[1], Pmode))
20836 return "call\t%P1";
20837 return "call\t%A1";
20839 [(set_attr "type" "callv")])
20841 (define_insn "*sibcall_value_1"
20842 [(set (match_operand 0 "" "")
20843 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20844 (match_operand:SI 2 "" "")))]
20845 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20847 if (constant_call_address_operand (operands[1], Pmode))
20851 [(set_attr "type" "callv")])
20853 (define_insn "*call_value_1_rex64"
20854 [(set (match_operand 0 "" "")
20855 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20856 (match_operand:DI 2 "" "")))]
20857 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20859 if (constant_call_address_operand (operands[1], Pmode))
20860 return "call\t%P1";
20861 return "call\t%A1";
20863 [(set_attr "type" "callv")])
20865 (define_insn "*sibcall_value_1_rex64"
20866 [(set (match_operand 0 "" "")
20867 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20868 (match_operand:DI 2 "" "")))]
20869 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20871 [(set_attr "type" "callv")])
20873 (define_insn "*sibcall_value_1_rex64_v"
20874 [(set (match_operand 0 "" "")
20875 (call (mem:QI (reg:DI R11_REG))
20876 (match_operand:DI 1 "" "")))]
20877 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20879 [(set_attr "type" "callv")])
20881 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20882 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20883 ;; caught for use by garbage collectors and the like. Using an insn that
20884 ;; maps to SIGILL makes it more likely the program will rightfully die.
20885 ;; Keeping with tradition, "6" is in honor of #UD.
20886 (define_insn "trap"
20887 [(trap_if (const_int 1) (const_int 6))]
20889 { return ASM_SHORT "0x0b0f"; }
20890 [(set_attr "length" "2")])
20892 (define_expand "sse_prologue_save"
20893 [(parallel [(set (match_operand:BLK 0 "" "")
20894 (unspec:BLK [(reg:DI 21)
20901 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20902 (use (match_operand:DI 1 "register_operand" ""))
20903 (use (match_operand:DI 2 "immediate_operand" ""))
20904 (use (label_ref:DI (match_operand 3 "" "")))])]
20908 (define_insn "*sse_prologue_save_insn"
20909 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20910 (match_operand:DI 4 "const_int_operand" "n")))
20911 (unspec:BLK [(reg:DI 21)
20918 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20919 (use (match_operand:DI 1 "register_operand" "r"))
20920 (use (match_operand:DI 2 "const_int_operand" "i"))
20921 (use (label_ref:DI (match_operand 3 "" "X")))]
20923 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20924 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20928 operands[0] = gen_rtx_MEM (Pmode,
20929 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20930 output_asm_insn (\"jmp\\t%A1\", operands);
20931 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20933 operands[4] = adjust_address (operands[0], DImode, i*16);
20934 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20935 PUT_MODE (operands[4], TImode);
20936 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20937 output_asm_insn (\"rex\", operands);
20938 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20940 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20941 CODE_LABEL_NUMBER (operands[3]));
20945 [(set_attr "type" "other")
20946 (set_attr "length_immediate" "0")
20947 (set_attr "length_address" "0")
20948 (set_attr "length" "135")
20949 (set_attr "memory" "store")
20950 (set_attr "modrm" "0")
20951 (set_attr "mode" "DI")])
20953 (define_expand "prefetch"
20954 [(prefetch (match_operand 0 "address_operand" "")
20955 (match_operand:SI 1 "const_int_operand" "")
20956 (match_operand:SI 2 "const_int_operand" ""))]
20957 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20959 int rw = INTVAL (operands[1]);
20960 int locality = INTVAL (operands[2]);
20962 gcc_assert (rw == 0 || rw == 1);
20963 gcc_assert (locality >= 0 && locality <= 3);
20964 gcc_assert (GET_MODE (operands[0]) == Pmode
20965 || GET_MODE (operands[0]) == VOIDmode);
20967 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20968 supported by SSE counterpart or the SSE prefetch is not available
20969 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20971 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20972 operands[2] = GEN_INT (3);
20974 operands[1] = const0_rtx;
20977 (define_insn "*prefetch_sse"
20978 [(prefetch (match_operand:SI 0 "address_operand" "p")
20980 (match_operand:SI 1 "const_int_operand" ""))]
20981 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20983 static const char * const patterns[4] = {
20984 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20987 int locality = INTVAL (operands[1]);
20988 gcc_assert (locality >= 0 && locality <= 3);
20990 return patterns[locality];
20992 [(set_attr "type" "sse")
20993 (set_attr "memory" "none")])
20995 (define_insn "*prefetch_sse_rex"
20996 [(prefetch (match_operand:DI 0 "address_operand" "p")
20998 (match_operand:SI 1 "const_int_operand" ""))]
20999 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21001 static const char * const patterns[4] = {
21002 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21005 int locality = INTVAL (operands[1]);
21006 gcc_assert (locality >= 0 && locality <= 3);
21008 return patterns[locality];
21010 [(set_attr "type" "sse")
21011 (set_attr "memory" "none")])
21013 (define_insn "*prefetch_3dnow"
21014 [(prefetch (match_operand:SI 0 "address_operand" "p")
21015 (match_operand:SI 1 "const_int_operand" "n")
21017 "TARGET_3DNOW && !TARGET_64BIT"
21019 if (INTVAL (operands[1]) == 0)
21020 return "prefetch\t%a0";
21022 return "prefetchw\t%a0";
21024 [(set_attr "type" "mmx")
21025 (set_attr "memory" "none")])
21027 (define_insn "*prefetch_3dnow_rex"
21028 [(prefetch (match_operand:DI 0 "address_operand" "p")
21029 (match_operand:SI 1 "const_int_operand" "n")
21031 "TARGET_3DNOW && TARGET_64BIT"
21033 if (INTVAL (operands[1]) == 0)
21034 return "prefetch\t%a0";
21036 return "prefetchw\t%a0";
21038 [(set_attr "type" "mmx")
21039 (set_attr "memory" "none")])
21041 (define_expand "stack_protect_set"
21042 [(match_operand 0 "memory_operand" "")
21043 (match_operand 1 "memory_operand" "")]
21046 #ifdef TARGET_THREAD_SSP_OFFSET
21048 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21049 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21051 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21052 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21055 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21057 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21062 (define_insn "stack_protect_set_si"
21063 [(set (match_operand:SI 0 "memory_operand" "=m")
21064 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21065 (set (match_scratch:SI 2 "=&r") (const_int 0))
21066 (clobber (reg:CC FLAGS_REG))]
21068 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21069 [(set_attr "type" "multi")])
21071 (define_insn "stack_protect_set_di"
21072 [(set (match_operand:DI 0 "memory_operand" "=m")
21073 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21074 (set (match_scratch:DI 2 "=&r") (const_int 0))
21075 (clobber (reg:CC FLAGS_REG))]
21077 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21078 [(set_attr "type" "multi")])
21080 (define_insn "stack_tls_protect_set_si"
21081 [(set (match_operand:SI 0 "memory_operand" "=m")
21082 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21083 (set (match_scratch:SI 2 "=&r") (const_int 0))
21084 (clobber (reg:CC FLAGS_REG))]
21086 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21087 [(set_attr "type" "multi")])
21089 (define_insn "stack_tls_protect_set_di"
21090 [(set (match_operand:DI 0 "memory_operand" "=m")
21091 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21092 (set (match_scratch:DI 2 "=&r") (const_int 0))
21093 (clobber (reg:CC FLAGS_REG))]
21096 /* The kernel uses a different segment register for performance reasons; a
21097 system call would not have to trash the userspace segment register,
21098 which would be expensive */
21099 if (ix86_cmodel != CM_KERNEL)
21100 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21102 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21104 [(set_attr "type" "multi")])
21106 (define_expand "stack_protect_test"
21107 [(match_operand 0 "memory_operand" "")
21108 (match_operand 1 "memory_operand" "")
21109 (match_operand 2 "" "")]
21112 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21113 ix86_compare_op0 = operands[0];
21114 ix86_compare_op1 = operands[1];
21115 ix86_compare_emitted = flags;
21117 #ifdef TARGET_THREAD_SSP_OFFSET
21119 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21120 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21122 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21123 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21126 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21128 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21130 emit_jump_insn (gen_beq (operands[2]));
21134 (define_insn "stack_protect_test_si"
21135 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21136 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21137 (match_operand:SI 2 "memory_operand" "m")]
21139 (clobber (match_scratch:SI 3 "=&r"))]
21141 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21142 [(set_attr "type" "multi")])
21144 (define_insn "stack_protect_test_di"
21145 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21146 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21147 (match_operand:DI 2 "memory_operand" "m")]
21149 (clobber (match_scratch:DI 3 "=&r"))]
21151 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21152 [(set_attr "type" "multi")])
21154 (define_insn "stack_tls_protect_test_si"
21155 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21156 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21157 (match_operand:SI 2 "const_int_operand" "i")]
21158 UNSPEC_SP_TLS_TEST))
21159 (clobber (match_scratch:SI 3 "=r"))]
21161 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21162 [(set_attr "type" "multi")])
21164 (define_insn "stack_tls_protect_test_di"
21165 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21166 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21167 (match_operand:DI 2 "const_int_operand" "i")]
21168 UNSPEC_SP_TLS_TEST))
21169 (clobber (match_scratch:DI 3 "=r"))]
21172 /* The kernel uses a different segment register for performance reasons; a
21173 system call would not have to trash the userspace segment register,
21174 which would be expensive */
21175 if (ix86_cmodel != CM_KERNEL)
21176 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21178 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21180 [(set_attr "type" "multi")])
21184 (include "sync.md")