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")])
492 ;; Scheduling descriptions
494 (include "pentium.md")
497 (include "athlon.md")
501 ;; Operand and operator predicates and constraints
503 (include "predicates.md")
504 (include "constraints.md")
507 ;; Compare instructions.
509 ;; All compare insns have expanders that save the operands away without
510 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
511 ;; after the cmp) will actually emit the cmpM.
513 (define_expand "cmpti"
514 [(set (reg:CC FLAGS_REG)
515 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
516 (match_operand:TI 1 "x86_64_general_operand" "")))]
519 if (MEM_P (operands[0]) && MEM_P (operands[1]))
520 operands[0] = force_reg (TImode, operands[0]);
521 ix86_compare_op0 = operands[0];
522 ix86_compare_op1 = operands[1];
526 (define_expand "cmpdi"
527 [(set (reg:CC FLAGS_REG)
528 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
529 (match_operand:DI 1 "x86_64_general_operand" "")))]
532 if (MEM_P (operands[0]) && MEM_P (operands[1]))
533 operands[0] = force_reg (DImode, operands[0]);
534 ix86_compare_op0 = operands[0];
535 ix86_compare_op1 = operands[1];
539 (define_expand "cmpsi"
540 [(set (reg:CC FLAGS_REG)
541 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
542 (match_operand:SI 1 "general_operand" "")))]
545 if (MEM_P (operands[0]) && MEM_P (operands[1]))
546 operands[0] = force_reg (SImode, operands[0]);
547 ix86_compare_op0 = operands[0];
548 ix86_compare_op1 = operands[1];
552 (define_expand "cmphi"
553 [(set (reg:CC FLAGS_REG)
554 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
555 (match_operand:HI 1 "general_operand" "")))]
558 if (MEM_P (operands[0]) && MEM_P (operands[1]))
559 operands[0] = force_reg (HImode, operands[0]);
560 ix86_compare_op0 = operands[0];
561 ix86_compare_op1 = operands[1];
565 (define_expand "cmpqi"
566 [(set (reg:CC FLAGS_REG)
567 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
568 (match_operand:QI 1 "general_operand" "")))]
571 if (MEM_P (operands[0]) && MEM_P (operands[1]))
572 operands[0] = force_reg (QImode, operands[0]);
573 ix86_compare_op0 = operands[0];
574 ix86_compare_op1 = operands[1];
578 (define_insn "cmpdi_ccno_1_rex64"
579 [(set (reg FLAGS_REG)
580 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
581 (match_operand:DI 1 "const0_operand" "n,n")))]
582 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
584 test{q}\t{%0, %0|%0, %0}
585 cmp{q}\t{%1, %0|%0, %1}"
586 [(set_attr "type" "test,icmp")
587 (set_attr "length_immediate" "0,1")
588 (set_attr "mode" "DI")])
590 (define_insn "*cmpdi_minus_1_rex64"
591 [(set (reg FLAGS_REG)
592 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
593 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
595 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
596 "cmp{q}\t{%1, %0|%0, %1}"
597 [(set_attr "type" "icmp")
598 (set_attr "mode" "DI")])
600 (define_expand "cmpdi_1_rex64"
601 [(set (reg:CC FLAGS_REG)
602 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
603 (match_operand:DI 1 "general_operand" "")))]
607 (define_insn "cmpdi_1_insn_rex64"
608 [(set (reg FLAGS_REG)
609 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
610 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
611 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
612 "cmp{q}\t{%1, %0|%0, %1}"
613 [(set_attr "type" "icmp")
614 (set_attr "mode" "DI")])
617 (define_insn "*cmpsi_ccno_1"
618 [(set (reg FLAGS_REG)
619 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
620 (match_operand:SI 1 "const0_operand" "n,n")))]
621 "ix86_match_ccmode (insn, CCNOmode)"
623 test{l}\t{%0, %0|%0, %0}
624 cmp{l}\t{%1, %0|%0, %1}"
625 [(set_attr "type" "test,icmp")
626 (set_attr "length_immediate" "0,1")
627 (set_attr "mode" "SI")])
629 (define_insn "*cmpsi_minus_1"
630 [(set (reg FLAGS_REG)
631 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632 (match_operand:SI 1 "general_operand" "ri,mr"))
634 "ix86_match_ccmode (insn, CCGOCmode)"
635 "cmp{l}\t{%1, %0|%0, %1}"
636 [(set_attr "type" "icmp")
637 (set_attr "mode" "SI")])
639 (define_expand "cmpsi_1"
640 [(set (reg:CC FLAGS_REG)
641 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642 (match_operand:SI 1 "general_operand" "ri,mr")))]
646 (define_insn "*cmpsi_1_insn"
647 [(set (reg FLAGS_REG)
648 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
649 (match_operand:SI 1 "general_operand" "ri,mr")))]
650 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
651 && ix86_match_ccmode (insn, CCmode)"
652 "cmp{l}\t{%1, %0|%0, %1}"
653 [(set_attr "type" "icmp")
654 (set_attr "mode" "SI")])
656 (define_insn "*cmphi_ccno_1"
657 [(set (reg FLAGS_REG)
658 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
659 (match_operand:HI 1 "const0_operand" "n,n")))]
660 "ix86_match_ccmode (insn, CCNOmode)"
662 test{w}\t{%0, %0|%0, %0}
663 cmp{w}\t{%1, %0|%0, %1}"
664 [(set_attr "type" "test,icmp")
665 (set_attr "length_immediate" "0,1")
666 (set_attr "mode" "HI")])
668 (define_insn "*cmphi_minus_1"
669 [(set (reg FLAGS_REG)
670 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
671 (match_operand:HI 1 "general_operand" "ri,mr"))
673 "ix86_match_ccmode (insn, CCGOCmode)"
674 "cmp{w}\t{%1, %0|%0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "HI")])
678 (define_insn "*cmphi_1"
679 [(set (reg FLAGS_REG)
680 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
681 (match_operand:HI 1 "general_operand" "ri,mr")))]
682 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
683 && ix86_match_ccmode (insn, CCmode)"
684 "cmp{w}\t{%1, %0|%0, %1}"
685 [(set_attr "type" "icmp")
686 (set_attr "mode" "HI")])
688 (define_insn "*cmpqi_ccno_1"
689 [(set (reg FLAGS_REG)
690 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
691 (match_operand:QI 1 "const0_operand" "n,n")))]
692 "ix86_match_ccmode (insn, CCNOmode)"
694 test{b}\t{%0, %0|%0, %0}
695 cmp{b}\t{$0, %0|%0, 0}"
696 [(set_attr "type" "test,icmp")
697 (set_attr "length_immediate" "0,1")
698 (set_attr "mode" "QI")])
700 (define_insn "*cmpqi_1"
701 [(set (reg FLAGS_REG)
702 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
703 (match_operand:QI 1 "general_operand" "qi,mq")))]
704 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
705 && ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%1, %0|%0, %1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
710 (define_insn "*cmpqi_minus_1"
711 [(set (reg FLAGS_REG)
712 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
713 (match_operand:QI 1 "general_operand" "qi,mq"))
715 "ix86_match_ccmode (insn, CCGOCmode)"
716 "cmp{b}\t{%1, %0|%0, %1}"
717 [(set_attr "type" "icmp")
718 (set_attr "mode" "QI")])
720 (define_insn "*cmpqi_ext_1"
721 [(set (reg FLAGS_REG)
723 (match_operand:QI 0 "general_operand" "Qm")
726 (match_operand 1 "ext_register_operand" "Q")
729 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730 "cmp{b}\t{%h1, %0|%0, %h1}"
731 [(set_attr "type" "icmp")
732 (set_attr "mode" "QI")])
734 (define_insn "*cmpqi_ext_1_rex64"
735 [(set (reg FLAGS_REG)
737 (match_operand:QI 0 "register_operand" "Q")
740 (match_operand 1 "ext_register_operand" "Q")
743 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744 "cmp{b}\t{%h1, %0|%0, %h1}"
745 [(set_attr "type" "icmp")
746 (set_attr "mode" "QI")])
748 (define_insn "*cmpqi_ext_2"
749 [(set (reg FLAGS_REG)
753 (match_operand 0 "ext_register_operand" "Q")
756 (match_operand:QI 1 "const0_operand" "n")))]
757 "ix86_match_ccmode (insn, CCNOmode)"
759 [(set_attr "type" "test")
760 (set_attr "length_immediate" "0")
761 (set_attr "mode" "QI")])
763 (define_expand "cmpqi_ext_3"
764 [(set (reg:CC FLAGS_REG)
768 (match_operand 0 "ext_register_operand" "")
771 (match_operand:QI 1 "general_operand" "")))]
775 (define_insn "cmpqi_ext_3_insn"
776 [(set (reg FLAGS_REG)
780 (match_operand 0 "ext_register_operand" "Q")
783 (match_operand:QI 1 "general_operand" "Qmn")))]
784 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
785 "cmp{b}\t{%1, %h0|%h0, %1}"
786 [(set_attr "type" "icmp")
787 (set_attr "mode" "QI")])
789 (define_insn "cmpqi_ext_3_insn_rex64"
790 [(set (reg FLAGS_REG)
794 (match_operand 0 "ext_register_operand" "Q")
797 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
798 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
799 "cmp{b}\t{%1, %h0|%h0, %1}"
800 [(set_attr "type" "icmp")
801 (set_attr "mode" "QI")])
803 (define_insn "*cmpqi_ext_4"
804 [(set (reg FLAGS_REG)
808 (match_operand 0 "ext_register_operand" "Q")
813 (match_operand 1 "ext_register_operand" "Q")
816 "ix86_match_ccmode (insn, CCmode)"
817 "cmp{b}\t{%h1, %h0|%h0, %h1}"
818 [(set_attr "type" "icmp")
819 (set_attr "mode" "QI")])
821 ;; These implement float point compares.
822 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
823 ;; which would allow mix and match FP modes on the compares. Which is what
824 ;; the old patterns did, but with many more of them.
826 (define_expand "cmpxf"
827 [(set (reg:CC FLAGS_REG)
828 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
829 (match_operand:XF 1 "nonmemory_operand" "")))]
832 ix86_compare_op0 = operands[0];
833 ix86_compare_op1 = operands[1];
837 (define_expand "cmpdf"
838 [(set (reg:CC FLAGS_REG)
839 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
840 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
841 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
843 ix86_compare_op0 = operands[0];
844 ix86_compare_op1 = operands[1];
848 (define_expand "cmpsf"
849 [(set (reg:CC FLAGS_REG)
850 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
851 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
852 "TARGET_80387 || TARGET_SSE_MATH"
854 ix86_compare_op0 = operands[0];
855 ix86_compare_op1 = operands[1];
859 ;; FP compares, step 1:
860 ;; Set the FP condition codes.
862 ;; CCFPmode compare with exceptions
863 ;; CCFPUmode compare with no exceptions
865 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
866 ;; used to manage the reg stack popping would not be preserved.
868 (define_insn "*cmpfp_0"
869 [(set (match_operand:HI 0 "register_operand" "=a")
872 (match_operand 1 "register_operand" "f")
873 (match_operand 2 "const0_operand" "X"))]
876 && FLOAT_MODE_P (GET_MODE (operands[1]))
877 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
878 "* return output_fp_compare (insn, operands, 0, 0);"
879 [(set_attr "type" "multi")
880 (set_attr "unit" "i387")
882 (cond [(match_operand:SF 1 "" "")
884 (match_operand:DF 1 "" "")
887 (const_string "XF")))])
889 (define_insn "*cmpfp_sf"
890 [(set (match_operand:HI 0 "register_operand" "=a")
893 (match_operand:SF 1 "register_operand" "f")
894 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
897 "* return output_fp_compare (insn, operands, 0, 0);"
898 [(set_attr "type" "multi")
899 (set_attr "unit" "i387")
900 (set_attr "mode" "SF")])
902 (define_insn "*cmpfp_df"
903 [(set (match_operand:HI 0 "register_operand" "=a")
906 (match_operand:DF 1 "register_operand" "f")
907 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
910 "* return output_fp_compare (insn, operands, 0, 0);"
911 [(set_attr "type" "multi")
912 (set_attr "unit" "i387")
913 (set_attr "mode" "DF")])
915 (define_insn "*cmpfp_xf"
916 [(set (match_operand:HI 0 "register_operand" "=a")
919 (match_operand:XF 1 "register_operand" "f")
920 (match_operand:XF 2 "register_operand" "f"))]
923 "* return output_fp_compare (insn, operands, 0, 0);"
924 [(set_attr "type" "multi")
925 (set_attr "unit" "i387")
926 (set_attr "mode" "XF")])
928 (define_insn "*cmpfp_u"
929 [(set (match_operand:HI 0 "register_operand" "=a")
932 (match_operand 1 "register_operand" "f")
933 (match_operand 2 "register_operand" "f"))]
936 && FLOAT_MODE_P (GET_MODE (operands[1]))
937 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938 "* return output_fp_compare (insn, operands, 0, 1);"
939 [(set_attr "type" "multi")
940 (set_attr "unit" "i387")
942 (cond [(match_operand:SF 1 "" "")
944 (match_operand:DF 1 "" "")
947 (const_string "XF")))])
949 (define_insn "*cmpfp_<mode>"
950 [(set (match_operand:HI 0 "register_operand" "=a")
953 (match_operand 1 "register_operand" "f")
954 (match_operator 3 "float_operator"
955 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
957 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
958 && FLOAT_MODE_P (GET_MODE (operands[1]))
959 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
960 "* return output_fp_compare (insn, operands, 0, 0);"
961 [(set_attr "type" "multi")
962 (set_attr "unit" "i387")
963 (set_attr "fp_int_src" "true")
964 (set_attr "mode" "<MODE>")])
966 ;; FP compares, step 2
967 ;; Move the fpsw to ax.
969 (define_insn "x86_fnstsw_1"
970 [(set (match_operand:HI 0 "register_operand" "=a")
971 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
974 [(set_attr "length" "2")
975 (set_attr "mode" "SI")
976 (set_attr "unit" "i387")])
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
981 (define_insn "x86_sahf_1"
982 [(set (reg:CC FLAGS_REG)
983 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
986 [(set_attr "length" "1")
987 (set_attr "athlon_decode" "vector")
988 (set_attr "amdfam10_decode" "direct")
989 (set_attr "mode" "SI")])
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
993 (define_insn "*cmpfp_i_mixed"
994 [(set (reg:CCFP FLAGS_REG)
995 (compare:CCFP (match_operand 0 "register_operand" "f,x")
996 (match_operand 1 "nonimmediate_operand" "f,xm")))]
998 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000 "* return output_fp_compare (insn, operands, 1, 0);"
1001 [(set_attr "type" "fcmp,ssecomi")
1003 (if_then_else (match_operand:SF 1 "" "")
1005 (const_string "DF")))
1006 (set_attr "athlon_decode" "vector")
1007 (set_attr "amdfam10_decode" "direct")])
1009 (define_insn "*cmpfp_i_sse"
1010 [(set (reg:CCFP FLAGS_REG)
1011 (compare:CCFP (match_operand 0 "register_operand" "x")
1012 (match_operand 1 "nonimmediate_operand" "xm")))]
1014 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016 "* return output_fp_compare (insn, operands, 1, 0);"
1017 [(set_attr "type" "ssecomi")
1019 (if_then_else (match_operand:SF 1 "" "")
1021 (const_string "DF")))
1022 (set_attr "athlon_decode" "vector")
1023 (set_attr "amdfam10_decode" "direct")])
1025 (define_insn "*cmpfp_i_i387"
1026 [(set (reg:CCFP FLAGS_REG)
1027 (compare:CCFP (match_operand 0 "register_operand" "f")
1028 (match_operand 1 "register_operand" "f")))]
1029 "TARGET_80387 && TARGET_CMOVE
1030 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1031 && FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033 "* return output_fp_compare (insn, operands, 1, 0);"
1034 [(set_attr "type" "fcmp")
1036 (cond [(match_operand:SF 1 "" "")
1038 (match_operand:DF 1 "" "")
1041 (const_string "XF")))
1042 (set_attr "athlon_decode" "vector")
1043 (set_attr "amdfam10_decode" "direct")])
1045 (define_insn "*cmpfp_iu_mixed"
1046 [(set (reg:CCFPU FLAGS_REG)
1047 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1048 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1049 "TARGET_MIX_SSE_I387
1050 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1051 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052 "* return output_fp_compare (insn, operands, 1, 1);"
1053 [(set_attr "type" "fcmp,ssecomi")
1055 (if_then_else (match_operand:SF 1 "" "")
1057 (const_string "DF")))
1058 (set_attr "athlon_decode" "vector")
1059 (set_attr "amdfam10_decode" "direct")])
1061 (define_insn "*cmpfp_iu_sse"
1062 [(set (reg:CCFPU FLAGS_REG)
1063 (compare:CCFPU (match_operand 0 "register_operand" "x")
1064 (match_operand 1 "nonimmediate_operand" "xm")))]
1066 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1068 "* return output_fp_compare (insn, operands, 1, 1);"
1069 [(set_attr "type" "ssecomi")
1071 (if_then_else (match_operand:SF 1 "" "")
1073 (const_string "DF")))
1074 (set_attr "athlon_decode" "vector")
1075 (set_attr "amdfam10_decode" "direct")])
1077 (define_insn "*cmpfp_iu_387"
1078 [(set (reg:CCFPU FLAGS_REG)
1079 (compare:CCFPU (match_operand 0 "register_operand" "f")
1080 (match_operand 1 "register_operand" "f")))]
1081 "TARGET_80387 && TARGET_CMOVE
1082 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1083 && FLOAT_MODE_P (GET_MODE (operands[0]))
1084 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1085 "* return output_fp_compare (insn, operands, 1, 1);"
1086 [(set_attr "type" "fcmp")
1088 (cond [(match_operand:SF 1 "" "")
1090 (match_operand:DF 1 "" "")
1093 (const_string "XF")))
1094 (set_attr "athlon_decode" "vector")
1095 (set_attr "amdfam10_decode" "direct")])
1097 ;; Move instructions.
1099 ;; General case of fullword move.
1101 (define_expand "movsi"
1102 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1103 (match_operand:SI 1 "general_operand" ""))]
1105 "ix86_expand_move (SImode, operands); DONE;")
1107 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1110 ;; %%% We don't use a post-inc memory reference because x86 is not a
1111 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1112 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1113 ;; targets without our curiosities, and it is just as easy to represent
1114 ;; this differently.
1116 (define_insn "*pushsi2"
1117 [(set (match_operand:SI 0 "push_operand" "=<")
1118 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1121 [(set_attr "type" "push")
1122 (set_attr "mode" "SI")])
1124 ;; For 64BIT abi we always round up to 8 bytes.
1125 (define_insn "*pushsi2_rex64"
1126 [(set (match_operand:SI 0 "push_operand" "=X")
1127 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1130 [(set_attr "type" "push")
1131 (set_attr "mode" "SI")])
1133 (define_insn "*pushsi2_prologue"
1134 [(set (match_operand:SI 0 "push_operand" "=<")
1135 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1136 (clobber (mem:BLK (scratch)))]
1139 [(set_attr "type" "push")
1140 (set_attr "mode" "SI")])
1142 (define_insn "*popsi1_epilogue"
1143 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144 (mem:SI (reg:SI SP_REG)))
1145 (set (reg:SI SP_REG)
1146 (plus:SI (reg:SI SP_REG) (const_int 4)))
1147 (clobber (mem:BLK (scratch)))]
1150 [(set_attr "type" "pop")
1151 (set_attr "mode" "SI")])
1153 (define_insn "popsi1"
1154 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1155 (mem:SI (reg:SI SP_REG)))
1156 (set (reg:SI SP_REG)
1157 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1160 [(set_attr "type" "pop")
1161 (set_attr "mode" "SI")])
1163 (define_insn "*movsi_xor"
1164 [(set (match_operand:SI 0 "register_operand" "=r")
1165 (match_operand:SI 1 "const0_operand" "i"))
1166 (clobber (reg:CC FLAGS_REG))]
1167 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1168 "xor{l}\t{%0, %0|%0, %0}"
1169 [(set_attr "type" "alu1")
1170 (set_attr "mode" "SI")
1171 (set_attr "length_immediate" "0")])
1173 (define_insn "*movsi_or"
1174 [(set (match_operand:SI 0 "register_operand" "=r")
1175 (match_operand:SI 1 "immediate_operand" "i"))
1176 (clobber (reg:CC FLAGS_REG))]
1178 && operands[1] == constm1_rtx
1179 && (TARGET_PENTIUM || optimize_size)"
1181 operands[1] = constm1_rtx;
1182 return "or{l}\t{%1, %0|%0, %1}";
1184 [(set_attr "type" "alu1")
1185 (set_attr "mode" "SI")
1186 (set_attr "length_immediate" "1")])
1188 (define_insn "*movsi_1"
1189 [(set (match_operand:SI 0 "nonimmediate_operand"
1190 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1191 (match_operand:SI 1 "general_operand"
1192 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1193 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1195 switch (get_attr_type (insn))
1198 if (get_attr_mode (insn) == MODE_TI)
1199 return "pxor\t%0, %0";
1200 return "xorps\t%0, %0";
1203 switch (get_attr_mode (insn))
1206 return "movdqa\t{%1, %0|%0, %1}";
1208 return "movaps\t{%1, %0|%0, %1}";
1210 return "movd\t{%1, %0|%0, %1}";
1212 return "movss\t{%1, %0|%0, %1}";
1218 return "pxor\t%0, %0";
1221 if (get_attr_mode (insn) == MODE_DI)
1222 return "movq\t{%1, %0|%0, %1}";
1223 return "movd\t{%1, %0|%0, %1}";
1226 return "lea{l}\t{%1, %0|%0, %1}";
1229 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230 return "mov{l}\t{%1, %0|%0, %1}";
1234 (cond [(eq_attr "alternative" "2")
1235 (const_string "mmxadd")
1236 (eq_attr "alternative" "3,4,5")
1237 (const_string "mmxmov")
1238 (eq_attr "alternative" "6")
1239 (const_string "sselog1")
1240 (eq_attr "alternative" "7,8,9,10,11")
1241 (const_string "ssemov")
1242 (match_operand:DI 1 "pic_32bit_operand" "")
1243 (const_string "lea")
1245 (const_string "imov")))
1247 (cond [(eq_attr "alternative" "2,3")
1249 (eq_attr "alternative" "6,7")
1251 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252 (const_string "V4SF")
1253 (const_string "TI"))
1254 (and (eq_attr "alternative" "8,9,10,11")
1255 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1258 (const_string "SI")))])
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1268 movabs{l}\t{%1, %P0|%P0, %1}
1269 mov{l}\t{%1, %a0|%a0, %1}"
1270 [(set_attr "type" "imov")
1271 (set_attr "modrm" "0,*")
1272 (set_attr "length_address" "8,0")
1273 (set_attr "length_immediate" "0,*")
1274 (set_attr "memory" "store")
1275 (set_attr "mode" "SI")])
1277 (define_insn "*movabssi_2_rex64"
1278 [(set (match_operand:SI 0 "register_operand" "=a,r")
1279 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1282 movabs{l}\t{%P1, %0|%0, %P1}
1283 mov{l}\t{%a1, %0|%0, %a1}"
1284 [(set_attr "type" "imov")
1285 (set_attr "modrm" "0,*")
1286 (set_attr "length_address" "8,0")
1287 (set_attr "length_immediate" "0")
1288 (set_attr "memory" "load")
1289 (set_attr "mode" "SI")])
1291 (define_insn "*swapsi"
1292 [(set (match_operand:SI 0 "register_operand" "+r")
1293 (match_operand:SI 1 "register_operand" "+r"))
1298 [(set_attr "type" "imov")
1299 (set_attr "mode" "SI")
1300 (set_attr "pent_pair" "np")
1301 (set_attr "athlon_decode" "vector")
1302 (set_attr "amdfam10_decode" "double")])
1304 (define_expand "movhi"
1305 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306 (match_operand:HI 1 "general_operand" ""))]
1308 "ix86_expand_move (HImode, operands); DONE;")
1310 (define_insn "*pushhi2"
1311 [(set (match_operand:HI 0 "push_operand" "=X")
1312 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1315 [(set_attr "type" "push")
1316 (set_attr "mode" "SI")])
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320 [(set (match_operand:HI 0 "push_operand" "=X")
1321 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1324 [(set_attr "type" "push")
1325 (set_attr "mode" "DI")])
1327 (define_insn "*movhi_1"
1328 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1332 switch (get_attr_type (insn))
1335 /* movzwl is faster than movw on p2 due to partial word stalls,
1336 though not as fast as an aligned movl. */
1337 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1339 if (get_attr_mode (insn) == MODE_SI)
1340 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1342 return "mov{w}\t{%1, %0|%0, %1}";
1346 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347 (const_string "imov")
1348 (and (eq_attr "alternative" "0")
1349 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1351 (eq (symbol_ref "TARGET_HIMODE_MATH")
1353 (const_string "imov")
1354 (and (eq_attr "alternative" "1,2")
1355 (match_operand:HI 1 "aligned_operand" ""))
1356 (const_string "imov")
1357 (and (ne (symbol_ref "TARGET_MOVX")
1359 (eq_attr "alternative" "0,2"))
1360 (const_string "imovx")
1362 (const_string "imov")))
1364 (cond [(eq_attr "type" "imovx")
1366 (and (eq_attr "alternative" "1,2")
1367 (match_operand:HI 1 "aligned_operand" ""))
1369 (and (eq_attr "alternative" "0")
1370 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1372 (eq (symbol_ref "TARGET_HIMODE_MATH")
1376 (const_string "HI")))])
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1386 movabs{w}\t{%1, %P0|%P0, %1}
1387 mov{w}\t{%1, %a0|%a0, %1}"
1388 [(set_attr "type" "imov")
1389 (set_attr "modrm" "0,*")
1390 (set_attr "length_address" "8,0")
1391 (set_attr "length_immediate" "0,*")
1392 (set_attr "memory" "store")
1393 (set_attr "mode" "HI")])
1395 (define_insn "*movabshi_2_rex64"
1396 [(set (match_operand:HI 0 "register_operand" "=a,r")
1397 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1400 movabs{w}\t{%P1, %0|%0, %P1}
1401 mov{w}\t{%a1, %0|%0, %a1}"
1402 [(set_attr "type" "imov")
1403 (set_attr "modrm" "0,*")
1404 (set_attr "length_address" "8,0")
1405 (set_attr "length_immediate" "0")
1406 (set_attr "memory" "load")
1407 (set_attr "mode" "HI")])
1409 (define_insn "*swaphi_1"
1410 [(set (match_operand:HI 0 "register_operand" "+r")
1411 (match_operand:HI 1 "register_operand" "+r"))
1414 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1416 [(set_attr "type" "imov")
1417 (set_attr "mode" "SI")
1418 (set_attr "pent_pair" "np")
1419 (set_attr "athlon_decode" "vector")
1420 (set_attr "amdfam10_decode" "double")])
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424 [(set (match_operand:HI 0 "register_operand" "+r")
1425 (match_operand:HI 1 "register_operand" "+r"))
1428 "TARGET_PARTIAL_REG_STALL"
1430 [(set_attr "type" "imov")
1431 (set_attr "mode" "HI")
1432 (set_attr "pent_pair" "np")
1433 (set_attr "athlon_decode" "vector")])
1435 (define_expand "movstricthi"
1436 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437 (match_operand:HI 1 "general_operand" ""))]
1438 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1440 /* Don't generate memory->memory moves, go through a register */
1441 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442 operands[1] = force_reg (HImode, operands[1]);
1445 (define_insn "*movstricthi_1"
1446 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447 (match_operand:HI 1 "general_operand" "rn,m"))]
1448 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450 "mov{w}\t{%1, %0|%0, %1}"
1451 [(set_attr "type" "imov")
1452 (set_attr "mode" "HI")])
1454 (define_insn "*movstricthi_xor"
1455 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456 (match_operand:HI 1 "const0_operand" "i"))
1457 (clobber (reg:CC FLAGS_REG))]
1459 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1460 "xor{w}\t{%0, %0|%0, %0}"
1461 [(set_attr "type" "alu1")
1462 (set_attr "mode" "HI")
1463 (set_attr "length_immediate" "0")])
1465 (define_expand "movqi"
1466 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467 (match_operand:QI 1 "general_operand" ""))]
1469 "ix86_expand_move (QImode, operands); DONE;")
1471 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1472 ;; "push a byte". But actually we use pushl, which has the effect
1473 ;; of rounding the amount pushed up to a word.
1475 (define_insn "*pushqi2"
1476 [(set (match_operand:QI 0 "push_operand" "=X")
1477 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1480 [(set_attr "type" "push")
1481 (set_attr "mode" "SI")])
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485 [(set (match_operand:QI 0 "push_operand" "=X")
1486 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1489 [(set_attr "type" "push")
1490 (set_attr "mode" "DI")])
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there. Then we use movzx.
1502 (define_insn "*movqi_1"
1503 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1505 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1507 switch (get_attr_type (insn))
1510 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1511 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1513 if (get_attr_mode (insn) == MODE_SI)
1514 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1516 return "mov{b}\t{%1, %0|%0, %1}";
1520 (cond [(and (eq_attr "alternative" "5")
1521 (not (match_operand:QI 1 "aligned_operand" "")))
1522 (const_string "imovx")
1523 (ne (symbol_ref "optimize_size") (const_int 0))
1524 (const_string "imov")
1525 (and (eq_attr "alternative" "3")
1526 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1528 (eq (symbol_ref "TARGET_QIMODE_MATH")
1530 (const_string "imov")
1531 (eq_attr "alternative" "3,5")
1532 (const_string "imovx")
1533 (and (ne (symbol_ref "TARGET_MOVX")
1535 (eq_attr "alternative" "2"))
1536 (const_string "imovx")
1538 (const_string "imov")))
1540 (cond [(eq_attr "alternative" "3,4,5")
1542 (eq_attr "alternative" "6")
1544 (eq_attr "type" "imovx")
1546 (and (eq_attr "type" "imov")
1547 (and (eq_attr "alternative" "0,1")
1548 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1550 (and (eq (symbol_ref "optimize_size")
1552 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1555 ;; Avoid partial register stalls when not using QImode arithmetic
1556 (and (eq_attr "type" "imov")
1557 (and (eq_attr "alternative" "0,1")
1558 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1560 (eq (symbol_ref "TARGET_QIMODE_MATH")
1564 (const_string "QI")))])
1566 (define_expand "reload_outqi"
1567 [(parallel [(match_operand:QI 0 "" "=m")
1568 (match_operand:QI 1 "register_operand" "r")
1569 (match_operand:QI 2 "register_operand" "=&q")])]
1573 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1575 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1576 if (! q_regs_operand (op1, QImode))
1578 emit_insn (gen_movqi (op2, op1));
1581 emit_insn (gen_movqi (op0, op1));
1585 (define_insn "*swapqi_1"
1586 [(set (match_operand:QI 0 "register_operand" "+r")
1587 (match_operand:QI 1 "register_operand" "+r"))
1590 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1592 [(set_attr "type" "imov")
1593 (set_attr "mode" "SI")
1594 (set_attr "pent_pair" "np")
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "vector")])
1598 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1599 (define_insn "*swapqi_2"
1600 [(set (match_operand:QI 0 "register_operand" "+q")
1601 (match_operand:QI 1 "register_operand" "+q"))
1604 "TARGET_PARTIAL_REG_STALL"
1606 [(set_attr "type" "imov")
1607 (set_attr "mode" "QI")
1608 (set_attr "pent_pair" "np")
1609 (set_attr "athlon_decode" "vector")])
1611 (define_expand "movstrictqi"
1612 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1613 (match_operand:QI 1 "general_operand" ""))]
1614 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1616 /* Don't generate memory->memory moves, go through a register. */
1617 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1618 operands[1] = force_reg (QImode, operands[1]);
1621 (define_insn "*movstrictqi_1"
1622 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1623 (match_operand:QI 1 "general_operand" "*qn,m"))]
1624 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1625 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626 "mov{b}\t{%1, %0|%0, %1}"
1627 [(set_attr "type" "imov")
1628 (set_attr "mode" "QI")])
1630 (define_insn "*movstrictqi_xor"
1631 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1632 (match_operand:QI 1 "const0_operand" "i"))
1633 (clobber (reg:CC FLAGS_REG))]
1634 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1635 "xor{b}\t{%0, %0|%0, %0}"
1636 [(set_attr "type" "alu1")
1637 (set_attr "mode" "QI")
1638 (set_attr "length_immediate" "0")])
1640 (define_insn "*movsi_extv_1"
1641 [(set (match_operand:SI 0 "register_operand" "=R")
1642 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1646 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1647 [(set_attr "type" "imovx")
1648 (set_attr "mode" "SI")])
1650 (define_insn "*movhi_extv_1"
1651 [(set (match_operand:HI 0 "register_operand" "=R")
1652 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1656 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1657 [(set_attr "type" "imovx")
1658 (set_attr "mode" "SI")])
1660 (define_insn "*movqi_extv_1"
1661 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1662 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1667 switch (get_attr_type (insn))
1670 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1672 return "mov{b}\t{%h1, %0|%0, %h1}";
1676 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678 (ne (symbol_ref "TARGET_MOVX")
1680 (const_string "imovx")
1681 (const_string "imov")))
1683 (if_then_else (eq_attr "type" "imovx")
1685 (const_string "QI")))])
1687 (define_insn "*movqi_extv_1_rex64"
1688 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1689 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1694 switch (get_attr_type (insn))
1697 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1699 return "mov{b}\t{%h1, %0|%0, %h1}";
1703 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1704 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1705 (ne (symbol_ref "TARGET_MOVX")
1707 (const_string "imovx")
1708 (const_string "imov")))
1710 (if_then_else (eq_attr "type" "imovx")
1712 (const_string "QI")))])
1714 ;; Stores and loads of ax to arbitrary constant address.
1715 ;; We fake an second form of instruction to force reload to load address
1716 ;; into register when rax is not available
1717 (define_insn "*movabsqi_1_rex64"
1718 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1719 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1720 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1722 movabs{b}\t{%1, %P0|%P0, %1}
1723 mov{b}\t{%1, %a0|%a0, %1}"
1724 [(set_attr "type" "imov")
1725 (set_attr "modrm" "0,*")
1726 (set_attr "length_address" "8,0")
1727 (set_attr "length_immediate" "0,*")
1728 (set_attr "memory" "store")
1729 (set_attr "mode" "QI")])
1731 (define_insn "*movabsqi_2_rex64"
1732 [(set (match_operand:QI 0 "register_operand" "=a,r")
1733 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1734 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1736 movabs{b}\t{%P1, %0|%0, %P1}
1737 mov{b}\t{%a1, %0|%0, %a1}"
1738 [(set_attr "type" "imov")
1739 (set_attr "modrm" "0,*")
1740 (set_attr "length_address" "8,0")
1741 (set_attr "length_immediate" "0")
1742 (set_attr "memory" "load")
1743 (set_attr "mode" "QI")])
1745 (define_insn "*movdi_extzv_1"
1746 [(set (match_operand:DI 0 "register_operand" "=R")
1747 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1751 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1752 [(set_attr "type" "imovx")
1753 (set_attr "mode" "DI")])
1755 (define_insn "*movsi_extzv_1"
1756 [(set (match_operand:SI 0 "register_operand" "=R")
1757 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1761 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1762 [(set_attr "type" "imovx")
1763 (set_attr "mode" "SI")])
1765 (define_insn "*movqi_extzv_2"
1766 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1767 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1772 switch (get_attr_type (insn))
1775 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1777 return "mov{b}\t{%h1, %0|%0, %h1}";
1781 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1782 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1783 (ne (symbol_ref "TARGET_MOVX")
1785 (const_string "imovx")
1786 (const_string "imov")))
1788 (if_then_else (eq_attr "type" "imovx")
1790 (const_string "QI")))])
1792 (define_insn "*movqi_extzv_2_rex64"
1793 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1794 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1799 switch (get_attr_type (insn))
1802 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1804 return "mov{b}\t{%h1, %0|%0, %h1}";
1808 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1809 (ne (symbol_ref "TARGET_MOVX")
1811 (const_string "imovx")
1812 (const_string "imov")))
1814 (if_then_else (eq_attr "type" "imovx")
1816 (const_string "QI")))])
1818 (define_insn "movsi_insv_1"
1819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1822 (match_operand:SI 1 "general_operand" "Qmn"))]
1824 "mov{b}\t{%b1, %h0|%h0, %b1}"
1825 [(set_attr "type" "imov")
1826 (set_attr "mode" "QI")])
1828 (define_insn "*movsi_insv_1_rex64"
1829 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1832 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1834 "mov{b}\t{%b1, %h0|%h0, %b1}"
1835 [(set_attr "type" "imov")
1836 (set_attr "mode" "QI")])
1838 (define_insn "movdi_insv_1_rex64"
1839 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1842 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1844 "mov{b}\t{%b1, %h0|%h0, %b1}"
1845 [(set_attr "type" "imov")
1846 (set_attr "mode" "QI")])
1848 (define_insn "*movqi_insv_2"
1849 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1852 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1855 "mov{b}\t{%h1, %h0|%h0, %h1}"
1856 [(set_attr "type" "imov")
1857 (set_attr "mode" "QI")])
1859 (define_expand "movdi"
1860 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1861 (match_operand:DI 1 "general_operand" ""))]
1863 "ix86_expand_move (DImode, operands); DONE;")
1865 (define_insn "*pushdi"
1866 [(set (match_operand:DI 0 "push_operand" "=<")
1867 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1871 (define_insn "*pushdi2_rex64"
1872 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1873 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1878 [(set_attr "type" "push,multi")
1879 (set_attr "mode" "DI")])
1881 ;; Convert impossible pushes of immediate to existing instructions.
1882 ;; First try to get scratch register and go through it. In case this
1883 ;; fails, push sign extended lower part first and then overwrite
1884 ;; upper part by 32bit move.
1886 [(match_scratch:DI 2 "r")
1887 (set (match_operand:DI 0 "push_operand" "")
1888 (match_operand:DI 1 "immediate_operand" ""))]
1889 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890 && !x86_64_immediate_operand (operands[1], DImode)"
1891 [(set (match_dup 2) (match_dup 1))
1892 (set (match_dup 0) (match_dup 2))]
1895 ;; We need to define this as both peepholer and splitter for case
1896 ;; peephole2 pass is not run.
1897 ;; "&& 1" is needed to keep it from matching the previous pattern.
1899 [(set (match_operand:DI 0 "push_operand" "")
1900 (match_operand:DI 1 "immediate_operand" ""))]
1901 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1902 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1903 [(set (match_dup 0) (match_dup 1))
1904 (set (match_dup 2) (match_dup 3))]
1905 "split_di (operands + 1, 1, operands + 2, operands + 3);
1906 operands[1] = gen_lowpart (DImode, operands[2]);
1907 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1912 [(set (match_operand:DI 0 "push_operand" "")
1913 (match_operand:DI 1 "immediate_operand" ""))]
1914 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1915 ? flow2_completed : reload_completed)
1916 && !symbolic_operand (operands[1], DImode)
1917 && !x86_64_immediate_operand (operands[1], DImode)"
1918 [(set (match_dup 0) (match_dup 1))
1919 (set (match_dup 2) (match_dup 3))]
1920 "split_di (operands + 1, 1, operands + 2, operands + 3);
1921 operands[1] = gen_lowpart (DImode, operands[2]);
1922 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1926 (define_insn "*pushdi2_prologue_rex64"
1927 [(set (match_operand:DI 0 "push_operand" "=<")
1928 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1929 (clobber (mem:BLK (scratch)))]
1932 [(set_attr "type" "push")
1933 (set_attr "mode" "DI")])
1935 (define_insn "*popdi1_epilogue_rex64"
1936 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1937 (mem:DI (reg:DI SP_REG)))
1938 (set (reg:DI SP_REG)
1939 (plus:DI (reg:DI SP_REG) (const_int 8)))
1940 (clobber (mem:BLK (scratch)))]
1943 [(set_attr "type" "pop")
1944 (set_attr "mode" "DI")])
1946 (define_insn "popdi1"
1947 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1948 (mem:DI (reg:DI SP_REG)))
1949 (set (reg:DI SP_REG)
1950 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1953 [(set_attr "type" "pop")
1954 (set_attr "mode" "DI")])
1956 (define_insn "*movdi_xor_rex64"
1957 [(set (match_operand:DI 0 "register_operand" "=r")
1958 (match_operand:DI 1 "const0_operand" "i"))
1959 (clobber (reg:CC FLAGS_REG))]
1960 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1961 && reload_completed"
1962 "xor{l}\t{%k0, %k0|%k0, %k0}"
1963 [(set_attr "type" "alu1")
1964 (set_attr "mode" "SI")
1965 (set_attr "length_immediate" "0")])
1967 (define_insn "*movdi_or_rex64"
1968 [(set (match_operand:DI 0 "register_operand" "=r")
1969 (match_operand:DI 1 "const_int_operand" "i"))
1970 (clobber (reg:CC FLAGS_REG))]
1971 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1973 && operands[1] == constm1_rtx"
1975 operands[1] = constm1_rtx;
1976 return "or{q}\t{%1, %0|%0, %1}";
1978 [(set_attr "type" "alu1")
1979 (set_attr "mode" "DI")
1980 (set_attr "length_immediate" "1")])
1982 (define_insn "*movdi_2"
1983 [(set (match_operand:DI 0 "nonimmediate_operand"
1984 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
1985 (match_operand:DI 1 "general_operand"
1986 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
1987 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 movq\t{%1, %0|%0, %1}
1993 movq\t{%1, %0|%0, %1}
1995 movq\t{%1, %0|%0, %1}
1996 movdqa\t{%1, %0|%0, %1}
1997 movq\t{%1, %0|%0, %1}
1999 movlps\t{%1, %0|%0, %1}
2000 movaps\t{%1, %0|%0, %1}
2001 movlps\t{%1, %0|%0, %1}"
2002 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2006 [(set (match_operand:DI 0 "push_operand" "")
2007 (match_operand:DI 1 "general_operand" ""))]
2008 "!TARGET_64BIT && reload_completed
2009 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2011 "ix86_split_long_move (operands); DONE;")
2013 ;; %%% This multiword shite has got to go.
2015 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016 (match_operand:DI 1 "general_operand" ""))]
2017 "!TARGET_64BIT && reload_completed
2018 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2021 "ix86_split_long_move (operands); DONE;")
2023 (define_insn "*movdi_1_rex64"
2024 [(set (match_operand:DI 0 "nonimmediate_operand"
2025 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2026 (match_operand:DI 1 "general_operand"
2027 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2028 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2030 switch (get_attr_type (insn))
2033 if (SSE_REG_P (operands[0]))
2034 return "movq2dq\t{%1, %0|%0, %1}";
2036 return "movdq2q\t{%1, %0|%0, %1}";
2039 if (get_attr_mode (insn) == MODE_TI)
2040 return "movdqa\t{%1, %0|%0, %1}";
2044 /* Moves from and into integer register is done using movd
2045 opcode with REX prefix. */
2046 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2047 return "movd\t{%1, %0|%0, %1}";
2048 return "movq\t{%1, %0|%0, %1}";
2052 return "pxor\t%0, %0";
2058 return "lea{q}\t{%a1, %0|%0, %a1}";
2061 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2062 if (get_attr_mode (insn) == MODE_SI)
2063 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2064 else if (which_alternative == 2)
2065 return "movabs{q}\t{%1, %0|%0, %1}";
2067 return "mov{q}\t{%1, %0|%0, %1}";
2071 (cond [(eq_attr "alternative" "5")
2072 (const_string "mmxadd")
2073 (eq_attr "alternative" "6,7,8,9,10")
2074 (const_string "mmxmov")
2075 (eq_attr "alternative" "11")
2076 (const_string "sselog1")
2077 (eq_attr "alternative" "12,13,14,15,16")
2078 (const_string "ssemov")
2079 (eq_attr "alternative" "17,18")
2080 (const_string "ssecvt")
2081 (eq_attr "alternative" "4")
2082 (const_string "multi")
2083 (match_operand:DI 1 "pic_32bit_operand" "")
2084 (const_string "lea")
2086 (const_string "imov")))
2087 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2088 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2091 ;; Stores and loads of ax to arbitrary constant address.
2092 ;; We fake an second form of instruction to force reload to load address
2093 ;; into register when rax is not available
2094 (define_insn "*movabsdi_1_rex64"
2095 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2096 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2097 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2099 movabs{q}\t{%1, %P0|%P0, %1}
2100 mov{q}\t{%1, %a0|%a0, %1}"
2101 [(set_attr "type" "imov")
2102 (set_attr "modrm" "0,*")
2103 (set_attr "length_address" "8,0")
2104 (set_attr "length_immediate" "0,*")
2105 (set_attr "memory" "store")
2106 (set_attr "mode" "DI")])
2108 (define_insn "*movabsdi_2_rex64"
2109 [(set (match_operand:DI 0 "register_operand" "=a,r")
2110 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2111 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2113 movabs{q}\t{%P1, %0|%0, %P1}
2114 mov{q}\t{%a1, %0|%0, %a1}"
2115 [(set_attr "type" "imov")
2116 (set_attr "modrm" "0,*")
2117 (set_attr "length_address" "8,0")
2118 (set_attr "length_immediate" "0")
2119 (set_attr "memory" "load")
2120 (set_attr "mode" "DI")])
2122 ;; Convert impossible stores of immediate to existing instructions.
2123 ;; First try to get scratch register and go through it. In case this
2124 ;; fails, move by 32bit parts.
2126 [(match_scratch:DI 2 "r")
2127 (set (match_operand:DI 0 "memory_operand" "")
2128 (match_operand:DI 1 "immediate_operand" ""))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode)"
2131 [(set (match_dup 2) (match_dup 1))
2132 (set (match_dup 0) (match_dup 2))]
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2139 [(set (match_operand:DI 0 "memory_operand" "")
2140 (match_operand:DI 1 "immediate_operand" ""))]
2141 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143 [(set (match_dup 2) (match_dup 3))
2144 (set (match_dup 4) (match_dup 5))]
2145 "split_di (operands, 2, operands + 2, operands + 4);")
2148 [(set (match_operand:DI 0 "memory_operand" "")
2149 (match_operand:DI 1 "immediate_operand" ""))]
2150 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151 ? flow2_completed : reload_completed)
2152 && !symbolic_operand (operands[1], DImode)
2153 && !x86_64_immediate_operand (operands[1], DImode)"
2154 [(set (match_dup 2) (match_dup 3))
2155 (set (match_dup 4) (match_dup 5))]
2156 "split_di (operands, 2, operands + 2, operands + 4);")
2158 (define_insn "*swapdi_rex64"
2159 [(set (match_operand:DI 0 "register_operand" "+r")
2160 (match_operand:DI 1 "register_operand" "+r"))
2165 [(set_attr "type" "imov")
2166 (set_attr "mode" "DI")
2167 (set_attr "pent_pair" "np")
2168 (set_attr "athlon_decode" "vector")
2169 (set_attr "amdfam10_decode" "double")])
2171 (define_expand "movti"
2172 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2173 (match_operand:TI 1 "nonimmediate_operand" ""))]
2174 "TARGET_SSE || TARGET_64BIT"
2177 ix86_expand_move (TImode, operands);
2179 ix86_expand_vector_move (TImode, operands);
2183 (define_insn "*movti_internal"
2184 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2185 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2186 "TARGET_SSE && !TARGET_64BIT
2187 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 switch (which_alternative)
2192 if (get_attr_mode (insn) == MODE_V4SF)
2193 return "xorps\t%0, %0";
2195 return "pxor\t%0, %0";
2198 if (get_attr_mode (insn) == MODE_V4SF)
2199 return "movaps\t{%1, %0|%0, %1}";
2201 return "movdqa\t{%1, %0|%0, %1}";
2206 [(set_attr "type" "sselog1,ssemov,ssemov")
2208 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2209 (ne (symbol_ref "optimize_size") (const_int 0)))
2210 (const_string "V4SF")
2211 (and (eq_attr "alternative" "2")
2212 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2214 (const_string "V4SF")]
2215 (const_string "TI")))])
2217 (define_insn "*movti_rex64"
2218 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2219 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2221 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2223 switch (which_alternative)
2229 if (get_attr_mode (insn) == MODE_V4SF)
2230 return "xorps\t%0, %0";
2232 return "pxor\t%0, %0";
2235 if (get_attr_mode (insn) == MODE_V4SF)
2236 return "movaps\t{%1, %0|%0, %1}";
2238 return "movdqa\t{%1, %0|%0, %1}";
2243 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2245 (cond [(eq_attr "alternative" "2,3")
2247 (ne (symbol_ref "optimize_size")
2249 (const_string "V4SF")
2250 (const_string "TI"))
2251 (eq_attr "alternative" "4")
2253 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2255 (ne (symbol_ref "optimize_size")
2257 (const_string "V4SF")
2258 (const_string "TI"))]
2259 (const_string "DI")))])
2262 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2263 (match_operand:TI 1 "general_operand" ""))]
2264 "reload_completed && !SSE_REG_P (operands[0])
2265 && !SSE_REG_P (operands[1])"
2267 "ix86_split_long_move (operands); DONE;")
2269 (define_expand "movsf"
2270 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2271 (match_operand:SF 1 "general_operand" ""))]
2273 "ix86_expand_move (SFmode, operands); DONE;")
2275 (define_insn "*pushsf"
2276 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2277 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2280 /* Anything else should be already split before reg-stack. */
2281 gcc_assert (which_alternative == 1);
2282 return "push{l}\t%1";
2284 [(set_attr "type" "multi,push,multi")
2285 (set_attr "unit" "i387,*,*")
2286 (set_attr "mode" "SF,SI,SF")])
2288 (define_insn "*pushsf_rex64"
2289 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2290 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2293 /* Anything else should be already split before reg-stack. */
2294 gcc_assert (which_alternative == 1);
2295 return "push{q}\t%q1";
2297 [(set_attr "type" "multi,push,multi")
2298 (set_attr "unit" "i387,*,*")
2299 (set_attr "mode" "SF,DI,SF")])
2302 [(set (match_operand:SF 0 "push_operand" "")
2303 (match_operand:SF 1 "memory_operand" ""))]
2305 && MEM_P (operands[1])
2306 && constant_pool_reference_p (operands[1])"
2309 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2312 ;; %%% Kill this when call knows how to work this out.
2314 [(set (match_operand:SF 0 "push_operand" "")
2315 (match_operand:SF 1 "any_fp_register_operand" ""))]
2317 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2318 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2321 [(set (match_operand:SF 0 "push_operand" "")
2322 (match_operand:SF 1 "any_fp_register_operand" ""))]
2324 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2325 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2327 (define_insn "*movsf_1"
2328 [(set (match_operand:SF 0 "nonimmediate_operand"
2329 "=f,m,f,r ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r ")
2330 (match_operand:SF 1 "general_operand"
2331 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r ,*Ym"))]
2332 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2333 && (reload_in_progress || reload_completed
2334 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2335 || (!TARGET_SSE_MATH && optimize_size
2336 && standard_80387_constant_p (operands[1]))
2337 || GET_CODE (operands[1]) != CONST_DOUBLE
2338 || memory_operand (operands[0], SFmode))"
2340 switch (which_alternative)
2343 return output_387_reg_move (insn, operands);
2346 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2347 return "fstp%z0\t%y0";
2349 return "fst%z0\t%y0";
2352 return standard_80387_constant_opcode (operands[1]);
2356 return "mov{l}\t{%1, %0|%0, %1}";
2358 if (get_attr_mode (insn) == MODE_TI)
2359 return "pxor\t%0, %0";
2361 return "xorps\t%0, %0";
2363 if (get_attr_mode (insn) == MODE_V4SF)
2364 return "movaps\t{%1, %0|%0, %1}";
2366 return "movss\t{%1, %0|%0, %1}";
2368 return "movss\t{%1, %0|%0, %1}";
2371 case 12: case 13: case 14: case 15:
2372 return "movd\t{%1, %0|%0, %1}";
2375 return "movq\t{%1, %0|%0, %1}";
2381 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2383 (cond [(eq_attr "alternative" "3,4,9,10")
2385 (eq_attr "alternative" "5")
2387 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2389 (ne (symbol_ref "TARGET_SSE2")
2391 (eq (symbol_ref "optimize_size")
2394 (const_string "V4SF"))
2395 /* For architectures resolving dependencies on
2396 whole SSE registers use APS move to break dependency
2397 chains, otherwise use short move to avoid extra work.
2399 Do the same for architectures resolving dependencies on
2400 the parts. While in DF mode it is better to always handle
2401 just register parts, the SF mode is different due to lack
2402 of instructions to load just part of the register. It is
2403 better to maintain the whole registers in single format
2404 to avoid problems on using packed logical operations. */
2405 (eq_attr "alternative" "6")
2407 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2409 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2411 (const_string "V4SF")
2412 (const_string "SF"))
2413 (eq_attr "alternative" "11")
2414 (const_string "DI")]
2415 (const_string "SF")))])
2417 (define_insn "*swapsf"
2418 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2419 (match_operand:SF 1 "fp_register_operand" "+f"))
2422 "reload_completed || TARGET_80387"
2424 if (STACK_TOP_P (operands[0]))
2429 [(set_attr "type" "fxch")
2430 (set_attr "mode" "SF")])
2432 (define_expand "movdf"
2433 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2434 (match_operand:DF 1 "general_operand" ""))]
2436 "ix86_expand_move (DFmode, operands); DONE;")
2438 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2439 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2440 ;; On the average, pushdf using integers can be still shorter. Allow this
2441 ;; pattern for optimize_size too.
2443 (define_insn "*pushdf_nointeger"
2444 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2445 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2446 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2448 /* This insn should be already split before reg-stack. */
2451 [(set_attr "type" "multi")
2452 (set_attr "unit" "i387,*,*,*")
2453 (set_attr "mode" "DF,SI,SI,DF")])
2455 (define_insn "*pushdf_integer"
2456 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2457 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2458 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2460 /* This insn should be already split before reg-stack. */
2463 [(set_attr "type" "multi")
2464 (set_attr "unit" "i387,*,*")
2465 (set_attr "mode" "DF,SI,DF")])
2467 ;; %%% Kill this when call knows how to work this out.
2469 [(set (match_operand:DF 0 "push_operand" "")
2470 (match_operand:DF 1 "any_fp_register_operand" ""))]
2471 "!TARGET_64BIT && reload_completed"
2472 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2473 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2477 [(set (match_operand:DF 0 "push_operand" "")
2478 (match_operand:DF 1 "any_fp_register_operand" ""))]
2479 "TARGET_64BIT && reload_completed"
2480 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2481 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2485 [(set (match_operand:DF 0 "push_operand" "")
2486 (match_operand:DF 1 "general_operand" ""))]
2489 "ix86_split_long_move (operands); DONE;")
2491 ;; Moving is usually shorter when only FP registers are used. This separate
2492 ;; movdf pattern avoids the use of integer registers for FP operations
2493 ;; when optimizing for size.
2495 (define_insn "*movdf_nointeger"
2496 [(set (match_operand:DF 0 "nonimmediate_operand"
2497 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2498 (match_operand:DF 1 "general_operand"
2499 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2500 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2501 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2502 && (reload_in_progress || reload_completed
2503 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2504 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2505 && standard_80387_constant_p (operands[1]))
2506 || GET_CODE (operands[1]) != CONST_DOUBLE
2507 || memory_operand (operands[0], DFmode))"
2509 switch (which_alternative)
2512 return output_387_reg_move (insn, operands);
2515 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2516 return "fstp%z0\t%y0";
2518 return "fst%z0\t%y0";
2521 return standard_80387_constant_opcode (operands[1]);
2527 switch (get_attr_mode (insn))
2530 return "xorps\t%0, %0";
2532 return "xorpd\t%0, %0";
2534 return "pxor\t%0, %0";
2541 switch (get_attr_mode (insn))
2544 return "movaps\t{%1, %0|%0, %1}";
2546 return "movapd\t{%1, %0|%0, %1}";
2548 return "movdqa\t{%1, %0|%0, %1}";
2550 return "movq\t{%1, %0|%0, %1}";
2552 return "movsd\t{%1, %0|%0, %1}";
2554 return "movlpd\t{%1, %0|%0, %1}";
2556 return "movlps\t{%1, %0|%0, %1}";
2565 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2567 (cond [(eq_attr "alternative" "0,1,2")
2569 (eq_attr "alternative" "3,4")
2572 /* For SSE1, we have many fewer alternatives. */
2573 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2574 (cond [(eq_attr "alternative" "5,6")
2575 (const_string "V4SF")
2577 (const_string "V2SF"))
2579 /* xorps is one byte shorter. */
2580 (eq_attr "alternative" "5")
2581 (cond [(ne (symbol_ref "optimize_size")
2583 (const_string "V4SF")
2584 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2588 (const_string "V2DF"))
2590 /* For architectures resolving dependencies on
2591 whole SSE registers use APD move to break dependency
2592 chains, otherwise use short move to avoid extra work.
2594 movaps encodes one byte shorter. */
2595 (eq_attr "alternative" "6")
2597 [(ne (symbol_ref "optimize_size")
2599 (const_string "V4SF")
2600 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2602 (const_string "V2DF")
2604 (const_string "DF"))
2605 /* For architectures resolving dependencies on register
2606 parts we may avoid extra work to zero out upper part
2608 (eq_attr "alternative" "7")
2610 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2612 (const_string "V1DF")
2613 (const_string "DF"))
2615 (const_string "DF")))])
2617 (define_insn "*movdf_integer_rex64"
2618 [(set (match_operand:DF 0 "nonimmediate_operand"
2619 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2620 (match_operand:DF 1 "general_operand"
2621 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2622 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2623 && (reload_in_progress || reload_completed
2624 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2625 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2626 && standard_80387_constant_p (operands[1]))
2627 || GET_CODE (operands[1]) != CONST_DOUBLE
2628 || memory_operand (operands[0], DFmode))"
2630 switch (which_alternative)
2633 return output_387_reg_move (insn, operands);
2636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2637 return "fstp%z0\t%y0";
2639 return "fst%z0\t%y0";
2642 return standard_80387_constant_opcode (operands[1]);
2649 switch (get_attr_mode (insn))
2652 return "xorps\t%0, %0";
2654 return "xorpd\t%0, %0";
2656 return "pxor\t%0, %0";
2663 switch (get_attr_mode (insn))
2666 return "movaps\t{%1, %0|%0, %1}";
2668 return "movapd\t{%1, %0|%0, %1}";
2670 return "movdqa\t{%1, %0|%0, %1}";
2672 return "movq\t{%1, %0|%0, %1}";
2674 return "movsd\t{%1, %0|%0, %1}";
2676 return "movlpd\t{%1, %0|%0, %1}";
2678 return "movlps\t{%1, %0|%0, %1}";
2685 return "movd\t{%1, %0|%0, %1}";
2691 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2693 (cond [(eq_attr "alternative" "0,1,2")
2695 (eq_attr "alternative" "3,4,9,10")
2698 /* For SSE1, we have many fewer alternatives. */
2699 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700 (cond [(eq_attr "alternative" "5,6")
2701 (const_string "V4SF")
2703 (const_string "V2SF"))
2705 /* xorps is one byte shorter. */
2706 (eq_attr "alternative" "5")
2707 (cond [(ne (symbol_ref "optimize_size")
2709 (const_string "V4SF")
2710 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2714 (const_string "V2DF"))
2716 /* For architectures resolving dependencies on
2717 whole SSE registers use APD move to break dependency
2718 chains, otherwise use short move to avoid extra work.
2720 movaps encodes one byte shorter. */
2721 (eq_attr "alternative" "6")
2723 [(ne (symbol_ref "optimize_size")
2725 (const_string "V4SF")
2726 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2728 (const_string "V2DF")
2730 (const_string "DF"))
2731 /* For architectures resolving dependencies on register
2732 parts we may avoid extra work to zero out upper part
2734 (eq_attr "alternative" "7")
2736 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2738 (const_string "V1DF")
2739 (const_string "DF"))
2741 (const_string "DF")))])
2743 (define_insn "*movdf_integer"
2744 [(set (match_operand:DF 0 "nonimmediate_operand"
2745 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2746 (match_operand:DF 1 "general_operand"
2747 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2748 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2749 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2750 && (reload_in_progress || reload_completed
2751 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2752 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2753 && standard_80387_constant_p (operands[1]))
2754 || GET_CODE (operands[1]) != CONST_DOUBLE
2755 || memory_operand (operands[0], DFmode))"
2757 switch (which_alternative)
2760 return output_387_reg_move (insn, operands);
2763 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764 return "fstp%z0\t%y0";
2766 return "fst%z0\t%y0";
2769 return standard_80387_constant_opcode (operands[1]);
2776 switch (get_attr_mode (insn))
2779 return "xorps\t%0, %0";
2781 return "xorpd\t%0, %0";
2783 return "pxor\t%0, %0";
2790 switch (get_attr_mode (insn))
2793 return "movaps\t{%1, %0|%0, %1}";
2795 return "movapd\t{%1, %0|%0, %1}";
2797 return "movdqa\t{%1, %0|%0, %1}";
2799 return "movq\t{%1, %0|%0, %1}";
2801 return "movsd\t{%1, %0|%0, %1}";
2803 return "movlpd\t{%1, %0|%0, %1}";
2805 return "movlps\t{%1, %0|%0, %1}";
2814 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2816 (cond [(eq_attr "alternative" "0,1,2")
2818 (eq_attr "alternative" "3,4")
2821 /* For SSE1, we have many fewer alternatives. */
2822 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2823 (cond [(eq_attr "alternative" "5,6")
2824 (const_string "V4SF")
2826 (const_string "V2SF"))
2828 /* xorps is one byte shorter. */
2829 (eq_attr "alternative" "5")
2830 (cond [(ne (symbol_ref "optimize_size")
2832 (const_string "V4SF")
2833 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2837 (const_string "V2DF"))
2839 /* For architectures resolving dependencies on
2840 whole SSE registers use APD move to break dependency
2841 chains, otherwise use short move to avoid extra work.
2843 movaps encodes one byte shorter. */
2844 (eq_attr "alternative" "6")
2846 [(ne (symbol_ref "optimize_size")
2848 (const_string "V4SF")
2849 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2851 (const_string "V2DF")
2853 (const_string "DF"))
2854 /* For architectures resolving dependencies on register
2855 parts we may avoid extra work to zero out upper part
2857 (eq_attr "alternative" "7")
2859 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2861 (const_string "V1DF")
2862 (const_string "DF"))
2864 (const_string "DF")))])
2867 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2868 (match_operand:DF 1 "general_operand" ""))]
2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && ! (ANY_FP_REG_P (operands[0]) ||
2872 (GET_CODE (operands[0]) == SUBREG
2873 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874 && ! (ANY_FP_REG_P (operands[1]) ||
2875 (GET_CODE (operands[1]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2878 "ix86_split_long_move (operands); DONE;")
2880 (define_insn "*swapdf"
2881 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2882 (match_operand:DF 1 "fp_register_operand" "+f"))
2885 "reload_completed || TARGET_80387"
2887 if (STACK_TOP_P (operands[0]))
2892 [(set_attr "type" "fxch")
2893 (set_attr "mode" "DF")])
2895 (define_expand "movxf"
2896 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2897 (match_operand:XF 1 "general_operand" ""))]
2899 "ix86_expand_move (XFmode, operands); DONE;")
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2903 ;; Pushing using integer instructions is longer except for constants
2904 ;; and direct memory references.
2905 ;; (assuming that any given constant is pushed only once, but this ought to be
2906 ;; handled elsewhere).
2908 (define_insn "*pushxf_nointeger"
2909 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2910 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2913 /* This insn should be already split before reg-stack. */
2916 [(set_attr "type" "multi")
2917 (set_attr "unit" "i387,*,*")
2918 (set_attr "mode" "XF,SI,SI")])
2920 (define_insn "*pushxf_integer"
2921 [(set (match_operand:XF 0 "push_operand" "=<,<")
2922 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2925 /* This insn should be already split before reg-stack. */
2928 [(set_attr "type" "multi")
2929 (set_attr "unit" "i387,*")
2930 (set_attr "mode" "XF,SI")])
2933 [(set (match_operand 0 "push_operand" "")
2934 (match_operand 1 "general_operand" ""))]
2936 && (GET_MODE (operands[0]) == XFmode
2937 || GET_MODE (operands[0]) == DFmode)
2938 && !ANY_FP_REG_P (operands[1])"
2940 "ix86_split_long_move (operands); DONE;")
2943 [(set (match_operand:XF 0 "push_operand" "")
2944 (match_operand:XF 1 "any_fp_register_operand" ""))]
2946 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2947 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2948 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2951 [(set (match_operand:XF 0 "push_operand" "")
2952 (match_operand:XF 1 "any_fp_register_operand" ""))]
2954 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2955 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2956 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2958 ;; Do not use integer registers when optimizing for size
2959 (define_insn "*movxf_nointeger"
2960 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2961 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2963 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2964 && (reload_in_progress || reload_completed
2965 || (optimize_size && standard_80387_constant_p (operands[1]))
2966 || GET_CODE (operands[1]) != CONST_DOUBLE
2967 || memory_operand (operands[0], XFmode))"
2969 switch (which_alternative)
2972 return output_387_reg_move (insn, operands);
2975 /* There is no non-popping store to memory for XFmode. So if
2976 we need one, follow the store with a load. */
2977 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2978 return "fstp%z0\t%y0\;fld%z0\t%y0";
2980 return "fstp%z0\t%y0";
2983 return standard_80387_constant_opcode (operands[1]);
2991 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2992 (set_attr "mode" "XF,XF,XF,SI,SI")])
2994 (define_insn "*movxf_integer"
2995 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2996 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2998 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2999 && (reload_in_progress || reload_completed
3000 || (optimize_size && standard_80387_constant_p (operands[1]))
3001 || GET_CODE (operands[1]) != CONST_DOUBLE
3002 || memory_operand (operands[0], XFmode))"
3004 switch (which_alternative)
3007 return output_387_reg_move (insn, operands);
3010 /* There is no non-popping store to memory for XFmode. So if
3011 we need one, follow the store with a load. */
3012 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013 return "fstp%z0\t%y0\;fld%z0\t%y0";
3015 return "fstp%z0\t%y0";
3018 return standard_80387_constant_opcode (operands[1]);
3027 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3028 (set_attr "mode" "XF,XF,XF,SI,SI")])
3031 [(set (match_operand 0 "nonimmediate_operand" "")
3032 (match_operand 1 "general_operand" ""))]
3034 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3035 && GET_MODE (operands[0]) == XFmode
3036 && ! (ANY_FP_REG_P (operands[0]) ||
3037 (GET_CODE (operands[0]) == SUBREG
3038 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039 && ! (ANY_FP_REG_P (operands[1]) ||
3040 (GET_CODE (operands[1]) == SUBREG
3041 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3043 "ix86_split_long_move (operands); DONE;")
3046 [(set (match_operand 0 "register_operand" "")
3047 (match_operand 1 "memory_operand" ""))]
3049 && MEM_P (operands[1])
3050 && (GET_MODE (operands[0]) == XFmode
3051 || GET_MODE (operands[0]) == SFmode
3052 || GET_MODE (operands[0]) == DFmode)
3053 && constant_pool_reference_p (operands[1])"
3054 [(set (match_dup 0) (match_dup 1))]
3056 rtx c = avoid_constant_pool_reference (operands[1]);
3057 rtx r = operands[0];
3059 if (GET_CODE (r) == SUBREG)
3064 if (!standard_sse_constant_p (c))
3067 else if (FP_REG_P (r))
3069 if (!standard_80387_constant_p (c))
3072 else if (MMX_REG_P (r))
3079 [(set (match_operand 0 "register_operand" "")
3080 (float_extend (match_operand 1 "memory_operand" "")))]
3082 && MEM_P (operands[1])
3083 && (GET_MODE (operands[0]) == XFmode
3084 || GET_MODE (operands[0]) == SFmode
3085 || GET_MODE (operands[0]) == DFmode)
3086 && constant_pool_reference_p (operands[1])"
3087 [(set (match_dup 0) (match_dup 1))]
3089 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3090 rtx r = operands[0];
3092 if (GET_CODE (r) == SUBREG)
3097 if (!standard_sse_constant_p (c))
3100 else if (FP_REG_P (r))
3102 if (!standard_80387_constant_p (c))
3105 else if (MMX_REG_P (r))
3111 (define_insn "swapxf"
3112 [(set (match_operand:XF 0 "register_operand" "+f")
3113 (match_operand:XF 1 "register_operand" "+f"))
3118 if (STACK_TOP_P (operands[0]))
3123 [(set_attr "type" "fxch")
3124 (set_attr "mode" "XF")])
3126 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3128 [(set (match_operand:X87MODEF 0 "register_operand" "")
3129 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3130 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3131 && (standard_80387_constant_p (operands[1]) == 8
3132 || standard_80387_constant_p (operands[1]) == 9)"
3133 [(set (match_dup 0)(match_dup 1))
3135 (neg:X87MODEF (match_dup 0)))]
3139 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3140 if (real_isnegzero (&r))
3141 operands[1] = CONST0_RTX (<MODE>mode);
3143 operands[1] = CONST1_RTX (<MODE>mode);
3146 (define_expand "movtf"
3147 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3148 (match_operand:TF 1 "nonimmediate_operand" ""))]
3151 ix86_expand_move (TFmode, operands);
3155 (define_insn "*movtf_internal"
3156 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3157 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3159 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3161 switch (which_alternative)
3167 if (get_attr_mode (insn) == MODE_V4SF)
3168 return "xorps\t%0, %0";
3170 return "pxor\t%0, %0";
3173 if (get_attr_mode (insn) == MODE_V4SF)
3174 return "movaps\t{%1, %0|%0, %1}";
3176 return "movdqa\t{%1, %0|%0, %1}";
3181 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3183 (cond [(eq_attr "alternative" "2,3")
3185 (ne (symbol_ref "optimize_size")
3187 (const_string "V4SF")
3188 (const_string "TI"))
3189 (eq_attr "alternative" "4")
3191 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3193 (ne (symbol_ref "optimize_size")
3195 (const_string "V4SF")
3196 (const_string "TI"))]
3197 (const_string "DI")))])
3200 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201 (match_operand:TF 1 "general_operand" ""))]
3202 "reload_completed && !SSE_REG_P (operands[0])
3203 && !SSE_REG_P (operands[1])"
3205 "ix86_split_long_move (operands); DONE;")
3207 ;; Zero extension instructions
3209 (define_expand "zero_extendhisi2"
3210 [(set (match_operand:SI 0 "register_operand" "")
3211 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3214 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3216 operands[1] = force_reg (HImode, operands[1]);
3217 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3222 (define_insn "zero_extendhisi2_and"
3223 [(set (match_operand:SI 0 "register_operand" "=r")
3224 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3225 (clobber (reg:CC FLAGS_REG))]
3226 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3228 [(set_attr "type" "alu1")
3229 (set_attr "mode" "SI")])
3232 [(set (match_operand:SI 0 "register_operand" "")
3233 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3234 (clobber (reg:CC FLAGS_REG))]
3235 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3236 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3237 (clobber (reg:CC FLAGS_REG))])]
3240 (define_insn "*zero_extendhisi2_movzwl"
3241 [(set (match_operand:SI 0 "register_operand" "=r")
3242 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3244 "movz{wl|x}\t{%1, %0|%0, %1}"
3245 [(set_attr "type" "imovx")
3246 (set_attr "mode" "SI")])
3248 (define_expand "zero_extendqihi2"
3250 [(set (match_operand:HI 0 "register_operand" "")
3251 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252 (clobber (reg:CC FLAGS_REG))])]
3256 (define_insn "*zero_extendqihi2_and"
3257 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3258 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3259 (clobber (reg:CC FLAGS_REG))]
3260 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3262 [(set_attr "type" "alu1")
3263 (set_attr "mode" "HI")])
3265 (define_insn "*zero_extendqihi2_movzbw_and"
3266 [(set (match_operand:HI 0 "register_operand" "=r,r")
3267 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3268 (clobber (reg:CC FLAGS_REG))]
3269 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3271 [(set_attr "type" "imovx,alu1")
3272 (set_attr "mode" "HI")])
3274 ; zero extend to SImode here to avoid partial register stalls
3275 (define_insn "*zero_extendqihi2_movzbl"
3276 [(set (match_operand:HI 0 "register_operand" "=r")
3277 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3279 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "SI")])
3283 ;; For the movzbw case strip only the clobber
3285 [(set (match_operand:HI 0 "register_operand" "")
3286 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3287 (clobber (reg:CC FLAGS_REG))]
3289 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3290 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3291 [(set (match_operand:HI 0 "register_operand" "")
3292 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3294 ;; When source and destination does not overlap, clear destination
3295 ;; first and then do the movb
3297 [(set (match_operand:HI 0 "register_operand" "")
3298 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3299 (clobber (reg:CC FLAGS_REG))]
3301 && ANY_QI_REG_P (operands[0])
3302 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3303 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3304 [(set (match_dup 0) (const_int 0))
3305 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3306 "operands[2] = gen_lowpart (QImode, operands[0]);")
3308 ;; Rest is handled by single and.
3310 [(set (match_operand:HI 0 "register_operand" "")
3311 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3312 (clobber (reg:CC FLAGS_REG))]
3314 && true_regnum (operands[0]) == true_regnum (operands[1])"
3315 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3316 (clobber (reg:CC FLAGS_REG))])]
3319 (define_expand "zero_extendqisi2"
3321 [(set (match_operand:SI 0 "register_operand" "")
3322 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3323 (clobber (reg:CC FLAGS_REG))])]
3327 (define_insn "*zero_extendqisi2_and"
3328 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3329 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3330 (clobber (reg:CC FLAGS_REG))]
3331 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3333 [(set_attr "type" "alu1")
3334 (set_attr "mode" "SI")])
3336 (define_insn "*zero_extendqisi2_movzbw_and"
3337 [(set (match_operand:SI 0 "register_operand" "=r,r")
3338 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3339 (clobber (reg:CC FLAGS_REG))]
3340 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3342 [(set_attr "type" "imovx,alu1")
3343 (set_attr "mode" "SI")])
3345 (define_insn "*zero_extendqisi2_movzbw"
3346 [(set (match_operand:SI 0 "register_operand" "=r")
3347 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3349 "movz{bl|x}\t{%1, %0|%0, %1}"
3350 [(set_attr "type" "imovx")
3351 (set_attr "mode" "SI")])
3353 ;; For the movzbl case strip only the clobber
3355 [(set (match_operand:SI 0 "register_operand" "")
3356 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3357 (clobber (reg:CC FLAGS_REG))]
3359 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3360 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3362 (zero_extend:SI (match_dup 1)))])
3364 ;; When source and destination does not overlap, clear destination
3365 ;; first and then do the movb
3367 [(set (match_operand:SI 0 "register_operand" "")
3368 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3369 (clobber (reg:CC FLAGS_REG))]
3371 && ANY_QI_REG_P (operands[0])
3372 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3373 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3375 [(set (match_dup 0) (const_int 0))
3376 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3377 "operands[2] = gen_lowpart (QImode, operands[0]);")
3379 ;; Rest is handled by single and.
3381 [(set (match_operand:SI 0 "register_operand" "")
3382 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3383 (clobber (reg:CC FLAGS_REG))]
3385 && true_regnum (operands[0]) == true_regnum (operands[1])"
3386 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3387 (clobber (reg:CC FLAGS_REG))])]
3390 ;; %%% Kill me once multi-word ops are sane.
3391 (define_expand "zero_extendsidi2"
3392 [(set (match_operand:DI 0 "register_operand" "=r")
3393 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3398 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3403 (define_insn "zero_extendsidi2_32"
3404 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3406 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3407 (clobber (reg:CC FLAGS_REG))]
3413 movd\t{%1, %0|%0, %1}
3414 movd\t{%1, %0|%0, %1}
3415 movd\t{%1, %0|%0, %1}
3416 movd\t{%1, %0|%0, %1}"
3417 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3418 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3420 (define_insn "zero_extendsidi2_rex64"
3421 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3423 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3426 mov\t{%k1, %k0|%k0, %k1}
3428 movd\t{%1, %0|%0, %1}
3429 movd\t{%1, %0|%0, %1}
3430 movd\t{%1, %0|%0, %1}
3431 movd\t{%1, %0|%0, %1}"
3432 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3433 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3436 [(set (match_operand:DI 0 "memory_operand" "")
3437 (zero_extend:DI (match_dup 0)))]
3439 [(set (match_dup 4) (const_int 0))]
3440 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3443 [(set (match_operand:DI 0 "register_operand" "")
3444 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3445 (clobber (reg:CC FLAGS_REG))]
3446 "!TARGET_64BIT && reload_completed
3447 && true_regnum (operands[0]) == true_regnum (operands[1])"
3448 [(set (match_dup 4) (const_int 0))]
3449 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3452 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3453 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3454 (clobber (reg:CC FLAGS_REG))]
3455 "!TARGET_64BIT && reload_completed
3456 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3457 [(set (match_dup 3) (match_dup 1))
3458 (set (match_dup 4) (const_int 0))]
3459 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3461 (define_insn "zero_extendhidi2"
3462 [(set (match_operand:DI 0 "register_operand" "=r")
3463 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3465 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3466 [(set_attr "type" "imovx")
3467 (set_attr "mode" "DI")])
3469 (define_insn "zero_extendqidi2"
3470 [(set (match_operand:DI 0 "register_operand" "=r")
3471 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3473 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3474 [(set_attr "type" "imovx")
3475 (set_attr "mode" "DI")])
3477 ;; Sign extension instructions
3479 (define_expand "extendsidi2"
3480 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3481 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3482 (clobber (reg:CC FLAGS_REG))
3483 (clobber (match_scratch:SI 2 ""))])]
3488 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3493 (define_insn "*extendsidi2_1"
3494 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496 (clobber (reg:CC FLAGS_REG))
3497 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3501 (define_insn "extendsidi2_rex64"
3502 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3503 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3507 movs{lq|x}\t{%1,%0|%0, %1}"
3508 [(set_attr "type" "imovx")
3509 (set_attr "mode" "DI")
3510 (set_attr "prefix_0f" "0")
3511 (set_attr "modrm" "0,1")])
3513 (define_insn "extendhidi2"
3514 [(set (match_operand:DI 0 "register_operand" "=r")
3515 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3517 "movs{wq|x}\t{%1,%0|%0, %1}"
3518 [(set_attr "type" "imovx")
3519 (set_attr "mode" "DI")])
3521 (define_insn "extendqidi2"
3522 [(set (match_operand:DI 0 "register_operand" "=r")
3523 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3525 "movs{bq|x}\t{%1,%0|%0, %1}"
3526 [(set_attr "type" "imovx")
3527 (set_attr "mode" "DI")])
3529 ;; Extend to memory case when source register does die.
3531 [(set (match_operand:DI 0 "memory_operand" "")
3532 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533 (clobber (reg:CC FLAGS_REG))
3534 (clobber (match_operand:SI 2 "register_operand" ""))]
3536 && dead_or_set_p (insn, operands[1])
3537 && !reg_mentioned_p (operands[1], operands[0]))"
3538 [(set (match_dup 3) (match_dup 1))
3539 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3540 (clobber (reg:CC FLAGS_REG))])
3541 (set (match_dup 4) (match_dup 1))]
3542 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3544 ;; Extend to memory case when source register does not die.
3546 [(set (match_operand:DI 0 "memory_operand" "")
3547 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3548 (clobber (reg:CC FLAGS_REG))
3549 (clobber (match_operand:SI 2 "register_operand" ""))]
3553 split_di (&operands[0], 1, &operands[3], &operands[4]);
3555 emit_move_insn (operands[3], operands[1]);
3557 /* Generate a cltd if possible and doing so it profitable. */
3558 if (true_regnum (operands[1]) == 0
3559 && true_regnum (operands[2]) == 1
3560 && (optimize_size || TARGET_USE_CLTD))
3562 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3566 emit_move_insn (operands[2], operands[1]);
3567 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3569 emit_move_insn (operands[4], operands[2]);
3573 ;; Extend to register case. Optimize case where source and destination
3574 ;; registers match and cases where we can use cltd.
3576 [(set (match_operand:DI 0 "register_operand" "")
3577 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3578 (clobber (reg:CC FLAGS_REG))
3579 (clobber (match_scratch:SI 2 ""))]
3583 split_di (&operands[0], 1, &operands[3], &operands[4]);
3585 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3586 emit_move_insn (operands[3], operands[1]);
3588 /* Generate a cltd if possible and doing so it profitable. */
3589 if (true_regnum (operands[3]) == 0
3590 && (optimize_size || TARGET_USE_CLTD))
3592 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3596 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3597 emit_move_insn (operands[4], operands[1]);
3599 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3603 (define_insn "extendhisi2"
3604 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3605 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3608 switch (get_attr_prefix_0f (insn))
3611 return "{cwtl|cwde}";
3613 return "movs{wl|x}\t{%1,%0|%0, %1}";
3616 [(set_attr "type" "imovx")
3617 (set_attr "mode" "SI")
3618 (set (attr "prefix_0f")
3619 ;; movsx is short decodable while cwtl is vector decoded.
3620 (if_then_else (and (eq_attr "cpu" "!k6")
3621 (eq_attr "alternative" "0"))
3623 (const_string "1")))
3625 (if_then_else (eq_attr "prefix_0f" "0")
3627 (const_string "1")))])
3629 (define_insn "*extendhisi2_zext"
3630 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3632 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3635 switch (get_attr_prefix_0f (insn))
3638 return "{cwtl|cwde}";
3640 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3643 [(set_attr "type" "imovx")
3644 (set_attr "mode" "SI")
3645 (set (attr "prefix_0f")
3646 ;; movsx is short decodable while cwtl is vector decoded.
3647 (if_then_else (and (eq_attr "cpu" "!k6")
3648 (eq_attr "alternative" "0"))
3650 (const_string "1")))
3652 (if_then_else (eq_attr "prefix_0f" "0")
3654 (const_string "1")))])
3656 (define_insn "extendqihi2"
3657 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3658 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3661 switch (get_attr_prefix_0f (insn))
3664 return "{cbtw|cbw}";
3666 return "movs{bw|x}\t{%1,%0|%0, %1}";
3669 [(set_attr "type" "imovx")
3670 (set_attr "mode" "HI")
3671 (set (attr "prefix_0f")
3672 ;; movsx is short decodable while cwtl is vector decoded.
3673 (if_then_else (and (eq_attr "cpu" "!k6")
3674 (eq_attr "alternative" "0"))
3676 (const_string "1")))
3678 (if_then_else (eq_attr "prefix_0f" "0")
3680 (const_string "1")))])
3682 (define_insn "extendqisi2"
3683 [(set (match_operand:SI 0 "register_operand" "=r")
3684 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3686 "movs{bl|x}\t{%1,%0|%0, %1}"
3687 [(set_attr "type" "imovx")
3688 (set_attr "mode" "SI")])
3690 (define_insn "*extendqisi2_zext"
3691 [(set (match_operand:DI 0 "register_operand" "=r")
3693 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3695 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3696 [(set_attr "type" "imovx")
3697 (set_attr "mode" "SI")])
3699 ;; Conversions between float and double.
3701 ;; These are all no-ops in the model used for the 80387. So just
3704 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3705 (define_insn "*dummy_extendsfdf2"
3706 [(set (match_operand:DF 0 "push_operand" "=<")
3707 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3712 [(set (match_operand:DF 0 "push_operand" "")
3713 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3715 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3716 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3719 [(set (match_operand:DF 0 "push_operand" "")
3720 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3722 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3723 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3725 (define_insn "*dummy_extendsfxf2"
3726 [(set (match_operand:XF 0 "push_operand" "=<")
3727 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3732 [(set (match_operand:XF 0 "push_operand" "")
3733 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3735 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3736 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3737 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3740 [(set (match_operand:XF 0 "push_operand" "")
3741 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3743 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3744 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3745 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3748 [(set (match_operand:XF 0 "push_operand" "")
3749 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3751 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3752 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3753 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3756 [(set (match_operand:XF 0 "push_operand" "")
3757 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3759 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3760 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3761 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3763 (define_expand "extendsfdf2"
3764 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3765 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3766 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3768 /* ??? Needed for compress_float_constant since all fp constants
3769 are LEGITIMATE_CONSTANT_P. */
3770 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3772 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3773 && standard_80387_constant_p (operands[1]) > 0)
3775 operands[1] = simplify_const_unary_operation
3776 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3777 emit_move_insn_1 (operands[0], operands[1]);
3780 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3784 (define_insn "*extendsfdf2_mixed"
3785 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3787 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3788 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3790 switch (which_alternative)
3793 return output_387_reg_move (insn, operands);
3796 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797 return "fstp%z0\t%y0";
3799 return "fst%z0\t%y0";
3802 return "cvtss2sd\t{%1, %0|%0, %1}";
3808 [(set_attr "type" "fmov,fmov,ssecvt")
3809 (set_attr "mode" "SF,XF,DF")])
3811 (define_insn "*extendsfdf2_sse"
3812 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3813 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3814 "TARGET_SSE2 && TARGET_SSE_MATH"
3815 "cvtss2sd\t{%1, %0|%0, %1}"
3816 [(set_attr "type" "ssecvt")
3817 (set_attr "mode" "DF")])
3819 (define_insn "*extendsfdf2_i387"
3820 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3821 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3824 switch (which_alternative)
3827 return output_387_reg_move (insn, operands);
3830 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3831 return "fstp%z0\t%y0";
3833 return "fst%z0\t%y0";
3839 [(set_attr "type" "fmov")
3840 (set_attr "mode" "SF,XF")])
3842 (define_expand "extendsfxf2"
3843 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3844 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3847 /* ??? Needed for compress_float_constant since all fp constants
3848 are LEGITIMATE_CONSTANT_P. */
3849 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3851 if (standard_80387_constant_p (operands[1]) > 0)
3853 operands[1] = simplify_const_unary_operation
3854 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3855 emit_move_insn_1 (operands[0], operands[1]);
3858 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3862 (define_insn "*extendsfxf2_i387"
3863 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3864 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3867 switch (which_alternative)
3870 return output_387_reg_move (insn, operands);
3873 /* There is no non-popping store to memory for XFmode. So if
3874 we need one, follow the store with a load. */
3875 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876 return "fstp%z0\t%y0";
3878 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3884 [(set_attr "type" "fmov")
3885 (set_attr "mode" "SF,XF")])
3887 (define_expand "extenddfxf2"
3888 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3889 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3892 /* ??? Needed for compress_float_constant since all fp constants
3893 are LEGITIMATE_CONSTANT_P. */
3894 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3896 if (standard_80387_constant_p (operands[1]) > 0)
3898 operands[1] = simplify_const_unary_operation
3899 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3900 emit_move_insn_1 (operands[0], operands[1]);
3903 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3907 (define_insn "*extenddfxf2_i387"
3908 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3909 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3912 switch (which_alternative)
3915 return output_387_reg_move (insn, operands);
3918 /* There is no non-popping store to memory for XFmode. So if
3919 we need one, follow the store with a load. */
3920 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3923 return "fstp%z0\t%y0";
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "DF,XF")])
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case. Otherwise this is just like a simple move
3935 ;; insn. So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3938 ;; Conversion from DFmode to SFmode.
3940 (define_expand "truncdfsf2"
3941 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3943 (match_operand:DF 1 "nonimmediate_operand" "")))]
3944 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3946 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3948 else if (flag_unsafe_math_optimizations)
3952 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3953 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3958 (define_expand "truncdfsf2_with_temp"
3959 [(parallel [(set (match_operand:SF 0 "" "")
3960 (float_truncate:SF (match_operand:DF 1 "" "")))
3961 (clobber (match_operand:SF 2 "" ""))])]
3964 (define_insn "*truncdfsf_fast_mixed"
3965 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3967 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3968 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3970 switch (which_alternative)
3973 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974 return "fstp%z0\t%y0";
3976 return "fst%z0\t%y0";
3978 return output_387_reg_move (insn, operands);
3980 return "cvtsd2ss\t{%1, %0|%0, %1}";
3985 [(set_attr "type" "fmov,fmov,ssecvt")
3986 (set_attr "mode" "SF")])
3988 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3989 ;; because nothing we do here is unsafe.
3990 (define_insn "*truncdfsf_fast_sse"
3991 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3993 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3994 "TARGET_SSE2 && TARGET_SSE_MATH"
3995 "cvtsd2ss\t{%1, %0|%0, %1}"
3996 [(set_attr "type" "ssecvt")
3997 (set_attr "mode" "SF")])
3999 (define_insn "*truncdfsf_fast_i387"
4000 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4002 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4003 "TARGET_80387 && flag_unsafe_math_optimizations"
4004 "* return output_387_reg_move (insn, operands);"
4005 [(set_attr "type" "fmov")
4006 (set_attr "mode" "SF")])
4008 (define_insn "*truncdfsf_mixed"
4009 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4011 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4012 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4013 "TARGET_MIX_SSE_I387"
4015 switch (which_alternative)
4018 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4019 return "fstp%z0\t%y0";
4021 return "fst%z0\t%y0";
4025 return "cvtsd2ss\t{%1, %0|%0, %1}";
4030 [(set_attr "type" "fmov,multi,ssecvt")
4031 (set_attr "unit" "*,i387,*")
4032 (set_attr "mode" "SF")])
4034 (define_insn "*truncdfsf_i387"
4035 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4037 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4038 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4041 switch (which_alternative)
4044 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045 return "fstp%z0\t%y0";
4047 return "fst%z0\t%y0";
4054 [(set_attr "type" "fmov,multi")
4055 (set_attr "unit" "*,i387")
4056 (set_attr "mode" "SF")])
4058 (define_insn "*truncdfsf2_i387_1"
4059 [(set (match_operand:SF 0 "memory_operand" "=m")
4061 (match_operand:DF 1 "register_operand" "f")))]
4063 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4064 && !TARGET_MIX_SSE_I387"
4066 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067 return "fstp%z0\t%y0";
4069 return "fst%z0\t%y0";
4071 [(set_attr "type" "fmov")
4072 (set_attr "mode" "SF")])
4075 [(set (match_operand:SF 0 "register_operand" "")
4077 (match_operand:DF 1 "fp_register_operand" "")))
4078 (clobber (match_operand 2 "" ""))]
4080 [(set (match_dup 2) (match_dup 1))
4081 (set (match_dup 0) (match_dup 2))]
4083 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4086 ;; Conversion from XFmode to SFmode.
4088 (define_expand "truncxfsf2"
4089 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4091 (match_operand:XF 1 "register_operand" "")))
4092 (clobber (match_dup 2))])]
4095 if (flag_unsafe_math_optimizations)
4097 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4098 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4099 if (reg != operands[0])
4100 emit_move_insn (operands[0], reg);
4104 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4107 (define_insn "*truncxfsf2_mixed"
4108 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4110 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4111 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4114 gcc_assert (!which_alternative);
4115 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4116 return "fstp%z0\t%y0";
4118 return "fst%z0\t%y0";
4120 [(set_attr "type" "fmov,multi,multi,multi")
4121 (set_attr "unit" "*,i387,i387,i387")
4122 (set_attr "mode" "SF")])
4124 (define_insn "truncxfsf2_i387_noop"
4125 [(set (match_operand:SF 0 "register_operand" "=f")
4126 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4127 "TARGET_80387 && flag_unsafe_math_optimizations"
4128 "* return output_387_reg_move (insn, operands);"
4129 [(set_attr "type" "fmov")
4130 (set_attr "mode" "SF")])
4132 (define_insn "*truncxfsf2_i387"
4133 [(set (match_operand:SF 0 "memory_operand" "=m")
4135 (match_operand:XF 1 "register_operand" "f")))]
4138 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139 return "fstp%z0\t%y0";
4141 return "fst%z0\t%y0";
4143 [(set_attr "type" "fmov")
4144 (set_attr "mode" "SF")])
4147 [(set (match_operand:SF 0 "register_operand" "")
4149 (match_operand:XF 1 "register_operand" "")))
4150 (clobber (match_operand:SF 2 "memory_operand" ""))]
4151 "TARGET_80387 && reload_completed"
4152 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4153 (set (match_dup 0) (match_dup 2))]
4157 [(set (match_operand:SF 0 "memory_operand" "")
4159 (match_operand:XF 1 "register_operand" "")))
4160 (clobber (match_operand:SF 2 "memory_operand" ""))]
4162 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4165 ;; Conversion from XFmode to DFmode.
4167 (define_expand "truncxfdf2"
4168 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4170 (match_operand:XF 1 "register_operand" "")))
4171 (clobber (match_dup 2))])]
4174 if (flag_unsafe_math_optimizations)
4176 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4177 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4178 if (reg != operands[0])
4179 emit_move_insn (operands[0], reg);
4183 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4186 (define_insn "*truncxfdf2_mixed"
4187 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4189 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4190 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4193 gcc_assert (!which_alternative);
4194 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4195 return "fstp%z0\t%y0";
4197 return "fst%z0\t%y0";
4199 [(set_attr "type" "fmov,multi,multi,multi")
4200 (set_attr "unit" "*,i387,i387,i387")
4201 (set_attr "mode" "DF")])
4203 (define_insn "truncxfdf2_i387_noop"
4204 [(set (match_operand:DF 0 "register_operand" "=f")
4205 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4206 "TARGET_80387 && flag_unsafe_math_optimizations"
4207 "* return output_387_reg_move (insn, operands);"
4208 [(set_attr "type" "fmov")
4209 (set_attr "mode" "DF")])
4211 (define_insn "*truncxfdf2_i387"
4212 [(set (match_operand:DF 0 "memory_operand" "=m")
4214 (match_operand:XF 1 "register_operand" "f")))]
4217 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4218 return "fstp%z0\t%y0";
4220 return "fst%z0\t%y0";
4222 [(set_attr "type" "fmov")
4223 (set_attr "mode" "DF")])
4226 [(set (match_operand:DF 0 "register_operand" "")
4228 (match_operand:XF 1 "register_operand" "")))
4229 (clobber (match_operand:DF 2 "memory_operand" ""))]
4230 "TARGET_80387 && reload_completed"
4231 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4232 (set (match_dup 0) (match_dup 2))]
4236 [(set (match_operand:DF 0 "memory_operand" "")
4238 (match_operand:XF 1 "register_operand" "")))
4239 (clobber (match_operand:DF 2 "memory_operand" ""))]
4241 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4244 ;; Signed conversion to DImode.
4246 (define_expand "fix_truncxfdi2"
4247 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248 (fix:DI (match_operand:XF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4254 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4259 (define_expand "fix_trunc<mode>di2"
4260 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4262 (clobber (reg:CC FLAGS_REG))])]
4263 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4266 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4268 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4271 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4273 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275 if (out != operands[0])
4276 emit_move_insn (operands[0], out);
4281 ;; Signed conversion to SImode.
4283 (define_expand "fix_truncxfsi2"
4284 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285 (fix:SI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4291 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4296 (define_expand "fix_trunc<mode>si2"
4297 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4303 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4305 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4308 if (SSE_FLOAT_MODE_P (<MODE>mode))
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4318 ;; Signed conversion to HImode.
4320 (define_expand "fix_trunc<mode>hi2"
4321 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4329 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4334 ;; Unsigned conversion to SImode.
4336 (define_expand "fixuns_trunc<mode>si2"
4337 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4338 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))]
4339 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4340 && TARGET_KEEPS_VECTOR_ALIGNED_STACK && !optimize_size"
4342 ix86_expand_convert_uns_si_sse (operands[0], operands[1]);
4346 ;; Unsigned conversion to HImode.
4347 ;; Without these patterns, we'll try the unsigned SI conversion which
4348 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4350 (define_expand "fixuns_truncsfhi2"
4352 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4353 (set (match_operand:HI 0 "nonimmediate_operand" "")
4354 (subreg:HI (match_dup 2) 0))]
4356 "operands[2] = gen_reg_rtx (SImode);")
4358 (define_expand "fixuns_truncdfhi2"
4360 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4361 (set (match_operand:HI 0 "nonimmediate_operand" "")
4362 (subreg:HI (match_dup 2) 0))]
4364 "operands[2] = gen_reg_rtx (SImode);")
4366 ;; When SSE is available, it is always faster to use it!
4367 (define_insn "fix_truncsfdi_sse"
4368 [(set (match_operand:DI 0 "register_operand" "=r,r")
4369 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4370 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4371 "cvttss2si{q}\t{%1, %0|%0, %1}"
4372 [(set_attr "type" "sseicvt")
4373 (set_attr "mode" "SF")
4374 (set_attr "athlon_decode" "double,vector")
4375 (set_attr "amdfam10_decode" "double,double")])
4377 (define_insn "fix_truncdfdi_sse"
4378 [(set (match_operand:DI 0 "register_operand" "=r,r")
4379 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4380 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4381 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4382 [(set_attr "type" "sseicvt")
4383 (set_attr "mode" "DF")
4384 (set_attr "athlon_decode" "double,vector")
4385 (set_attr "amdfam10_decode" "double,double")])
4387 (define_insn "fix_truncsfsi_sse"
4388 [(set (match_operand:SI 0 "register_operand" "=r,r")
4389 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4390 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4391 "cvttss2si\t{%1, %0|%0, %1}"
4392 [(set_attr "type" "sseicvt")
4393 (set_attr "mode" "DF")
4394 (set_attr "athlon_decode" "double,vector")
4395 (set_attr "amdfam10_decode" "double,double")])
4397 (define_insn "fix_truncdfsi_sse"
4398 [(set (match_operand:SI 0 "register_operand" "=r,r")
4399 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4400 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4401 "cvttsd2si\t{%1, %0|%0, %1}"
4402 [(set_attr "type" "sseicvt")
4403 (set_attr "mode" "DF")
4404 (set_attr "athlon_decode" "double,vector")
4405 (set_attr "amdfam10_decode" "double,double")])
4407 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4409 [(set (match_operand:DF 0 "register_operand" "")
4410 (match_operand:DF 1 "memory_operand" ""))
4411 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4412 (fix:SSEMODEI24 (match_dup 0)))]
4414 && peep2_reg_dead_p (2, operands[0])"
4415 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4419 [(set (match_operand:SF 0 "register_operand" "")
4420 (match_operand:SF 1 "memory_operand" ""))
4421 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422 (fix:SSEMODEI24 (match_dup 0)))]
4424 && peep2_reg_dead_p (2, operands[0])"
4425 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4428 ;; Avoid vector decoded forms of the instruction.
4430 [(match_scratch:DF 2 "Y")
4431 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4434 [(set (match_dup 2) (match_dup 1))
4435 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4439 [(match_scratch:SF 2 "x")
4440 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4441 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4442 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4443 [(set (match_dup 2) (match_dup 1))
4444 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4447 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4448 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4449 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4451 && FLOAT_MODE_P (GET_MODE (operands[1]))
4452 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4453 && (TARGET_64BIT || <MODE>mode != DImode))
4455 && !(reload_completed || reload_in_progress)"
4460 if (memory_operand (operands[0], VOIDmode))
4461 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4464 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4465 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4471 [(set_attr "type" "fisttp")
4472 (set_attr "mode" "<MODE>")])
4474 (define_insn "fix_trunc<mode>_i387_fisttp"
4475 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4476 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4477 (clobber (match_scratch:XF 2 "=&1f"))]
4479 && FLOAT_MODE_P (GET_MODE (operands[1]))
4480 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4481 && (TARGET_64BIT || <MODE>mode != DImode))
4482 && TARGET_SSE_MATH)"
4483 "* return output_fix_trunc (insn, operands, 1);"
4484 [(set_attr "type" "fisttp")
4485 (set_attr "mode" "<MODE>")])
4487 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4488 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4489 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4490 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4491 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4493 && FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && (TARGET_64BIT || <MODE>mode != DImode))
4496 && TARGET_SSE_MATH)"
4498 [(set_attr "type" "fisttp")
4499 (set_attr "mode" "<MODE>")])
4502 [(set (match_operand:X87MODEI 0 "register_operand" "")
4503 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4504 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4505 (clobber (match_scratch 3 ""))]
4507 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4508 (clobber (match_dup 3))])
4509 (set (match_dup 0) (match_dup 2))]
4513 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4514 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4515 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4516 (clobber (match_scratch 3 ""))]
4518 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4519 (clobber (match_dup 3))])]
4522 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4523 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4524 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4525 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4526 ;; function in i386.c.
4527 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4528 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4529 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4530 (clobber (reg:CC FLAGS_REG))]
4531 "TARGET_80387 && !TARGET_FISTTP
4532 && FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && (TARGET_64BIT || <MODE>mode != DImode))
4535 && !(reload_completed || reload_in_progress)"
4540 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4542 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4543 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4544 if (memory_operand (operands[0], VOIDmode))
4545 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4546 operands[2], operands[3]));
4549 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4550 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4551 operands[2], operands[3],
4556 [(set_attr "type" "fistp")
4557 (set_attr "i387_cw" "trunc")
4558 (set_attr "mode" "<MODE>")])
4560 (define_insn "fix_truncdi_i387"
4561 [(set (match_operand:DI 0 "memory_operand" "=m")
4562 (fix:DI (match_operand 1 "register_operand" "f")))
4563 (use (match_operand:HI 2 "memory_operand" "m"))
4564 (use (match_operand:HI 3 "memory_operand" "m"))
4565 (clobber (match_scratch:XF 4 "=&1f"))]
4566 "TARGET_80387 && !TARGET_FISTTP
4567 && FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4569 "* return output_fix_trunc (insn, operands, 0);"
4570 [(set_attr "type" "fistp")
4571 (set_attr "i387_cw" "trunc")
4572 (set_attr "mode" "DI")])
4574 (define_insn "fix_truncdi_i387_with_temp"
4575 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4576 (fix:DI (match_operand 1 "register_operand" "f,f")))
4577 (use (match_operand:HI 2 "memory_operand" "m,m"))
4578 (use (match_operand:HI 3 "memory_operand" "m,m"))
4579 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4580 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4581 "TARGET_80387 && !TARGET_FISTTP
4582 && FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4585 [(set_attr "type" "fistp")
4586 (set_attr "i387_cw" "trunc")
4587 (set_attr "mode" "DI")])
4590 [(set (match_operand:DI 0 "register_operand" "")
4591 (fix:DI (match_operand 1 "register_operand" "")))
4592 (use (match_operand:HI 2 "memory_operand" ""))
4593 (use (match_operand:HI 3 "memory_operand" ""))
4594 (clobber (match_operand:DI 4 "memory_operand" ""))
4595 (clobber (match_scratch 5 ""))]
4597 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4600 (clobber (match_dup 5))])
4601 (set (match_dup 0) (match_dup 4))]
4605 [(set (match_operand:DI 0 "memory_operand" "")
4606 (fix:DI (match_operand 1 "register_operand" "")))
4607 (use (match_operand:HI 2 "memory_operand" ""))
4608 (use (match_operand:HI 3 "memory_operand" ""))
4609 (clobber (match_operand:DI 4 "memory_operand" ""))
4610 (clobber (match_scratch 5 ""))]
4612 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4615 (clobber (match_dup 5))])]
4618 (define_insn "fix_trunc<mode>_i387"
4619 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4620 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4621 (use (match_operand:HI 2 "memory_operand" "m"))
4622 (use (match_operand:HI 3 "memory_operand" "m"))]
4623 "TARGET_80387 && !TARGET_FISTTP
4624 && FLOAT_MODE_P (GET_MODE (operands[1]))
4625 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4626 "* return output_fix_trunc (insn, operands, 0);"
4627 [(set_attr "type" "fistp")
4628 (set_attr "i387_cw" "trunc")
4629 (set_attr "mode" "<MODE>")])
4631 (define_insn "fix_trunc<mode>_i387_with_temp"
4632 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4633 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4634 (use (match_operand:HI 2 "memory_operand" "m,m"))
4635 (use (match_operand:HI 3 "memory_operand" "m,m"))
4636 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4637 "TARGET_80387 && !TARGET_FISTTP
4638 && FLOAT_MODE_P (GET_MODE (operands[1]))
4639 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4641 [(set_attr "type" "fistp")
4642 (set_attr "i387_cw" "trunc")
4643 (set_attr "mode" "<MODE>")])
4646 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4647 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4648 (use (match_operand:HI 2 "memory_operand" ""))
4649 (use (match_operand:HI 3 "memory_operand" ""))
4650 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4652 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4654 (use (match_dup 3))])
4655 (set (match_dup 0) (match_dup 4))]
4659 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4660 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4661 (use (match_operand:HI 2 "memory_operand" ""))
4662 (use (match_operand:HI 3 "memory_operand" ""))
4663 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4665 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4667 (use (match_dup 3))])]
4670 (define_insn "x86_fnstcw_1"
4671 [(set (match_operand:HI 0 "memory_operand" "=m")
4672 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4675 [(set_attr "length" "2")
4676 (set_attr "mode" "HI")
4677 (set_attr "unit" "i387")])
4679 (define_insn "x86_fldcw_1"
4680 [(set (reg:HI FPCR_REG)
4681 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4684 [(set_attr "length" "2")
4685 (set_attr "mode" "HI")
4686 (set_attr "unit" "i387")
4687 (set_attr "athlon_decode" "vector")
4688 (set_attr "amdfam10_decode" "vector")])
4690 ;; Conversion between fixed point and floating point.
4692 ;; Even though we only accept memory inputs, the backend _really_
4693 ;; wants to be able to do this between registers.
4695 (define_expand "floathisf2"
4696 [(set (match_operand:SF 0 "register_operand" "")
4697 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4698 "TARGET_80387 || TARGET_SSE_MATH"
4700 if (TARGET_SSE_MATH)
4702 emit_insn (gen_floatsisf2 (operands[0],
4703 convert_to_mode (SImode, operands[1], 0)));
4708 (define_insn "*floathisf2_i387"
4709 [(set (match_operand:SF 0 "register_operand" "=f,f")
4710 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4711 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4715 [(set_attr "type" "fmov,multi")
4716 (set_attr "mode" "SF")
4717 (set_attr "unit" "*,i387")
4718 (set_attr "fp_int_src" "true")])
4720 (define_expand "floatsisf2"
4721 [(set (match_operand:SF 0 "register_operand" "")
4722 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4723 "TARGET_80387 || TARGET_SSE_MATH"
4726 (define_insn "*floatsisf2_mixed"
4727 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4728 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4729 "TARGET_MIX_SSE_I387"
4733 cvtsi2ss\t{%1, %0|%0, %1}
4734 cvtsi2ss\t{%1, %0|%0, %1}"
4735 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4736 (set_attr "mode" "SF")
4737 (set_attr "unit" "*,i387,*,*")
4738 (set_attr "athlon_decode" "*,*,vector,double")
4739 (set_attr "amdfam10_decode" "*,*,vector,double")
4740 (set_attr "fp_int_src" "true")])
4742 (define_insn "*floatsisf2_sse"
4743 [(set (match_operand:SF 0 "register_operand" "=x,x")
4744 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4746 "cvtsi2ss\t{%1, %0|%0, %1}"
4747 [(set_attr "type" "sseicvt")
4748 (set_attr "mode" "SF")
4749 (set_attr "athlon_decode" "vector,double")
4750 (set_attr "amdfam10_decode" "vector,double")
4751 (set_attr "fp_int_src" "true")])
4753 (define_insn "*floatsisf2_i387"
4754 [(set (match_operand:SF 0 "register_operand" "=f,f")
4755 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4760 [(set_attr "type" "fmov,multi")
4761 (set_attr "mode" "SF")
4762 (set_attr "unit" "*,i387")
4763 (set_attr "fp_int_src" "true")])
4765 (define_expand "floatdisf2"
4766 [(set (match_operand:SF 0 "register_operand" "")
4767 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4768 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4771 (define_insn "*floatdisf2_mixed"
4772 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4773 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4774 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4778 cvtsi2ss{q}\t{%1, %0|%0, %1}
4779 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4780 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4781 (set_attr "mode" "SF")
4782 (set_attr "unit" "*,i387,*,*")
4783 (set_attr "athlon_decode" "*,*,vector,double")
4784 (set_attr "amdfam10_decode" "*,*,vector,double")
4785 (set_attr "fp_int_src" "true")])
4787 (define_insn "*floatdisf2_sse"
4788 [(set (match_operand:SF 0 "register_operand" "=x,x")
4789 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4790 "TARGET_64BIT && TARGET_SSE_MATH"
4791 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4792 [(set_attr "type" "sseicvt")
4793 (set_attr "mode" "SF")
4794 (set_attr "athlon_decode" "vector,double")
4795 (set_attr "amdfam10_decode" "vector,double")
4796 (set_attr "fp_int_src" "true")])
4798 (define_insn "*floatdisf2_i387"
4799 [(set (match_operand:SF 0 "register_operand" "=f,f")
4800 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4805 [(set_attr "type" "fmov,multi")
4806 (set_attr "mode" "SF")
4807 (set_attr "unit" "*,i387")
4808 (set_attr "fp_int_src" "true")])
4810 (define_expand "floathidf2"
4811 [(set (match_operand:DF 0 "register_operand" "")
4812 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4813 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4815 if (TARGET_SSE2 && TARGET_SSE_MATH)
4817 emit_insn (gen_floatsidf2 (operands[0],
4818 convert_to_mode (SImode, operands[1], 0)));
4823 (define_insn "*floathidf2_i387"
4824 [(set (match_operand:DF 0 "register_operand" "=f,f")
4825 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4826 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4830 [(set_attr "type" "fmov,multi")
4831 (set_attr "mode" "DF")
4832 (set_attr "unit" "*,i387")
4833 (set_attr "fp_int_src" "true")])
4835 (define_expand "floatsidf2"
4836 [(set (match_operand:DF 0 "register_operand" "")
4837 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4838 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4841 (define_insn "*floatsidf2_mixed"
4842 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4843 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4844 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4848 cvtsi2sd\t{%1, %0|%0, %1}
4849 cvtsi2sd\t{%1, %0|%0, %1}"
4850 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4851 (set_attr "mode" "DF")
4852 (set_attr "unit" "*,i387,*,*")
4853 (set_attr "athlon_decode" "*,*,double,direct")
4854 (set_attr "amdfam10_decode" "*,*,vector,double")
4855 (set_attr "fp_int_src" "true")])
4857 (define_insn "*floatsidf2_sse"
4858 [(set (match_operand:DF 0 "register_operand" "=x,x")
4859 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4860 "TARGET_SSE2 && TARGET_SSE_MATH"
4861 "cvtsi2sd\t{%1, %0|%0, %1}"
4862 [(set_attr "type" "sseicvt")
4863 (set_attr "mode" "DF")
4864 (set_attr "athlon_decode" "double,direct")
4865 (set_attr "amdfam10_decode" "vector,double")
4866 (set_attr "fp_int_src" "true")])
4868 (define_insn "*floatsidf2_i387"
4869 [(set (match_operand:DF 0 "register_operand" "=f,f")
4870 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4875 [(set_attr "type" "fmov,multi")
4876 (set_attr "mode" "DF")
4877 (set_attr "unit" "*,i387")
4878 (set_attr "fp_int_src" "true")])
4880 (define_expand "floatdidf2"
4881 [(set (match_operand:DF 0 "register_operand" "")
4882 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4883 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4885 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4887 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4892 (define_insn "*floatdidf2_mixed"
4893 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4894 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4895 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4899 cvtsi2sd{q}\t{%1, %0|%0, %1}
4900 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4901 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4902 (set_attr "mode" "DF")
4903 (set_attr "unit" "*,i387,*,*")
4904 (set_attr "athlon_decode" "*,*,double,direct")
4905 (set_attr "amdfam10_decode" "*,*,vector,double")
4906 (set_attr "fp_int_src" "true")])
4908 (define_insn "*floatdidf2_sse"
4909 [(set (match_operand:DF 0 "register_operand" "=x,x")
4910 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4911 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4912 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4913 [(set_attr "type" "sseicvt")
4914 (set_attr "mode" "DF")
4915 (set_attr "athlon_decode" "double,direct")
4916 (set_attr "amdfam10_decode" "vector,double")
4917 (set_attr "fp_int_src" "true")])
4919 (define_insn "*floatdidf2_i387"
4920 [(set (match_operand:DF 0 "register_operand" "=f,f")
4921 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4926 [(set_attr "type" "fmov,multi")
4927 (set_attr "mode" "DF")
4928 (set_attr "unit" "*,i387")
4929 (set_attr "fp_int_src" "true")])
4931 (define_insn "floathixf2"
4932 [(set (match_operand:XF 0 "register_operand" "=f,f")
4933 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4938 [(set_attr "type" "fmov,multi")
4939 (set_attr "mode" "XF")
4940 (set_attr "unit" "*,i387")
4941 (set_attr "fp_int_src" "true")])
4943 (define_insn "floatsixf2"
4944 [(set (match_operand:XF 0 "register_operand" "=f,f")
4945 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4950 [(set_attr "type" "fmov,multi")
4951 (set_attr "mode" "XF")
4952 (set_attr "unit" "*,i387")
4953 (set_attr "fp_int_src" "true")])
4955 (define_insn "floatdixf2"
4956 [(set (match_operand:XF 0 "register_operand" "=f,f")
4957 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4962 [(set_attr "type" "fmov,multi")
4963 (set_attr "mode" "XF")
4964 (set_attr "unit" "*,i387")
4965 (set_attr "fp_int_src" "true")])
4967 ;; %%% Kill these when reload knows how to do it.
4969 [(set (match_operand 0 "fp_register_operand" "")
4970 (float (match_operand 1 "register_operand" "")))]
4973 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4976 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4977 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4978 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4979 ix86_free_from_memory (GET_MODE (operands[1]));
4983 (define_expand "floatunssisf2"
4984 [(use (match_operand:SF 0 "register_operand" ""))
4985 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4988 if (TARGET_SSE_MATH && TARGET_SSE2)
4989 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4991 x86_emit_floatuns (operands);
4995 (define_expand "floatunssidf2"
4996 [(use (match_operand:DF 0 "register_operand" ""))
4997 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4998 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4999 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5001 (define_expand "floatunsdisf2"
5002 [(use (match_operand:SF 0 "register_operand" ""))
5003 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5004 "TARGET_64BIT && TARGET_SSE_MATH"
5005 "x86_emit_floatuns (operands); DONE;")
5007 (define_expand "floatunsdidf2"
5008 [(use (match_operand:DF 0 "register_operand" ""))
5009 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5010 "TARGET_SSE_MATH && TARGET_SSE2
5011 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5014 x86_emit_floatuns (operands);
5016 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5020 ;; SSE extract/set expanders
5025 ;; %%% splits for addditi3
5027 (define_expand "addti3"
5028 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5029 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5030 (match_operand:TI 2 "x86_64_general_operand" "")))
5031 (clobber (reg:CC FLAGS_REG))]
5033 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5035 (define_insn "*addti3_1"
5036 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5037 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5038 (match_operand:TI 2 "general_operand" "roiF,riF")))
5039 (clobber (reg:CC FLAGS_REG))]
5040 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5044 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5045 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5046 (match_operand:TI 2 "general_operand" "")))
5047 (clobber (reg:CC FLAGS_REG))]
5048 "TARGET_64BIT && reload_completed"
5049 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5051 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5052 (parallel [(set (match_dup 3)
5053 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5056 (clobber (reg:CC FLAGS_REG))])]
5057 "split_ti (operands+0, 1, operands+0, operands+3);
5058 split_ti (operands+1, 1, operands+1, operands+4);
5059 split_ti (operands+2, 1, operands+2, operands+5);")
5061 ;; %%% splits for addsidi3
5062 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5063 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5064 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5066 (define_expand "adddi3"
5067 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5068 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5069 (match_operand:DI 2 "x86_64_general_operand" "")))
5070 (clobber (reg:CC FLAGS_REG))]
5072 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5074 (define_insn "*adddi3_1"
5075 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5076 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5077 (match_operand:DI 2 "general_operand" "roiF,riF")))
5078 (clobber (reg:CC FLAGS_REG))]
5079 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5083 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5084 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5085 (match_operand:DI 2 "general_operand" "")))
5086 (clobber (reg:CC FLAGS_REG))]
5087 "!TARGET_64BIT && reload_completed"
5088 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5090 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5091 (parallel [(set (match_dup 3)
5092 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5095 (clobber (reg:CC FLAGS_REG))])]
5096 "split_di (operands+0, 1, operands+0, operands+3);
5097 split_di (operands+1, 1, operands+1, operands+4);
5098 split_di (operands+2, 1, operands+2, operands+5);")
5100 (define_insn "adddi3_carry_rex64"
5101 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5102 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5103 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5104 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5105 (clobber (reg:CC FLAGS_REG))]
5106 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5107 "adc{q}\t{%2, %0|%0, %2}"
5108 [(set_attr "type" "alu")
5109 (set_attr "pent_pair" "pu")
5110 (set_attr "mode" "DI")])
5112 (define_insn "*adddi3_cc_rex64"
5113 [(set (reg:CC FLAGS_REG)
5114 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5115 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5117 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5118 (plus:DI (match_dup 1) (match_dup 2)))]
5119 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120 "add{q}\t{%2, %0|%0, %2}"
5121 [(set_attr "type" "alu")
5122 (set_attr "mode" "DI")])
5124 (define_insn "addqi3_carry"
5125 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5126 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5127 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5128 (match_operand:QI 2 "general_operand" "qi,qm")))
5129 (clobber (reg:CC FLAGS_REG))]
5130 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5131 "adc{b}\t{%2, %0|%0, %2}"
5132 [(set_attr "type" "alu")
5133 (set_attr "pent_pair" "pu")
5134 (set_attr "mode" "QI")])
5136 (define_insn "addhi3_carry"
5137 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5138 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5139 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5140 (match_operand:HI 2 "general_operand" "ri,rm")))
5141 (clobber (reg:CC FLAGS_REG))]
5142 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5143 "adc{w}\t{%2, %0|%0, %2}"
5144 [(set_attr "type" "alu")
5145 (set_attr "pent_pair" "pu")
5146 (set_attr "mode" "HI")])
5148 (define_insn "addsi3_carry"
5149 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5150 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5151 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5152 (match_operand:SI 2 "general_operand" "ri,rm")))
5153 (clobber (reg:CC FLAGS_REG))]
5154 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5155 "adc{l}\t{%2, %0|%0, %2}"
5156 [(set_attr "type" "alu")
5157 (set_attr "pent_pair" "pu")
5158 (set_attr "mode" "SI")])
5160 (define_insn "*addsi3_carry_zext"
5161 [(set (match_operand:DI 0 "register_operand" "=r")
5163 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5164 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5165 (match_operand:SI 2 "general_operand" "rim"))))
5166 (clobber (reg:CC FLAGS_REG))]
5167 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5168 "adc{l}\t{%2, %k0|%k0, %2}"
5169 [(set_attr "type" "alu")
5170 (set_attr "pent_pair" "pu")
5171 (set_attr "mode" "SI")])
5173 (define_insn "*addsi3_cc"
5174 [(set (reg:CC FLAGS_REG)
5175 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5176 (match_operand:SI 2 "general_operand" "ri,rm")]
5178 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5179 (plus:SI (match_dup 1) (match_dup 2)))]
5180 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5181 "add{l}\t{%2, %0|%0, %2}"
5182 [(set_attr "type" "alu")
5183 (set_attr "mode" "SI")])
5185 (define_insn "addqi3_cc"
5186 [(set (reg:CC FLAGS_REG)
5187 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5188 (match_operand:QI 2 "general_operand" "qi,qm")]
5190 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5191 (plus:QI (match_dup 1) (match_dup 2)))]
5192 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5193 "add{b}\t{%2, %0|%0, %2}"
5194 [(set_attr "type" "alu")
5195 (set_attr "mode" "QI")])
5197 (define_expand "addsi3"
5198 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5199 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5200 (match_operand:SI 2 "general_operand" "")))
5201 (clobber (reg:CC FLAGS_REG))])]
5203 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5205 (define_insn "*lea_1"
5206 [(set (match_operand:SI 0 "register_operand" "=r")
5207 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5209 "lea{l}\t{%a1, %0|%0, %a1}"
5210 [(set_attr "type" "lea")
5211 (set_attr "mode" "SI")])
5213 (define_insn "*lea_1_rex64"
5214 [(set (match_operand:SI 0 "register_operand" "=r")
5215 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5217 "lea{l}\t{%a1, %0|%0, %a1}"
5218 [(set_attr "type" "lea")
5219 (set_attr "mode" "SI")])
5221 (define_insn "*lea_1_zext"
5222 [(set (match_operand:DI 0 "register_operand" "=r")
5224 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5226 "lea{l}\t{%a1, %k0|%k0, %a1}"
5227 [(set_attr "type" "lea")
5228 (set_attr "mode" "SI")])
5230 (define_insn "*lea_2_rex64"
5231 [(set (match_operand:DI 0 "register_operand" "=r")
5232 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5234 "lea{q}\t{%a1, %0|%0, %a1}"
5235 [(set_attr "type" "lea")
5236 (set_attr "mode" "DI")])
5238 ;; The lea patterns for non-Pmodes needs to be matched by several
5239 ;; insns converted to real lea by splitters.
5241 (define_insn_and_split "*lea_general_1"
5242 [(set (match_operand 0 "register_operand" "=r")
5243 (plus (plus (match_operand 1 "index_register_operand" "l")
5244 (match_operand 2 "register_operand" "r"))
5245 (match_operand 3 "immediate_operand" "i")))]
5246 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5247 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5248 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5249 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5250 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5251 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5252 || GET_MODE (operands[3]) == VOIDmode)"
5254 "&& reload_completed"
5258 operands[0] = gen_lowpart (SImode, operands[0]);
5259 operands[1] = gen_lowpart (Pmode, operands[1]);
5260 operands[2] = gen_lowpart (Pmode, operands[2]);
5261 operands[3] = gen_lowpart (Pmode, operands[3]);
5262 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5264 if (Pmode != SImode)
5265 pat = gen_rtx_SUBREG (SImode, pat, 0);
5266 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5269 [(set_attr "type" "lea")
5270 (set_attr "mode" "SI")])
5272 (define_insn_and_split "*lea_general_1_zext"
5273 [(set (match_operand:DI 0 "register_operand" "=r")
5275 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5276 (match_operand:SI 2 "register_operand" "r"))
5277 (match_operand:SI 3 "immediate_operand" "i"))))]
5280 "&& reload_completed"
5282 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5284 (match_dup 3)) 0)))]
5286 operands[1] = gen_lowpart (Pmode, operands[1]);
5287 operands[2] = gen_lowpart (Pmode, operands[2]);
5288 operands[3] = gen_lowpart (Pmode, operands[3]);
5290 [(set_attr "type" "lea")
5291 (set_attr "mode" "SI")])
5293 (define_insn_and_split "*lea_general_2"
5294 [(set (match_operand 0 "register_operand" "=r")
5295 (plus (mult (match_operand 1 "index_register_operand" "l")
5296 (match_operand 2 "const248_operand" "i"))
5297 (match_operand 3 "nonmemory_operand" "ri")))]
5298 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5299 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5300 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5301 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5302 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5303 || GET_MODE (operands[3]) == VOIDmode)"
5305 "&& reload_completed"
5309 operands[0] = gen_lowpart (SImode, operands[0]);
5310 operands[1] = gen_lowpart (Pmode, operands[1]);
5311 operands[3] = gen_lowpart (Pmode, operands[3]);
5312 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5314 if (Pmode != SImode)
5315 pat = gen_rtx_SUBREG (SImode, pat, 0);
5316 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5319 [(set_attr "type" "lea")
5320 (set_attr "mode" "SI")])
5322 (define_insn_and_split "*lea_general_2_zext"
5323 [(set (match_operand:DI 0 "register_operand" "=r")
5325 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5326 (match_operand:SI 2 "const248_operand" "n"))
5327 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5330 "&& reload_completed"
5332 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5334 (match_dup 3)) 0)))]
5336 operands[1] = gen_lowpart (Pmode, operands[1]);
5337 operands[3] = gen_lowpart (Pmode, operands[3]);
5339 [(set_attr "type" "lea")
5340 (set_attr "mode" "SI")])
5342 (define_insn_and_split "*lea_general_3"
5343 [(set (match_operand 0 "register_operand" "=r")
5344 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5345 (match_operand 2 "const248_operand" "i"))
5346 (match_operand 3 "register_operand" "r"))
5347 (match_operand 4 "immediate_operand" "i")))]
5348 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5349 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5350 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5351 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5352 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5354 "&& reload_completed"
5358 operands[0] = gen_lowpart (SImode, operands[0]);
5359 operands[1] = gen_lowpart (Pmode, operands[1]);
5360 operands[3] = gen_lowpart (Pmode, operands[3]);
5361 operands[4] = gen_lowpart (Pmode, operands[4]);
5362 pat = gen_rtx_PLUS (Pmode,
5363 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5367 if (Pmode != SImode)
5368 pat = gen_rtx_SUBREG (SImode, pat, 0);
5369 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5372 [(set_attr "type" "lea")
5373 (set_attr "mode" "SI")])
5375 (define_insn_and_split "*lea_general_3_zext"
5376 [(set (match_operand:DI 0 "register_operand" "=r")
5378 (plus:SI (plus:SI (mult:SI
5379 (match_operand:SI 1 "index_register_operand" "l")
5380 (match_operand:SI 2 "const248_operand" "n"))
5381 (match_operand:SI 3 "register_operand" "r"))
5382 (match_operand:SI 4 "immediate_operand" "i"))))]
5385 "&& reload_completed"
5387 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5390 (match_dup 4)) 0)))]
5392 operands[1] = gen_lowpart (Pmode, operands[1]);
5393 operands[3] = gen_lowpart (Pmode, operands[3]);
5394 operands[4] = gen_lowpart (Pmode, operands[4]);
5396 [(set_attr "type" "lea")
5397 (set_attr "mode" "SI")])
5399 (define_insn "*adddi_1_rex64"
5400 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5401 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5402 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5403 (clobber (reg:CC FLAGS_REG))]
5404 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5406 switch (get_attr_type (insn))
5409 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5410 return "lea{q}\t{%a2, %0|%0, %a2}";
5413 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5414 if (operands[2] == const1_rtx)
5415 return "inc{q}\t%0";
5418 gcc_assert (operands[2] == constm1_rtx);
5419 return "dec{q}\t%0";
5423 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5425 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5426 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5427 if (CONST_INT_P (operands[2])
5428 /* Avoid overflows. */
5429 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5430 && (INTVAL (operands[2]) == 128
5431 || (INTVAL (operands[2]) < 0
5432 && INTVAL (operands[2]) != -128)))
5434 operands[2] = GEN_INT (-INTVAL (operands[2]));
5435 return "sub{q}\t{%2, %0|%0, %2}";
5437 return "add{q}\t{%2, %0|%0, %2}";
5441 (cond [(eq_attr "alternative" "2")
5442 (const_string "lea")
5443 ; Current assemblers are broken and do not allow @GOTOFF in
5444 ; ought but a memory context.
5445 (match_operand:DI 2 "pic_symbolic_operand" "")
5446 (const_string "lea")
5447 (match_operand:DI 2 "incdec_operand" "")
5448 (const_string "incdec")
5450 (const_string "alu")))
5451 (set_attr "mode" "DI")])
5453 ;; Convert lea to the lea pattern to avoid flags dependency.
5455 [(set (match_operand:DI 0 "register_operand" "")
5456 (plus:DI (match_operand:DI 1 "register_operand" "")
5457 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5458 (clobber (reg:CC FLAGS_REG))]
5459 "TARGET_64BIT && reload_completed
5460 && true_regnum (operands[0]) != true_regnum (operands[1])"
5462 (plus:DI (match_dup 1)
5466 (define_insn "*adddi_2_rex64"
5467 [(set (reg FLAGS_REG)
5469 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5470 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5472 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5473 (plus:DI (match_dup 1) (match_dup 2)))]
5474 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5475 && ix86_binary_operator_ok (PLUS, DImode, operands)
5476 /* Current assemblers are broken and do not allow @GOTOFF in
5477 ought but a memory context. */
5478 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5480 switch (get_attr_type (insn))
5483 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5484 if (operands[2] == const1_rtx)
5485 return "inc{q}\t%0";
5488 gcc_assert (operands[2] == constm1_rtx);
5489 return "dec{q}\t%0";
5493 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5494 /* ???? We ought to handle there the 32bit case too
5495 - do we need new constraint? */
5496 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5497 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5498 if (CONST_INT_P (operands[2])
5499 /* Avoid overflows. */
5500 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5501 && (INTVAL (operands[2]) == 128
5502 || (INTVAL (operands[2]) < 0
5503 && INTVAL (operands[2]) != -128)))
5505 operands[2] = GEN_INT (-INTVAL (operands[2]));
5506 return "sub{q}\t{%2, %0|%0, %2}";
5508 return "add{q}\t{%2, %0|%0, %2}";
5512 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5513 (const_string "incdec")
5514 (const_string "alu")))
5515 (set_attr "mode" "DI")])
5517 (define_insn "*adddi_3_rex64"
5518 [(set (reg FLAGS_REG)
5519 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5520 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5521 (clobber (match_scratch:DI 0 "=r"))]
5523 && ix86_match_ccmode (insn, CCZmode)
5524 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5525 /* Current assemblers are broken and do not allow @GOTOFF in
5526 ought but a memory context. */
5527 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5529 switch (get_attr_type (insn))
5532 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5533 if (operands[2] == const1_rtx)
5534 return "inc{q}\t%0";
5537 gcc_assert (operands[2] == constm1_rtx);
5538 return "dec{q}\t%0";
5542 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5543 /* ???? We ought to handle there the 32bit case too
5544 - do we need new constraint? */
5545 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5546 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5547 if (CONST_INT_P (operands[2])
5548 /* Avoid overflows. */
5549 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5550 && (INTVAL (operands[2]) == 128
5551 || (INTVAL (operands[2]) < 0
5552 && INTVAL (operands[2]) != -128)))
5554 operands[2] = GEN_INT (-INTVAL (operands[2]));
5555 return "sub{q}\t{%2, %0|%0, %2}";
5557 return "add{q}\t{%2, %0|%0, %2}";
5561 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5562 (const_string "incdec")
5563 (const_string "alu")))
5564 (set_attr "mode" "DI")])
5566 ; For comparisons against 1, -1 and 128, we may generate better code
5567 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5568 ; is matched then. We can't accept general immediate, because for
5569 ; case of overflows, the result is messed up.
5570 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5572 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5573 ; only for comparisons not depending on it.
5574 (define_insn "*adddi_4_rex64"
5575 [(set (reg FLAGS_REG)
5576 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5577 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5578 (clobber (match_scratch:DI 0 "=rm"))]
5580 && ix86_match_ccmode (insn, CCGCmode)"
5582 switch (get_attr_type (insn))
5585 if (operands[2] == constm1_rtx)
5586 return "inc{q}\t%0";
5589 gcc_assert (operands[2] == const1_rtx);
5590 return "dec{q}\t%0";
5594 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5595 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5596 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5597 if ((INTVAL (operands[2]) == -128
5598 || (INTVAL (operands[2]) > 0
5599 && INTVAL (operands[2]) != 128))
5600 /* Avoid overflows. */
5601 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5602 return "sub{q}\t{%2, %0|%0, %2}";
5603 operands[2] = GEN_INT (-INTVAL (operands[2]));
5604 return "add{q}\t{%2, %0|%0, %2}";
5608 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5609 (const_string "incdec")
5610 (const_string "alu")))
5611 (set_attr "mode" "DI")])
5613 (define_insn "*adddi_5_rex64"
5614 [(set (reg FLAGS_REG)
5616 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5617 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5619 (clobber (match_scratch:DI 0 "=r"))]
5621 && ix86_match_ccmode (insn, CCGOCmode)
5622 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5623 /* Current assemblers are broken and do not allow @GOTOFF in
5624 ought but a memory context. */
5625 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5627 switch (get_attr_type (insn))
5630 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631 if (operands[2] == const1_rtx)
5632 return "inc{q}\t%0";
5635 gcc_assert (operands[2] == constm1_rtx);
5636 return "dec{q}\t%0";
5640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5642 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5643 if (CONST_INT_P (operands[2])
5644 /* Avoid overflows. */
5645 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5646 && (INTVAL (operands[2]) == 128
5647 || (INTVAL (operands[2]) < 0
5648 && INTVAL (operands[2]) != -128)))
5650 operands[2] = GEN_INT (-INTVAL (operands[2]));
5651 return "sub{q}\t{%2, %0|%0, %2}";
5653 return "add{q}\t{%2, %0|%0, %2}";
5657 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5658 (const_string "incdec")
5659 (const_string "alu")))
5660 (set_attr "mode" "DI")])
5663 (define_insn "*addsi_1"
5664 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5665 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5666 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5667 (clobber (reg:CC FLAGS_REG))]
5668 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5670 switch (get_attr_type (insn))
5673 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5674 return "lea{l}\t{%a2, %0|%0, %a2}";
5677 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5678 if (operands[2] == const1_rtx)
5679 return "inc{l}\t%0";
5682 gcc_assert (operands[2] == constm1_rtx);
5683 return "dec{l}\t%0";
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5690 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5691 if (CONST_INT_P (operands[2])
5692 && (INTVAL (operands[2]) == 128
5693 || (INTVAL (operands[2]) < 0
5694 && INTVAL (operands[2]) != -128)))
5696 operands[2] = GEN_INT (-INTVAL (operands[2]));
5697 return "sub{l}\t{%2, %0|%0, %2}";
5699 return "add{l}\t{%2, %0|%0, %2}";
5703 (cond [(eq_attr "alternative" "2")
5704 (const_string "lea")
5705 ; Current assemblers are broken and do not allow @GOTOFF in
5706 ; ought but a memory context.
5707 (match_operand:SI 2 "pic_symbolic_operand" "")
5708 (const_string "lea")
5709 (match_operand:SI 2 "incdec_operand" "")
5710 (const_string "incdec")
5712 (const_string "alu")))
5713 (set_attr "mode" "SI")])
5715 ;; Convert lea to the lea pattern to avoid flags dependency.
5717 [(set (match_operand 0 "register_operand" "")
5718 (plus (match_operand 1 "register_operand" "")
5719 (match_operand 2 "nonmemory_operand" "")))
5720 (clobber (reg:CC FLAGS_REG))]
5722 && true_regnum (operands[0]) != true_regnum (operands[1])"
5726 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5727 may confuse gen_lowpart. */
5728 if (GET_MODE (operands[0]) != Pmode)
5730 operands[1] = gen_lowpart (Pmode, operands[1]);
5731 operands[2] = gen_lowpart (Pmode, operands[2]);
5733 operands[0] = gen_lowpart (SImode, operands[0]);
5734 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5735 if (Pmode != SImode)
5736 pat = gen_rtx_SUBREG (SImode, pat, 0);
5737 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5741 ;; It may seem that nonimmediate operand is proper one for operand 1.
5742 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5743 ;; we take care in ix86_binary_operator_ok to not allow two memory
5744 ;; operands so proper swapping will be done in reload. This allow
5745 ;; patterns constructed from addsi_1 to match.
5746 (define_insn "addsi_1_zext"
5747 [(set (match_operand:DI 0 "register_operand" "=r,r")
5749 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5750 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5751 (clobber (reg:CC FLAGS_REG))]
5752 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5754 switch (get_attr_type (insn))
5757 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5758 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5761 if (operands[2] == const1_rtx)
5762 return "inc{l}\t%k0";
5765 gcc_assert (operands[2] == constm1_rtx);
5766 return "dec{l}\t%k0";
5770 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5771 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5772 if (CONST_INT_P (operands[2])
5773 && (INTVAL (operands[2]) == 128
5774 || (INTVAL (operands[2]) < 0
5775 && INTVAL (operands[2]) != -128)))
5777 operands[2] = GEN_INT (-INTVAL (operands[2]));
5778 return "sub{l}\t{%2, %k0|%k0, %2}";
5780 return "add{l}\t{%2, %k0|%k0, %2}";
5784 (cond [(eq_attr "alternative" "1")
5785 (const_string "lea")
5786 ; Current assemblers are broken and do not allow @GOTOFF in
5787 ; ought but a memory context.
5788 (match_operand:SI 2 "pic_symbolic_operand" "")
5789 (const_string "lea")
5790 (match_operand:SI 2 "incdec_operand" "")
5791 (const_string "incdec")
5793 (const_string "alu")))
5794 (set_attr "mode" "SI")])
5796 ;; Convert lea to the lea pattern to avoid flags dependency.
5798 [(set (match_operand:DI 0 "register_operand" "")
5800 (plus:SI (match_operand:SI 1 "register_operand" "")
5801 (match_operand:SI 2 "nonmemory_operand" ""))))
5802 (clobber (reg:CC FLAGS_REG))]
5803 "TARGET_64BIT && reload_completed
5804 && true_regnum (operands[0]) != true_regnum (operands[1])"
5806 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5808 operands[1] = gen_lowpart (Pmode, operands[1]);
5809 operands[2] = gen_lowpart (Pmode, operands[2]);
5812 (define_insn "*addsi_2"
5813 [(set (reg FLAGS_REG)
5815 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5816 (match_operand:SI 2 "general_operand" "rmni,rni"))
5818 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5819 (plus:SI (match_dup 1) (match_dup 2)))]
5820 "ix86_match_ccmode (insn, CCGOCmode)
5821 && ix86_binary_operator_ok (PLUS, SImode, operands)
5822 /* Current assemblers are broken and do not allow @GOTOFF in
5823 ought but a memory context. */
5824 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5826 switch (get_attr_type (insn))
5829 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5830 if (operands[2] == const1_rtx)
5831 return "inc{l}\t%0";
5834 gcc_assert (operands[2] == constm1_rtx);
5835 return "dec{l}\t%0";
5839 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5840 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5842 if (CONST_INT_P (operands[2])
5843 && (INTVAL (operands[2]) == 128
5844 || (INTVAL (operands[2]) < 0
5845 && INTVAL (operands[2]) != -128)))
5847 operands[2] = GEN_INT (-INTVAL (operands[2]));
5848 return "sub{l}\t{%2, %0|%0, %2}";
5850 return "add{l}\t{%2, %0|%0, %2}";
5854 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5855 (const_string "incdec")
5856 (const_string "alu")))
5857 (set_attr "mode" "SI")])
5859 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5860 (define_insn "*addsi_2_zext"
5861 [(set (reg FLAGS_REG)
5863 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5864 (match_operand:SI 2 "general_operand" "rmni"))
5866 (set (match_operand:DI 0 "register_operand" "=r")
5867 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5868 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5869 && ix86_binary_operator_ok (PLUS, SImode, operands)
5870 /* Current assemblers are broken and do not allow @GOTOFF in
5871 ought but a memory context. */
5872 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5874 switch (get_attr_type (insn))
5877 if (operands[2] == const1_rtx)
5878 return "inc{l}\t%k0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{l}\t%k0";
5886 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5888 if (CONST_INT_P (operands[2])
5889 && (INTVAL (operands[2]) == 128
5890 || (INTVAL (operands[2]) < 0
5891 && INTVAL (operands[2]) != -128)))
5893 operands[2] = GEN_INT (-INTVAL (operands[2]));
5894 return "sub{l}\t{%2, %k0|%k0, %2}";
5896 return "add{l}\t{%2, %k0|%k0, %2}";
5900 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "SI")])
5905 (define_insn "*addsi_3"
5906 [(set (reg FLAGS_REG)
5907 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5908 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5909 (clobber (match_scratch:SI 0 "=r"))]
5910 "ix86_match_ccmode (insn, CCZmode)
5911 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5912 /* Current assemblers are broken and do not allow @GOTOFF in
5913 ought but a memory context. */
5914 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5916 switch (get_attr_type (insn))
5919 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920 if (operands[2] == const1_rtx)
5921 return "inc{l}\t%0";
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return "dec{l}\t%0";
5929 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5930 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5931 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5932 if (CONST_INT_P (operands[2])
5933 && (INTVAL (operands[2]) == 128
5934 || (INTVAL (operands[2]) < 0
5935 && INTVAL (operands[2]) != -128)))
5937 operands[2] = GEN_INT (-INTVAL (operands[2]));
5938 return "sub{l}\t{%2, %0|%0, %2}";
5940 return "add{l}\t{%2, %0|%0, %2}";
5944 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set_attr "mode" "SI")])
5949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5950 (define_insn "*addsi_3_zext"
5951 [(set (reg FLAGS_REG)
5952 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5953 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5954 (set (match_operand:DI 0 "register_operand" "=r")
5955 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5956 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5957 && ix86_binary_operator_ok (PLUS, SImode, operands)
5958 /* Current assemblers are broken and do not allow @GOTOFF in
5959 ought but a memory context. */
5960 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5962 switch (get_attr_type (insn))
5965 if (operands[2] == const1_rtx)
5966 return "inc{l}\t%k0";
5969 gcc_assert (operands[2] == constm1_rtx);
5970 return "dec{l}\t%k0";
5974 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5976 if (CONST_INT_P (operands[2])
5977 && (INTVAL (operands[2]) == 128
5978 || (INTVAL (operands[2]) < 0
5979 && INTVAL (operands[2]) != -128)))
5981 operands[2] = GEN_INT (-INTVAL (operands[2]));
5982 return "sub{l}\t{%2, %k0|%k0, %2}";
5984 return "add{l}\t{%2, %k0|%k0, %2}";
5988 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5989 (const_string "incdec")
5990 (const_string "alu")))
5991 (set_attr "mode" "SI")])
5993 ; For comparisons against 1, -1 and 128, we may generate better code
5994 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5995 ; is matched then. We can't accept general immediate, because for
5996 ; case of overflows, the result is messed up.
5997 ; This pattern also don't hold of 0x80000000, since the value overflows
5999 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6000 ; only for comparisons not depending on it.
6001 (define_insn "*addsi_4"
6002 [(set (reg FLAGS_REG)
6003 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6004 (match_operand:SI 2 "const_int_operand" "n")))
6005 (clobber (match_scratch:SI 0 "=rm"))]
6006 "ix86_match_ccmode (insn, CCGCmode)
6007 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6009 switch (get_attr_type (insn))
6012 if (operands[2] == constm1_rtx)
6013 return "inc{l}\t%0";
6016 gcc_assert (operands[2] == const1_rtx);
6017 return "dec{l}\t%0";
6021 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6022 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6023 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6024 if ((INTVAL (operands[2]) == -128
6025 || (INTVAL (operands[2]) > 0
6026 && INTVAL (operands[2]) != 128)))
6027 return "sub{l}\t{%2, %0|%0, %2}";
6028 operands[2] = GEN_INT (-INTVAL (operands[2]));
6029 return "add{l}\t{%2, %0|%0, %2}";
6033 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6034 (const_string "incdec")
6035 (const_string "alu")))
6036 (set_attr "mode" "SI")])
6038 (define_insn "*addsi_5"
6039 [(set (reg FLAGS_REG)
6041 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6042 (match_operand:SI 2 "general_operand" "rmni"))
6044 (clobber (match_scratch:SI 0 "=r"))]
6045 "ix86_match_ccmode (insn, CCGOCmode)
6046 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6047 /* Current assemblers are broken and do not allow @GOTOFF in
6048 ought but a memory context. */
6049 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6051 switch (get_attr_type (insn))
6054 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6055 if (operands[2] == const1_rtx)
6056 return "inc{l}\t%0";
6059 gcc_assert (operands[2] == constm1_rtx);
6060 return "dec{l}\t%0";
6064 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6065 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6066 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6067 if (CONST_INT_P (operands[2])
6068 && (INTVAL (operands[2]) == 128
6069 || (INTVAL (operands[2]) < 0
6070 && INTVAL (operands[2]) != -128)))
6072 operands[2] = GEN_INT (-INTVAL (operands[2]));
6073 return "sub{l}\t{%2, %0|%0, %2}";
6075 return "add{l}\t{%2, %0|%0, %2}";
6079 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6080 (const_string "incdec")
6081 (const_string "alu")))
6082 (set_attr "mode" "SI")])
6084 (define_expand "addhi3"
6085 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6086 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6087 (match_operand:HI 2 "general_operand" "")))
6088 (clobber (reg:CC FLAGS_REG))])]
6089 "TARGET_HIMODE_MATH"
6090 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6092 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6093 ;; type optimizations enabled by define-splits. This is not important
6094 ;; for PII, and in fact harmful because of partial register stalls.
6096 (define_insn "*addhi_1_lea"
6097 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6098 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6099 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6100 (clobber (reg:CC FLAGS_REG))]
6101 "!TARGET_PARTIAL_REG_STALL
6102 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6104 switch (get_attr_type (insn))
6109 if (operands[2] == const1_rtx)
6110 return "inc{w}\t%0";
6113 gcc_assert (operands[2] == constm1_rtx);
6114 return "dec{w}\t%0";
6118 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6119 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6120 if (CONST_INT_P (operands[2])
6121 && (INTVAL (operands[2]) == 128
6122 || (INTVAL (operands[2]) < 0
6123 && INTVAL (operands[2]) != -128)))
6125 operands[2] = GEN_INT (-INTVAL (operands[2]));
6126 return "sub{w}\t{%2, %0|%0, %2}";
6128 return "add{w}\t{%2, %0|%0, %2}";
6132 (if_then_else (eq_attr "alternative" "2")
6133 (const_string "lea")
6134 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135 (const_string "incdec")
6136 (const_string "alu"))))
6137 (set_attr "mode" "HI,HI,SI")])
6139 (define_insn "*addhi_1"
6140 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6141 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6142 (match_operand:HI 2 "general_operand" "ri,rm")))
6143 (clobber (reg:CC FLAGS_REG))]
6144 "TARGET_PARTIAL_REG_STALL
6145 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6147 switch (get_attr_type (insn))
6150 if (operands[2] == const1_rtx)
6151 return "inc{w}\t%0";
6154 gcc_assert (operands[2] == constm1_rtx);
6155 return "dec{w}\t%0";
6159 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6160 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6161 if (CONST_INT_P (operands[2])
6162 && (INTVAL (operands[2]) == 128
6163 || (INTVAL (operands[2]) < 0
6164 && INTVAL (operands[2]) != -128)))
6166 operands[2] = GEN_INT (-INTVAL (operands[2]));
6167 return "sub{w}\t{%2, %0|%0, %2}";
6169 return "add{w}\t{%2, %0|%0, %2}";
6173 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6174 (const_string "incdec")
6175 (const_string "alu")))
6176 (set_attr "mode" "HI")])
6178 (define_insn "*addhi_2"
6179 [(set (reg FLAGS_REG)
6181 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6182 (match_operand:HI 2 "general_operand" "rmni,rni"))
6184 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6185 (plus:HI (match_dup 1) (match_dup 2)))]
6186 "ix86_match_ccmode (insn, CCGOCmode)
6187 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6189 switch (get_attr_type (insn))
6192 if (operands[2] == const1_rtx)
6193 return "inc{w}\t%0";
6196 gcc_assert (operands[2] == constm1_rtx);
6197 return "dec{w}\t%0";
6201 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6202 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6203 if (CONST_INT_P (operands[2])
6204 && (INTVAL (operands[2]) == 128
6205 || (INTVAL (operands[2]) < 0
6206 && INTVAL (operands[2]) != -128)))
6208 operands[2] = GEN_INT (-INTVAL (operands[2]));
6209 return "sub{w}\t{%2, %0|%0, %2}";
6211 return "add{w}\t{%2, %0|%0, %2}";
6215 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6216 (const_string "incdec")
6217 (const_string "alu")))
6218 (set_attr "mode" "HI")])
6220 (define_insn "*addhi_3"
6221 [(set (reg FLAGS_REG)
6222 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6223 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6224 (clobber (match_scratch:HI 0 "=r"))]
6225 "ix86_match_ccmode (insn, CCZmode)
6226 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6228 switch (get_attr_type (insn))
6231 if (operands[2] == const1_rtx)
6232 return "inc{w}\t%0";
6235 gcc_assert (operands[2] == constm1_rtx);
6236 return "dec{w}\t%0";
6240 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6242 if (CONST_INT_P (operands[2])
6243 && (INTVAL (operands[2]) == 128
6244 || (INTVAL (operands[2]) < 0
6245 && INTVAL (operands[2]) != -128)))
6247 operands[2] = GEN_INT (-INTVAL (operands[2]));
6248 return "sub{w}\t{%2, %0|%0, %2}";
6250 return "add{w}\t{%2, %0|%0, %2}";
6254 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255 (const_string "incdec")
6256 (const_string "alu")))
6257 (set_attr "mode" "HI")])
6259 ; See comments above addsi_4 for details.
6260 (define_insn "*addhi_4"
6261 [(set (reg FLAGS_REG)
6262 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6263 (match_operand:HI 2 "const_int_operand" "n")))
6264 (clobber (match_scratch:HI 0 "=rm"))]
6265 "ix86_match_ccmode (insn, CCGCmode)
6266 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6268 switch (get_attr_type (insn))
6271 if (operands[2] == constm1_rtx)
6272 return "inc{w}\t%0";
6275 gcc_assert (operands[2] == const1_rtx);
6276 return "dec{w}\t%0";
6280 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6281 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6282 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6283 if ((INTVAL (operands[2]) == -128
6284 || (INTVAL (operands[2]) > 0
6285 && INTVAL (operands[2]) != 128)))
6286 return "sub{w}\t{%2, %0|%0, %2}";
6287 operands[2] = GEN_INT (-INTVAL (operands[2]));
6288 return "add{w}\t{%2, %0|%0, %2}";
6292 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6293 (const_string "incdec")
6294 (const_string "alu")))
6295 (set_attr "mode" "SI")])
6298 (define_insn "*addhi_5"
6299 [(set (reg FLAGS_REG)
6301 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6302 (match_operand:HI 2 "general_operand" "rmni"))
6304 (clobber (match_scratch:HI 0 "=r"))]
6305 "ix86_match_ccmode (insn, CCGOCmode)
6306 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6308 switch (get_attr_type (insn))
6311 if (operands[2] == const1_rtx)
6312 return "inc{w}\t%0";
6315 gcc_assert (operands[2] == constm1_rtx);
6316 return "dec{w}\t%0";
6320 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6321 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6322 if (CONST_INT_P (operands[2])
6323 && (INTVAL (operands[2]) == 128
6324 || (INTVAL (operands[2]) < 0
6325 && INTVAL (operands[2]) != -128)))
6327 operands[2] = GEN_INT (-INTVAL (operands[2]));
6328 return "sub{w}\t{%2, %0|%0, %2}";
6330 return "add{w}\t{%2, %0|%0, %2}";
6334 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6335 (const_string "incdec")
6336 (const_string "alu")))
6337 (set_attr "mode" "HI")])
6339 (define_expand "addqi3"
6340 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6341 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6342 (match_operand:QI 2 "general_operand" "")))
6343 (clobber (reg:CC FLAGS_REG))])]
6344 "TARGET_QIMODE_MATH"
6345 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6347 ;; %%% Potential partial reg stall on alternative 2. What to do?
6348 (define_insn "*addqi_1_lea"
6349 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6350 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6351 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6352 (clobber (reg:CC FLAGS_REG))]
6353 "!TARGET_PARTIAL_REG_STALL
6354 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6356 int widen = (which_alternative == 2);
6357 switch (get_attr_type (insn))
6362 if (operands[2] == const1_rtx)
6363 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6366 gcc_assert (operands[2] == constm1_rtx);
6367 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6371 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6372 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6373 if (CONST_INT_P (operands[2])
6374 && (INTVAL (operands[2]) == 128
6375 || (INTVAL (operands[2]) < 0
6376 && INTVAL (operands[2]) != -128)))
6378 operands[2] = GEN_INT (-INTVAL (operands[2]));
6380 return "sub{l}\t{%2, %k0|%k0, %2}";
6382 return "sub{b}\t{%2, %0|%0, %2}";
6385 return "add{l}\t{%k2, %k0|%k0, %k2}";
6387 return "add{b}\t{%2, %0|%0, %2}";
6391 (if_then_else (eq_attr "alternative" "3")
6392 (const_string "lea")
6393 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6394 (const_string "incdec")
6395 (const_string "alu"))))
6396 (set_attr "mode" "QI,QI,SI,SI")])
6398 (define_insn "*addqi_1"
6399 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6400 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6401 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6402 (clobber (reg:CC FLAGS_REG))]
6403 "TARGET_PARTIAL_REG_STALL
6404 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6406 int widen = (which_alternative == 2);
6407 switch (get_attr_type (insn))
6410 if (operands[2] == const1_rtx)
6411 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6414 gcc_assert (operands[2] == constm1_rtx);
6415 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6419 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6420 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6421 if (CONST_INT_P (operands[2])
6422 && (INTVAL (operands[2]) == 128
6423 || (INTVAL (operands[2]) < 0
6424 && INTVAL (operands[2]) != -128)))
6426 operands[2] = GEN_INT (-INTVAL (operands[2]));
6428 return "sub{l}\t{%2, %k0|%k0, %2}";
6430 return "sub{b}\t{%2, %0|%0, %2}";
6433 return "add{l}\t{%k2, %k0|%k0, %k2}";
6435 return "add{b}\t{%2, %0|%0, %2}";
6439 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6440 (const_string "incdec")
6441 (const_string "alu")))
6442 (set_attr "mode" "QI,QI,SI")])
6444 (define_insn "*addqi_1_slp"
6445 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6446 (plus:QI (match_dup 0)
6447 (match_operand:QI 1 "general_operand" "qn,qnm")))
6448 (clobber (reg:CC FLAGS_REG))]
6449 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6450 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6452 switch (get_attr_type (insn))
6455 if (operands[1] == const1_rtx)
6456 return "inc{b}\t%0";
6459 gcc_assert (operands[1] == constm1_rtx);
6460 return "dec{b}\t%0";
6464 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6465 if (CONST_INT_P (operands[1])
6466 && INTVAL (operands[1]) < 0)
6468 operands[1] = GEN_INT (-INTVAL (operands[1]));
6469 return "sub{b}\t{%1, %0|%0, %1}";
6471 return "add{b}\t{%1, %0|%0, %1}";
6475 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6476 (const_string "incdec")
6477 (const_string "alu1")))
6478 (set (attr "memory")
6479 (if_then_else (match_operand 1 "memory_operand" "")
6480 (const_string "load")
6481 (const_string "none")))
6482 (set_attr "mode" "QI")])
6484 (define_insn "*addqi_2"
6485 [(set (reg FLAGS_REG)
6487 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6488 (match_operand:QI 2 "general_operand" "qmni,qni"))
6490 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6491 (plus:QI (match_dup 1) (match_dup 2)))]
6492 "ix86_match_ccmode (insn, CCGOCmode)
6493 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6495 switch (get_attr_type (insn))
6498 if (operands[2] == const1_rtx)
6499 return "inc{b}\t%0";
6502 gcc_assert (operands[2] == constm1_rtx
6503 || (CONST_INT_P (operands[2])
6504 && INTVAL (operands[2]) == 255));
6505 return "dec{b}\t%0";
6509 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6510 if (CONST_INT_P (operands[2])
6511 && INTVAL (operands[2]) < 0)
6513 operands[2] = GEN_INT (-INTVAL (operands[2]));
6514 return "sub{b}\t{%2, %0|%0, %2}";
6516 return "add{b}\t{%2, %0|%0, %2}";
6520 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6521 (const_string "incdec")
6522 (const_string "alu")))
6523 (set_attr "mode" "QI")])
6525 (define_insn "*addqi_3"
6526 [(set (reg FLAGS_REG)
6527 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6528 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6529 (clobber (match_scratch:QI 0 "=q"))]
6530 "ix86_match_ccmode (insn, CCZmode)
6531 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6533 switch (get_attr_type (insn))
6536 if (operands[2] == const1_rtx)
6537 return "inc{b}\t%0";
6540 gcc_assert (operands[2] == constm1_rtx
6541 || (CONST_INT_P (operands[2])
6542 && INTVAL (operands[2]) == 255));
6543 return "dec{b}\t%0";
6547 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6548 if (CONST_INT_P (operands[2])
6549 && INTVAL (operands[2]) < 0)
6551 operands[2] = GEN_INT (-INTVAL (operands[2]));
6552 return "sub{b}\t{%2, %0|%0, %2}";
6554 return "add{b}\t{%2, %0|%0, %2}";
6558 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6559 (const_string "incdec")
6560 (const_string "alu")))
6561 (set_attr "mode" "QI")])
6563 ; See comments above addsi_4 for details.
6564 (define_insn "*addqi_4"
6565 [(set (reg FLAGS_REG)
6566 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6567 (match_operand:QI 2 "const_int_operand" "n")))
6568 (clobber (match_scratch:QI 0 "=qm"))]
6569 "ix86_match_ccmode (insn, CCGCmode)
6570 && (INTVAL (operands[2]) & 0xff) != 0x80"
6572 switch (get_attr_type (insn))
6575 if (operands[2] == constm1_rtx
6576 || (CONST_INT_P (operands[2])
6577 && INTVAL (operands[2]) == 255))
6578 return "inc{b}\t%0";
6581 gcc_assert (operands[2] == const1_rtx);
6582 return "dec{b}\t%0";
6586 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6587 if (INTVAL (operands[2]) < 0)
6589 operands[2] = GEN_INT (-INTVAL (operands[2]));
6590 return "add{b}\t{%2, %0|%0, %2}";
6592 return "sub{b}\t{%2, %0|%0, %2}";
6596 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6597 (const_string "incdec")
6598 (const_string "alu")))
6599 (set_attr "mode" "QI")])
6602 (define_insn "*addqi_5"
6603 [(set (reg FLAGS_REG)
6605 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6606 (match_operand:QI 2 "general_operand" "qmni"))
6608 (clobber (match_scratch:QI 0 "=q"))]
6609 "ix86_match_ccmode (insn, CCGOCmode)
6610 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6612 switch (get_attr_type (insn))
6615 if (operands[2] == const1_rtx)
6616 return "inc{b}\t%0";
6619 gcc_assert (operands[2] == constm1_rtx
6620 || (CONST_INT_P (operands[2])
6621 && INTVAL (operands[2]) == 255));
6622 return "dec{b}\t%0";
6626 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6627 if (CONST_INT_P (operands[2])
6628 && INTVAL (operands[2]) < 0)
6630 operands[2] = GEN_INT (-INTVAL (operands[2]));
6631 return "sub{b}\t{%2, %0|%0, %2}";
6633 return "add{b}\t{%2, %0|%0, %2}";
6637 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6638 (const_string "incdec")
6639 (const_string "alu")))
6640 (set_attr "mode" "QI")])
6643 (define_insn "addqi_ext_1"
6644 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6649 (match_operand 1 "ext_register_operand" "0")
6652 (match_operand:QI 2 "general_operand" "Qmn")))
6653 (clobber (reg:CC FLAGS_REG))]
6656 switch (get_attr_type (insn))
6659 if (operands[2] == const1_rtx)
6660 return "inc{b}\t%h0";
6663 gcc_assert (operands[2] == constm1_rtx
6664 || (CONST_INT_P (operands[2])
6665 && INTVAL (operands[2]) == 255));
6666 return "dec{b}\t%h0";
6670 return "add{b}\t{%2, %h0|%h0, %2}";
6674 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6675 (const_string "incdec")
6676 (const_string "alu")))
6677 (set_attr "mode" "QI")])
6679 (define_insn "*addqi_ext_1_rex64"
6680 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6685 (match_operand 1 "ext_register_operand" "0")
6688 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6689 (clobber (reg:CC FLAGS_REG))]
6692 switch (get_attr_type (insn))
6695 if (operands[2] == const1_rtx)
6696 return "inc{b}\t%h0";
6699 gcc_assert (operands[2] == constm1_rtx
6700 || (CONST_INT_P (operands[2])
6701 && INTVAL (operands[2]) == 255));
6702 return "dec{b}\t%h0";
6706 return "add{b}\t{%2, %h0|%h0, %2}";
6710 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6711 (const_string "incdec")
6712 (const_string "alu")))
6713 (set_attr "mode" "QI")])
6715 (define_insn "*addqi_ext_2"
6716 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6721 (match_operand 1 "ext_register_operand" "%0")
6725 (match_operand 2 "ext_register_operand" "Q")
6728 (clobber (reg:CC FLAGS_REG))]
6730 "add{b}\t{%h2, %h0|%h0, %h2}"
6731 [(set_attr "type" "alu")
6732 (set_attr "mode" "QI")])
6734 ;; The patterns that match these are at the end of this file.
6736 (define_expand "addxf3"
6737 [(set (match_operand:XF 0 "register_operand" "")
6738 (plus:XF (match_operand:XF 1 "register_operand" "")
6739 (match_operand:XF 2 "register_operand" "")))]
6743 (define_expand "adddf3"
6744 [(set (match_operand:DF 0 "register_operand" "")
6745 (plus:DF (match_operand:DF 1 "register_operand" "")
6746 (match_operand:DF 2 "nonimmediate_operand" "")))]
6747 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6750 (define_expand "addsf3"
6751 [(set (match_operand:SF 0 "register_operand" "")
6752 (plus:SF (match_operand:SF 1 "register_operand" "")
6753 (match_operand:SF 2 "nonimmediate_operand" "")))]
6754 "TARGET_80387 || TARGET_SSE_MATH"
6757 ;; Subtract instructions
6759 ;; %%% splits for subditi3
6761 (define_expand "subti3"
6762 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6763 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6764 (match_operand:TI 2 "x86_64_general_operand" "")))
6765 (clobber (reg:CC FLAGS_REG))])]
6767 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6769 (define_insn "*subti3_1"
6770 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6771 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6772 (match_operand:TI 2 "general_operand" "roiF,riF")))
6773 (clobber (reg:CC FLAGS_REG))]
6774 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6778 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6779 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6780 (match_operand:TI 2 "general_operand" "")))
6781 (clobber (reg:CC FLAGS_REG))]
6782 "TARGET_64BIT && reload_completed"
6783 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6784 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6785 (parallel [(set (match_dup 3)
6786 (minus:DI (match_dup 4)
6787 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6789 (clobber (reg:CC FLAGS_REG))])]
6790 "split_ti (operands+0, 1, operands+0, operands+3);
6791 split_ti (operands+1, 1, operands+1, operands+4);
6792 split_ti (operands+2, 1, operands+2, operands+5);")
6794 ;; %%% splits for subsidi3
6796 (define_expand "subdi3"
6797 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6798 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6799 (match_operand:DI 2 "x86_64_general_operand" "")))
6800 (clobber (reg:CC FLAGS_REG))])]
6802 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6804 (define_insn "*subdi3_1"
6805 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6806 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6807 (match_operand:DI 2 "general_operand" "roiF,riF")))
6808 (clobber (reg:CC FLAGS_REG))]
6809 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6813 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6814 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6815 (match_operand:DI 2 "general_operand" "")))
6816 (clobber (reg:CC FLAGS_REG))]
6817 "!TARGET_64BIT && reload_completed"
6818 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6819 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6820 (parallel [(set (match_dup 3)
6821 (minus:SI (match_dup 4)
6822 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6824 (clobber (reg:CC FLAGS_REG))])]
6825 "split_di (operands+0, 1, operands+0, operands+3);
6826 split_di (operands+1, 1, operands+1, operands+4);
6827 split_di (operands+2, 1, operands+2, operands+5);")
6829 (define_insn "subdi3_carry_rex64"
6830 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6831 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6832 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6833 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6834 (clobber (reg:CC FLAGS_REG))]
6835 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6836 "sbb{q}\t{%2, %0|%0, %2}"
6837 [(set_attr "type" "alu")
6838 (set_attr "pent_pair" "pu")
6839 (set_attr "mode" "DI")])
6841 (define_insn "*subdi_1_rex64"
6842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6843 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6844 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6845 (clobber (reg:CC FLAGS_REG))]
6846 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6847 "sub{q}\t{%2, %0|%0, %2}"
6848 [(set_attr "type" "alu")
6849 (set_attr "mode" "DI")])
6851 (define_insn "*subdi_2_rex64"
6852 [(set (reg FLAGS_REG)
6854 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6855 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6857 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6858 (minus:DI (match_dup 1) (match_dup 2)))]
6859 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6860 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6861 "sub{q}\t{%2, %0|%0, %2}"
6862 [(set_attr "type" "alu")
6863 (set_attr "mode" "DI")])
6865 (define_insn "*subdi_3_rex63"
6866 [(set (reg FLAGS_REG)
6867 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6868 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6869 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6870 (minus:DI (match_dup 1) (match_dup 2)))]
6871 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6872 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6873 "sub{q}\t{%2, %0|%0, %2}"
6874 [(set_attr "type" "alu")
6875 (set_attr "mode" "DI")])
6877 (define_insn "subqi3_carry"
6878 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6879 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6880 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6881 (match_operand:QI 2 "general_operand" "qi,qm"))))
6882 (clobber (reg:CC FLAGS_REG))]
6883 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6884 "sbb{b}\t{%2, %0|%0, %2}"
6885 [(set_attr "type" "alu")
6886 (set_attr "pent_pair" "pu")
6887 (set_attr "mode" "QI")])
6889 (define_insn "subhi3_carry"
6890 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6891 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6892 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6893 (match_operand:HI 2 "general_operand" "ri,rm"))))
6894 (clobber (reg:CC FLAGS_REG))]
6895 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6896 "sbb{w}\t{%2, %0|%0, %2}"
6897 [(set_attr "type" "alu")
6898 (set_attr "pent_pair" "pu")
6899 (set_attr "mode" "HI")])
6901 (define_insn "subsi3_carry"
6902 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6903 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6904 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6905 (match_operand:SI 2 "general_operand" "ri,rm"))))
6906 (clobber (reg:CC FLAGS_REG))]
6907 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6908 "sbb{l}\t{%2, %0|%0, %2}"
6909 [(set_attr "type" "alu")
6910 (set_attr "pent_pair" "pu")
6911 (set_attr "mode" "SI")])
6913 (define_insn "subsi3_carry_zext"
6914 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6916 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6917 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6918 (match_operand:SI 2 "general_operand" "ri,rm")))))
6919 (clobber (reg:CC FLAGS_REG))]
6920 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6921 "sbb{l}\t{%2, %k0|%k0, %2}"
6922 [(set_attr "type" "alu")
6923 (set_attr "pent_pair" "pu")
6924 (set_attr "mode" "SI")])
6926 (define_expand "subsi3"
6927 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6928 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6929 (match_operand:SI 2 "general_operand" "")))
6930 (clobber (reg:CC FLAGS_REG))])]
6932 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6934 (define_insn "*subsi_1"
6935 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6936 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6937 (match_operand:SI 2 "general_operand" "ri,rm")))
6938 (clobber (reg:CC FLAGS_REG))]
6939 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6940 "sub{l}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "alu")
6942 (set_attr "mode" "SI")])
6944 (define_insn "*subsi_1_zext"
6945 [(set (match_operand:DI 0 "register_operand" "=r")
6947 (minus:SI (match_operand:SI 1 "register_operand" "0")
6948 (match_operand:SI 2 "general_operand" "rim"))))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6951 "sub{l}\t{%2, %k0|%k0, %2}"
6952 [(set_attr "type" "alu")
6953 (set_attr "mode" "SI")])
6955 (define_insn "*subsi_2"
6956 [(set (reg FLAGS_REG)
6958 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6959 (match_operand:SI 2 "general_operand" "ri,rm"))
6961 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6962 (minus:SI (match_dup 1) (match_dup 2)))]
6963 "ix86_match_ccmode (insn, CCGOCmode)
6964 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6965 "sub{l}\t{%2, %0|%0, %2}"
6966 [(set_attr "type" "alu")
6967 (set_attr "mode" "SI")])
6969 (define_insn "*subsi_2_zext"
6970 [(set (reg FLAGS_REG)
6972 (minus:SI (match_operand:SI 1 "register_operand" "0")
6973 (match_operand:SI 2 "general_operand" "rim"))
6975 (set (match_operand:DI 0 "register_operand" "=r")
6977 (minus:SI (match_dup 1)
6979 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6980 && 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_3"
6986 [(set (reg FLAGS_REG)
6987 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6988 (match_operand:SI 2 "general_operand" "ri,rm")))
6989 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6990 (minus:SI (match_dup 1) (match_dup 2)))]
6991 "ix86_match_ccmode (insn, CCmode)
6992 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6993 "sub{l}\t{%2, %0|%0, %2}"
6994 [(set_attr "type" "alu")
6995 (set_attr "mode" "SI")])
6997 (define_insn "*subsi_3_zext"
6998 [(set (reg FLAGS_REG)
6999 (compare (match_operand:SI 1 "register_operand" "0")
7000 (match_operand:SI 2 "general_operand" "rim")))
7001 (set (match_operand:DI 0 "register_operand" "=r")
7003 (minus:SI (match_dup 1)
7005 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7006 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7007 "sub{l}\t{%2, %1|%1, %2}"
7008 [(set_attr "type" "alu")
7009 (set_attr "mode" "DI")])
7011 (define_expand "subhi3"
7012 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7013 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7014 (match_operand:HI 2 "general_operand" "")))
7015 (clobber (reg:CC FLAGS_REG))])]
7016 "TARGET_HIMODE_MATH"
7017 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7019 (define_insn "*subhi_1"
7020 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7021 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7022 (match_operand:HI 2 "general_operand" "ri,rm")))
7023 (clobber (reg:CC FLAGS_REG))]
7024 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7025 "sub{w}\t{%2, %0|%0, %2}"
7026 [(set_attr "type" "alu")
7027 (set_attr "mode" "HI")])
7029 (define_insn "*subhi_2"
7030 [(set (reg FLAGS_REG)
7032 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7033 (match_operand:HI 2 "general_operand" "ri,rm"))
7035 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7036 (minus:HI (match_dup 1) (match_dup 2)))]
7037 "ix86_match_ccmode (insn, CCGOCmode)
7038 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7039 "sub{w}\t{%2, %0|%0, %2}"
7040 [(set_attr "type" "alu")
7041 (set_attr "mode" "HI")])
7043 (define_insn "*subhi_3"
7044 [(set (reg FLAGS_REG)
7045 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7046 (match_operand:HI 2 "general_operand" "ri,rm")))
7047 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7048 (minus:HI (match_dup 1) (match_dup 2)))]
7049 "ix86_match_ccmode (insn, CCmode)
7050 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7051 "sub{w}\t{%2, %0|%0, %2}"
7052 [(set_attr "type" "alu")
7053 (set_attr "mode" "HI")])
7055 (define_expand "subqi3"
7056 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7057 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7058 (match_operand:QI 2 "general_operand" "")))
7059 (clobber (reg:CC FLAGS_REG))])]
7060 "TARGET_QIMODE_MATH"
7061 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7063 (define_insn "*subqi_1"
7064 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7065 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7066 (match_operand:QI 2 "general_operand" "qn,qmn")))
7067 (clobber (reg:CC FLAGS_REG))]
7068 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7069 "sub{b}\t{%2, %0|%0, %2}"
7070 [(set_attr "type" "alu")
7071 (set_attr "mode" "QI")])
7073 (define_insn "*subqi_1_slp"
7074 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7075 (minus:QI (match_dup 0)
7076 (match_operand:QI 1 "general_operand" "qn,qmn")))
7077 (clobber (reg:CC FLAGS_REG))]
7078 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7079 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7080 "sub{b}\t{%1, %0|%0, %1}"
7081 [(set_attr "type" "alu1")
7082 (set_attr "mode" "QI")])
7084 (define_insn "*subqi_2"
7085 [(set (reg FLAGS_REG)
7087 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7088 (match_operand:QI 2 "general_operand" "qi,qm"))
7090 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7091 (minus:HI (match_dup 1) (match_dup 2)))]
7092 "ix86_match_ccmode (insn, CCGOCmode)
7093 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7094 "sub{b}\t{%2, %0|%0, %2}"
7095 [(set_attr "type" "alu")
7096 (set_attr "mode" "QI")])
7098 (define_insn "*subqi_3"
7099 [(set (reg FLAGS_REG)
7100 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7101 (match_operand:QI 2 "general_operand" "qi,qm")))
7102 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7103 (minus:HI (match_dup 1) (match_dup 2)))]
7104 "ix86_match_ccmode (insn, CCmode)
7105 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7106 "sub{b}\t{%2, %0|%0, %2}"
7107 [(set_attr "type" "alu")
7108 (set_attr "mode" "QI")])
7110 ;; The patterns that match these are at the end of this file.
7112 (define_expand "subxf3"
7113 [(set (match_operand:XF 0 "register_operand" "")
7114 (minus:XF (match_operand:XF 1 "register_operand" "")
7115 (match_operand:XF 2 "register_operand" "")))]
7119 (define_expand "subdf3"
7120 [(set (match_operand:DF 0 "register_operand" "")
7121 (minus:DF (match_operand:DF 1 "register_operand" "")
7122 (match_operand:DF 2 "nonimmediate_operand" "")))]
7123 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7126 (define_expand "subsf3"
7127 [(set (match_operand:SF 0 "register_operand" "")
7128 (minus:SF (match_operand:SF 1 "register_operand" "")
7129 (match_operand:SF 2 "nonimmediate_operand" "")))]
7130 "TARGET_80387 || TARGET_SSE_MATH"
7133 ;; Multiply instructions
7135 (define_expand "muldi3"
7136 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7137 (mult:DI (match_operand:DI 1 "register_operand" "")
7138 (match_operand:DI 2 "x86_64_general_operand" "")))
7139 (clobber (reg:CC FLAGS_REG))])]
7144 ;; IMUL reg64, reg64, imm8 Direct
7145 ;; IMUL reg64, mem64, imm8 VectorPath
7146 ;; IMUL reg64, reg64, imm32 Direct
7147 ;; IMUL reg64, mem64, imm32 VectorPath
7148 ;; IMUL reg64, reg64 Direct
7149 ;; IMUL reg64, mem64 Direct
7151 (define_insn "*muldi3_1_rex64"
7152 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7153 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7154 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7155 (clobber (reg:CC FLAGS_REG))]
7157 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7159 imul{q}\t{%2, %1, %0|%0, %1, %2}
7160 imul{q}\t{%2, %1, %0|%0, %1, %2}
7161 imul{q}\t{%2, %0|%0, %2}"
7162 [(set_attr "type" "imul")
7163 (set_attr "prefix_0f" "0,0,1")
7164 (set (attr "athlon_decode")
7165 (cond [(eq_attr "cpu" "athlon")
7166 (const_string "vector")
7167 (eq_attr "alternative" "1")
7168 (const_string "vector")
7169 (and (eq_attr "alternative" "2")
7170 (match_operand 1 "memory_operand" ""))
7171 (const_string "vector")]
7172 (const_string "direct")))
7173 (set (attr "amdfam10_decode")
7174 (cond [(and (eq_attr "alternative" "0,1")
7175 (match_operand 1 "memory_operand" ""))
7176 (const_string "vector")]
7177 (const_string "direct")))
7178 (set_attr "mode" "DI")])
7180 (define_expand "mulsi3"
7181 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7182 (mult:SI (match_operand:SI 1 "register_operand" "")
7183 (match_operand:SI 2 "general_operand" "")))
7184 (clobber (reg:CC FLAGS_REG))])]
7189 ;; IMUL reg32, reg32, imm8 Direct
7190 ;; IMUL reg32, mem32, imm8 VectorPath
7191 ;; IMUL reg32, reg32, imm32 Direct
7192 ;; IMUL reg32, mem32, imm32 VectorPath
7193 ;; IMUL reg32, reg32 Direct
7194 ;; IMUL reg32, mem32 Direct
7196 (define_insn "*mulsi3_1"
7197 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7198 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7199 (match_operand:SI 2 "general_operand" "K,i,mr")))
7200 (clobber (reg:CC FLAGS_REG))]
7201 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7203 imul{l}\t{%2, %1, %0|%0, %1, %2}
7204 imul{l}\t{%2, %1, %0|%0, %1, %2}
7205 imul{l}\t{%2, %0|%0, %2}"
7206 [(set_attr "type" "imul")
7207 (set_attr "prefix_0f" "0,0,1")
7208 (set (attr "athlon_decode")
7209 (cond [(eq_attr "cpu" "athlon")
7210 (const_string "vector")
7211 (eq_attr "alternative" "1")
7212 (const_string "vector")
7213 (and (eq_attr "alternative" "2")
7214 (match_operand 1 "memory_operand" ""))
7215 (const_string "vector")]
7216 (const_string "direct")))
7217 (set (attr "amdfam10_decode")
7218 (cond [(and (eq_attr "alternative" "0,1")
7219 (match_operand 1 "memory_operand" ""))
7220 (const_string "vector")]
7221 (const_string "direct")))
7222 (set_attr "mode" "SI")])
7224 (define_insn "*mulsi3_1_zext"
7225 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7227 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7228 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7229 (clobber (reg:CC FLAGS_REG))]
7231 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7233 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7234 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7235 imul{l}\t{%2, %k0|%k0, %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_expand "mulhi3"
7255 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7256 (mult:HI (match_operand:HI 1 "register_operand" "")
7257 (match_operand:HI 2 "general_operand" "")))
7258 (clobber (reg:CC FLAGS_REG))])]
7259 "TARGET_HIMODE_MATH"
7263 ;; IMUL reg16, reg16, imm8 VectorPath
7264 ;; IMUL reg16, mem16, imm8 VectorPath
7265 ;; IMUL reg16, reg16, imm16 VectorPath
7266 ;; IMUL reg16, mem16, imm16 VectorPath
7267 ;; IMUL reg16, reg16 Direct
7268 ;; IMUL reg16, mem16 Direct
7269 (define_insn "*mulhi3_1"
7270 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7271 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7272 (match_operand:HI 2 "general_operand" "K,i,mr")))
7273 (clobber (reg:CC FLAGS_REG))]
7274 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7276 imul{w}\t{%2, %1, %0|%0, %1, %2}
7277 imul{w}\t{%2, %1, %0|%0, %1, %2}
7278 imul{w}\t{%2, %0|%0, %2}"
7279 [(set_attr "type" "imul")
7280 (set_attr "prefix_0f" "0,0,1")
7281 (set (attr "athlon_decode")
7282 (cond [(eq_attr "cpu" "athlon")
7283 (const_string "vector")
7284 (eq_attr "alternative" "1,2")
7285 (const_string "vector")]
7286 (const_string "direct")))
7287 (set (attr "amdfam10_decode")
7288 (cond [(eq_attr "alternative" "0,1")
7289 (const_string "vector")]
7290 (const_string "direct")))
7291 (set_attr "mode" "HI")])
7293 (define_expand "mulqi3"
7294 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7295 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7296 (match_operand:QI 2 "register_operand" "")))
7297 (clobber (reg:CC FLAGS_REG))])]
7298 "TARGET_QIMODE_MATH"
7305 (define_insn "*mulqi3_1"
7306 [(set (match_operand:QI 0 "register_operand" "=a")
7307 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7308 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7309 (clobber (reg:CC FLAGS_REG))]
7311 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7313 [(set_attr "type" "imul")
7314 (set_attr "length_immediate" "0")
7315 (set (attr "athlon_decode")
7316 (if_then_else (eq_attr "cpu" "athlon")
7317 (const_string "vector")
7318 (const_string "direct")))
7319 (set_attr "amdfam10_decode" "direct")
7320 (set_attr "mode" "QI")])
7322 (define_expand "umulqihi3"
7323 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7324 (mult:HI (zero_extend:HI
7325 (match_operand:QI 1 "nonimmediate_operand" ""))
7327 (match_operand:QI 2 "register_operand" ""))))
7328 (clobber (reg:CC FLAGS_REG))])]
7329 "TARGET_QIMODE_MATH"
7332 (define_insn "*umulqihi3_1"
7333 [(set (match_operand:HI 0 "register_operand" "=a")
7334 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7335 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7336 (clobber (reg:CC FLAGS_REG))]
7338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7340 [(set_attr "type" "imul")
7341 (set_attr "length_immediate" "0")
7342 (set (attr "athlon_decode")
7343 (if_then_else (eq_attr "cpu" "athlon")
7344 (const_string "vector")
7345 (const_string "direct")))
7346 (set_attr "amdfam10_decode" "direct")
7347 (set_attr "mode" "QI")])
7349 (define_expand "mulqihi3"
7350 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7351 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7352 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7353 (clobber (reg:CC FLAGS_REG))])]
7354 "TARGET_QIMODE_MATH"
7357 (define_insn "*mulqihi3_insn"
7358 [(set (match_operand:HI 0 "register_operand" "=a")
7359 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7360 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7361 (clobber (reg:CC FLAGS_REG))]
7363 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7365 [(set_attr "type" "imul")
7366 (set_attr "length_immediate" "0")
7367 (set (attr "athlon_decode")
7368 (if_then_else (eq_attr "cpu" "athlon")
7369 (const_string "vector")
7370 (const_string "direct")))
7371 (set_attr "amdfam10_decode" "direct")
7372 (set_attr "mode" "QI")])
7374 (define_expand "umulditi3"
7375 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7376 (mult:TI (zero_extend:TI
7377 (match_operand:DI 1 "nonimmediate_operand" ""))
7379 (match_operand:DI 2 "register_operand" ""))))
7380 (clobber (reg:CC FLAGS_REG))])]
7384 (define_insn "*umulditi3_insn"
7385 [(set (match_operand:TI 0 "register_operand" "=A")
7386 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7387 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7388 (clobber (reg:CC FLAGS_REG))]
7390 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7392 [(set_attr "type" "imul")
7393 (set_attr "length_immediate" "0")
7394 (set (attr "athlon_decode")
7395 (if_then_else (eq_attr "cpu" "athlon")
7396 (const_string "vector")
7397 (const_string "double")))
7398 (set_attr "amdfam10_decode" "double")
7399 (set_attr "mode" "DI")])
7401 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7402 (define_expand "umulsidi3"
7403 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7404 (mult:DI (zero_extend:DI
7405 (match_operand:SI 1 "nonimmediate_operand" ""))
7407 (match_operand:SI 2 "register_operand" ""))))
7408 (clobber (reg:CC FLAGS_REG))])]
7412 (define_insn "*umulsidi3_insn"
7413 [(set (match_operand:DI 0 "register_operand" "=A")
7414 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7415 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7416 (clobber (reg:CC FLAGS_REG))]
7418 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7420 [(set_attr "type" "imul")
7421 (set_attr "length_immediate" "0")
7422 (set (attr "athlon_decode")
7423 (if_then_else (eq_attr "cpu" "athlon")
7424 (const_string "vector")
7425 (const_string "double")))
7426 (set_attr "amdfam10_decode" "double")
7427 (set_attr "mode" "SI")])
7429 (define_expand "mulditi3"
7430 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7431 (mult:TI (sign_extend:TI
7432 (match_operand:DI 1 "nonimmediate_operand" ""))
7434 (match_operand:DI 2 "register_operand" ""))))
7435 (clobber (reg:CC FLAGS_REG))])]
7439 (define_insn "*mulditi3_insn"
7440 [(set (match_operand:TI 0 "register_operand" "=A")
7441 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7442 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7443 (clobber (reg:CC FLAGS_REG))]
7445 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7447 [(set_attr "type" "imul")
7448 (set_attr "length_immediate" "0")
7449 (set (attr "athlon_decode")
7450 (if_then_else (eq_attr "cpu" "athlon")
7451 (const_string "vector")
7452 (const_string "double")))
7453 (set_attr "amdfam10_decode" "double")
7454 (set_attr "mode" "DI")])
7456 (define_expand "mulsidi3"
7457 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7458 (mult:DI (sign_extend:DI
7459 (match_operand:SI 1 "nonimmediate_operand" ""))
7461 (match_operand:SI 2 "register_operand" ""))))
7462 (clobber (reg:CC FLAGS_REG))])]
7466 (define_insn "*mulsidi3_insn"
7467 [(set (match_operand:DI 0 "register_operand" "=A")
7468 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7469 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7470 (clobber (reg:CC FLAGS_REG))]
7472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7474 [(set_attr "type" "imul")
7475 (set_attr "length_immediate" "0")
7476 (set (attr "athlon_decode")
7477 (if_then_else (eq_attr "cpu" "athlon")
7478 (const_string "vector")
7479 (const_string "double")))
7480 (set_attr "amdfam10_decode" "double")
7481 (set_attr "mode" "SI")])
7483 (define_expand "umuldi3_highpart"
7484 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7487 (mult:TI (zero_extend:TI
7488 (match_operand:DI 1 "nonimmediate_operand" ""))
7490 (match_operand:DI 2 "register_operand" "")))
7492 (clobber (match_scratch:DI 3 ""))
7493 (clobber (reg:CC FLAGS_REG))])]
7497 (define_insn "*umuldi3_highpart_rex64"
7498 [(set (match_operand:DI 0 "register_operand" "=d")
7501 (mult:TI (zero_extend:TI
7502 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7504 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7506 (clobber (match_scratch:DI 3 "=1"))
7507 (clobber (reg:CC FLAGS_REG))]
7509 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7511 [(set_attr "type" "imul")
7512 (set_attr "length_immediate" "0")
7513 (set (attr "athlon_decode")
7514 (if_then_else (eq_attr "cpu" "athlon")
7515 (const_string "vector")
7516 (const_string "double")))
7517 (set_attr "amdfam10_decode" "double")
7518 (set_attr "mode" "DI")])
7520 (define_expand "umulsi3_highpart"
7521 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7524 (mult:DI (zero_extend:DI
7525 (match_operand:SI 1 "nonimmediate_operand" ""))
7527 (match_operand:SI 2 "register_operand" "")))
7529 (clobber (match_scratch:SI 3 ""))
7530 (clobber (reg:CC FLAGS_REG))])]
7534 (define_insn "*umulsi3_highpart_insn"
7535 [(set (match_operand:SI 0 "register_operand" "=d")
7538 (mult:DI (zero_extend:DI
7539 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7541 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7543 (clobber (match_scratch:SI 3 "=1"))
7544 (clobber (reg:CC FLAGS_REG))]
7545 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7547 [(set_attr "type" "imul")
7548 (set_attr "length_immediate" "0")
7549 (set (attr "athlon_decode")
7550 (if_then_else (eq_attr "cpu" "athlon")
7551 (const_string "vector")
7552 (const_string "double")))
7553 (set_attr "amdfam10_decode" "double")
7554 (set_attr "mode" "SI")])
7556 (define_insn "*umulsi3_highpart_zext"
7557 [(set (match_operand:DI 0 "register_operand" "=d")
7558 (zero_extend:DI (truncate:SI
7560 (mult:DI (zero_extend:DI
7561 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7563 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7565 (clobber (match_scratch:SI 3 "=1"))
7566 (clobber (reg:CC FLAGS_REG))]
7568 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7570 [(set_attr "type" "imul")
7571 (set_attr "length_immediate" "0")
7572 (set (attr "athlon_decode")
7573 (if_then_else (eq_attr "cpu" "athlon")
7574 (const_string "vector")
7575 (const_string "double")))
7576 (set_attr "amdfam10_decode" "double")
7577 (set_attr "mode" "SI")])
7579 (define_expand "smuldi3_highpart"
7580 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7583 (mult:TI (sign_extend:TI
7584 (match_operand:DI 1 "nonimmediate_operand" ""))
7586 (match_operand:DI 2 "register_operand" "")))
7588 (clobber (match_scratch:DI 3 ""))
7589 (clobber (reg:CC FLAGS_REG))])]
7593 (define_insn "*smuldi3_highpart_rex64"
7594 [(set (match_operand:DI 0 "register_operand" "=d")
7597 (mult:TI (sign_extend:TI
7598 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7600 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7602 (clobber (match_scratch:DI 3 "=1"))
7603 (clobber (reg:CC FLAGS_REG))]
7605 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7607 [(set_attr "type" "imul")
7608 (set (attr "athlon_decode")
7609 (if_then_else (eq_attr "cpu" "athlon")
7610 (const_string "vector")
7611 (const_string "double")))
7612 (set_attr "amdfam10_decode" "double")
7613 (set_attr "mode" "DI")])
7615 (define_expand "smulsi3_highpart"
7616 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7619 (mult:DI (sign_extend:DI
7620 (match_operand:SI 1 "nonimmediate_operand" ""))
7622 (match_operand:SI 2 "register_operand" "")))
7624 (clobber (match_scratch:SI 3 ""))
7625 (clobber (reg:CC FLAGS_REG))])]
7629 (define_insn "*smulsi3_highpart_insn"
7630 [(set (match_operand:SI 0 "register_operand" "=d")
7633 (mult:DI (sign_extend:DI
7634 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7636 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7638 (clobber (match_scratch:SI 3 "=1"))
7639 (clobber (reg:CC FLAGS_REG))]
7640 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7642 [(set_attr "type" "imul")
7643 (set (attr "athlon_decode")
7644 (if_then_else (eq_attr "cpu" "athlon")
7645 (const_string "vector")
7646 (const_string "double")))
7647 (set_attr "amdfam10_decode" "double")
7648 (set_attr "mode" "SI")])
7650 (define_insn "*smulsi3_highpart_zext"
7651 [(set (match_operand:DI 0 "register_operand" "=d")
7652 (zero_extend:DI (truncate:SI
7654 (mult:DI (sign_extend:DI
7655 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7657 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7659 (clobber (match_scratch:SI 3 "=1"))
7660 (clobber (reg:CC FLAGS_REG))]
7662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7664 [(set_attr "type" "imul")
7665 (set (attr "athlon_decode")
7666 (if_then_else (eq_attr "cpu" "athlon")
7667 (const_string "vector")
7668 (const_string "double")))
7669 (set_attr "amdfam10_decode" "double")
7670 (set_attr "mode" "SI")])
7672 ;; The patterns that match these are at the end of this file.
7674 (define_expand "mulxf3"
7675 [(set (match_operand:XF 0 "register_operand" "")
7676 (mult:XF (match_operand:XF 1 "register_operand" "")
7677 (match_operand:XF 2 "register_operand" "")))]
7681 (define_expand "muldf3"
7682 [(set (match_operand:DF 0 "register_operand" "")
7683 (mult:DF (match_operand:DF 1 "register_operand" "")
7684 (match_operand:DF 2 "nonimmediate_operand" "")))]
7685 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7688 (define_expand "mulsf3"
7689 [(set (match_operand:SF 0 "register_operand" "")
7690 (mult:SF (match_operand:SF 1 "register_operand" "")
7691 (match_operand:SF 2 "nonimmediate_operand" "")))]
7692 "TARGET_80387 || TARGET_SSE_MATH"
7695 ;; Divide instructions
7697 (define_insn "divqi3"
7698 [(set (match_operand:QI 0 "register_operand" "=a")
7699 (div:QI (match_operand:HI 1 "register_operand" "0")
7700 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7701 (clobber (reg:CC FLAGS_REG))]
7702 "TARGET_QIMODE_MATH"
7704 [(set_attr "type" "idiv")
7705 (set_attr "mode" "QI")])
7707 (define_insn "udivqi3"
7708 [(set (match_operand:QI 0 "register_operand" "=a")
7709 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7710 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7711 (clobber (reg:CC FLAGS_REG))]
7712 "TARGET_QIMODE_MATH"
7714 [(set_attr "type" "idiv")
7715 (set_attr "mode" "QI")])
7717 ;; The patterns that match these are at the end of this file.
7719 (define_expand "divxf3"
7720 [(set (match_operand:XF 0 "register_operand" "")
7721 (div:XF (match_operand:XF 1 "register_operand" "")
7722 (match_operand:XF 2 "register_operand" "")))]
7726 (define_expand "divdf3"
7727 [(set (match_operand:DF 0 "register_operand" "")
7728 (div:DF (match_operand:DF 1 "register_operand" "")
7729 (match_operand:DF 2 "nonimmediate_operand" "")))]
7730 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7733 (define_expand "divsf3"
7734 [(set (match_operand:SF 0 "register_operand" "")
7735 (div:SF (match_operand:SF 1 "register_operand" "")
7736 (match_operand:SF 2 "nonimmediate_operand" "")))]
7737 "TARGET_80387 || TARGET_SSE_MATH"
7740 ;; Remainder instructions.
7742 (define_expand "divmoddi4"
7743 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7744 (div:DI (match_operand:DI 1 "register_operand" "")
7745 (match_operand:DI 2 "nonimmediate_operand" "")))
7746 (set (match_operand:DI 3 "register_operand" "")
7747 (mod:DI (match_dup 1) (match_dup 2)))
7748 (clobber (reg:CC FLAGS_REG))])]
7752 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7753 ;; Penalize eax case slightly because it results in worse scheduling
7755 (define_insn "*divmoddi4_nocltd_rex64"
7756 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7757 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7758 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7759 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7760 (mod:DI (match_dup 2) (match_dup 3)))
7761 (clobber (reg:CC FLAGS_REG))]
7762 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7764 [(set_attr "type" "multi")])
7766 (define_insn "*divmoddi4_cltd_rex64"
7767 [(set (match_operand:DI 0 "register_operand" "=a")
7768 (div:DI (match_operand:DI 2 "register_operand" "a")
7769 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7770 (set (match_operand:DI 1 "register_operand" "=&d")
7771 (mod:DI (match_dup 2) (match_dup 3)))
7772 (clobber (reg:CC FLAGS_REG))]
7773 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7775 [(set_attr "type" "multi")])
7777 (define_insn "*divmoddi_noext_rex64"
7778 [(set (match_operand:DI 0 "register_operand" "=a")
7779 (div:DI (match_operand:DI 1 "register_operand" "0")
7780 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7781 (set (match_operand:DI 3 "register_operand" "=d")
7782 (mod:DI (match_dup 1) (match_dup 2)))
7783 (use (match_operand:DI 4 "register_operand" "3"))
7784 (clobber (reg:CC FLAGS_REG))]
7787 [(set_attr "type" "idiv")
7788 (set_attr "mode" "DI")])
7791 [(set (match_operand:DI 0 "register_operand" "")
7792 (div:DI (match_operand:DI 1 "register_operand" "")
7793 (match_operand:DI 2 "nonimmediate_operand" "")))
7794 (set (match_operand:DI 3 "register_operand" "")
7795 (mod:DI (match_dup 1) (match_dup 2)))
7796 (clobber (reg:CC FLAGS_REG))]
7797 "TARGET_64BIT && reload_completed"
7798 [(parallel [(set (match_dup 3)
7799 (ashiftrt:DI (match_dup 4) (const_int 63)))
7800 (clobber (reg:CC FLAGS_REG))])
7801 (parallel [(set (match_dup 0)
7802 (div:DI (reg:DI 0) (match_dup 2)))
7804 (mod:DI (reg:DI 0) (match_dup 2)))
7806 (clobber (reg:CC FLAGS_REG))])]
7808 /* Avoid use of cltd in favor of a mov+shift. */
7809 if (!TARGET_USE_CLTD && !optimize_size)
7811 if (true_regnum (operands[1]))
7812 emit_move_insn (operands[0], operands[1]);
7814 emit_move_insn (operands[3], operands[1]);
7815 operands[4] = operands[3];
7819 gcc_assert (!true_regnum (operands[1]));
7820 operands[4] = operands[1];
7825 (define_expand "divmodsi4"
7826 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7827 (div:SI (match_operand:SI 1 "register_operand" "")
7828 (match_operand:SI 2 "nonimmediate_operand" "")))
7829 (set (match_operand:SI 3 "register_operand" "")
7830 (mod:SI (match_dup 1) (match_dup 2)))
7831 (clobber (reg:CC FLAGS_REG))])]
7835 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7836 ;; Penalize eax case slightly because it results in worse scheduling
7838 (define_insn "*divmodsi4_nocltd"
7839 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7840 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7841 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7842 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7843 (mod:SI (match_dup 2) (match_dup 3)))
7844 (clobber (reg:CC FLAGS_REG))]
7845 "!optimize_size && !TARGET_USE_CLTD"
7847 [(set_attr "type" "multi")])
7849 (define_insn "*divmodsi4_cltd"
7850 [(set (match_operand:SI 0 "register_operand" "=a")
7851 (div:SI (match_operand:SI 2 "register_operand" "a")
7852 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7853 (set (match_operand:SI 1 "register_operand" "=&d")
7854 (mod:SI (match_dup 2) (match_dup 3)))
7855 (clobber (reg:CC FLAGS_REG))]
7856 "optimize_size || TARGET_USE_CLTD"
7858 [(set_attr "type" "multi")])
7860 (define_insn "*divmodsi_noext"
7861 [(set (match_operand:SI 0 "register_operand" "=a")
7862 (div:SI (match_operand:SI 1 "register_operand" "0")
7863 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7864 (set (match_operand:SI 3 "register_operand" "=d")
7865 (mod:SI (match_dup 1) (match_dup 2)))
7866 (use (match_operand:SI 4 "register_operand" "3"))
7867 (clobber (reg:CC FLAGS_REG))]
7870 [(set_attr "type" "idiv")
7871 (set_attr "mode" "SI")])
7874 [(set (match_operand:SI 0 "register_operand" "")
7875 (div:SI (match_operand:SI 1 "register_operand" "")
7876 (match_operand:SI 2 "nonimmediate_operand" "")))
7877 (set (match_operand:SI 3 "register_operand" "")
7878 (mod:SI (match_dup 1) (match_dup 2)))
7879 (clobber (reg:CC FLAGS_REG))]
7881 [(parallel [(set (match_dup 3)
7882 (ashiftrt:SI (match_dup 4) (const_int 31)))
7883 (clobber (reg:CC FLAGS_REG))])
7884 (parallel [(set (match_dup 0)
7885 (div:SI (reg:SI 0) (match_dup 2)))
7887 (mod:SI (reg:SI 0) (match_dup 2)))
7889 (clobber (reg:CC FLAGS_REG))])]
7891 /* Avoid use of cltd in favor of a mov+shift. */
7892 if (!TARGET_USE_CLTD && !optimize_size)
7894 if (true_regnum (operands[1]))
7895 emit_move_insn (operands[0], operands[1]);
7897 emit_move_insn (operands[3], operands[1]);
7898 operands[4] = operands[3];
7902 gcc_assert (!true_regnum (operands[1]));
7903 operands[4] = operands[1];
7907 (define_insn "divmodhi4"
7908 [(set (match_operand:HI 0 "register_operand" "=a")
7909 (div:HI (match_operand:HI 1 "register_operand" "0")
7910 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7911 (set (match_operand:HI 3 "register_operand" "=&d")
7912 (mod:HI (match_dup 1) (match_dup 2)))
7913 (clobber (reg:CC FLAGS_REG))]
7914 "TARGET_HIMODE_MATH"
7916 [(set_attr "type" "multi")
7917 (set_attr "length_immediate" "0")
7918 (set_attr "mode" "SI")])
7920 (define_insn "udivmoddi4"
7921 [(set (match_operand:DI 0 "register_operand" "=a")
7922 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7923 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7924 (set (match_operand:DI 3 "register_operand" "=&d")
7925 (umod:DI (match_dup 1) (match_dup 2)))
7926 (clobber (reg:CC FLAGS_REG))]
7928 "xor{q}\t%3, %3\;div{q}\t%2"
7929 [(set_attr "type" "multi")
7930 (set_attr "length_immediate" "0")
7931 (set_attr "mode" "DI")])
7933 (define_insn "*udivmoddi4_noext"
7934 [(set (match_operand:DI 0 "register_operand" "=a")
7935 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7936 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7937 (set (match_operand:DI 3 "register_operand" "=d")
7938 (umod:DI (match_dup 1) (match_dup 2)))
7940 (clobber (reg:CC FLAGS_REG))]
7943 [(set_attr "type" "idiv")
7944 (set_attr "mode" "DI")])
7947 [(set (match_operand:DI 0 "register_operand" "")
7948 (udiv:DI (match_operand:DI 1 "register_operand" "")
7949 (match_operand:DI 2 "nonimmediate_operand" "")))
7950 (set (match_operand:DI 3 "register_operand" "")
7951 (umod:DI (match_dup 1) (match_dup 2)))
7952 (clobber (reg:CC FLAGS_REG))]
7953 "TARGET_64BIT && reload_completed"
7954 [(set (match_dup 3) (const_int 0))
7955 (parallel [(set (match_dup 0)
7956 (udiv:DI (match_dup 1) (match_dup 2)))
7958 (umod:DI (match_dup 1) (match_dup 2)))
7960 (clobber (reg:CC FLAGS_REG))])]
7963 (define_insn "udivmodsi4"
7964 [(set (match_operand:SI 0 "register_operand" "=a")
7965 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7966 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7967 (set (match_operand:SI 3 "register_operand" "=&d")
7968 (umod:SI (match_dup 1) (match_dup 2)))
7969 (clobber (reg:CC FLAGS_REG))]
7971 "xor{l}\t%3, %3\;div{l}\t%2"
7972 [(set_attr "type" "multi")
7973 (set_attr "length_immediate" "0")
7974 (set_attr "mode" "SI")])
7976 (define_insn "*udivmodsi4_noext"
7977 [(set (match_operand:SI 0 "register_operand" "=a")
7978 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7979 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7980 (set (match_operand:SI 3 "register_operand" "=d")
7981 (umod:SI (match_dup 1) (match_dup 2)))
7983 (clobber (reg:CC FLAGS_REG))]
7986 [(set_attr "type" "idiv")
7987 (set_attr "mode" "SI")])
7990 [(set (match_operand:SI 0 "register_operand" "")
7991 (udiv:SI (match_operand:SI 1 "register_operand" "")
7992 (match_operand:SI 2 "nonimmediate_operand" "")))
7993 (set (match_operand:SI 3 "register_operand" "")
7994 (umod:SI (match_dup 1) (match_dup 2)))
7995 (clobber (reg:CC FLAGS_REG))]
7997 [(set (match_dup 3) (const_int 0))
7998 (parallel [(set (match_dup 0)
7999 (udiv:SI (match_dup 1) (match_dup 2)))
8001 (umod:SI (match_dup 1) (match_dup 2)))
8003 (clobber (reg:CC FLAGS_REG))])]
8006 (define_expand "udivmodhi4"
8007 [(set (match_dup 4) (const_int 0))
8008 (parallel [(set (match_operand:HI 0 "register_operand" "")
8009 (udiv:HI (match_operand:HI 1 "register_operand" "")
8010 (match_operand:HI 2 "nonimmediate_operand" "")))
8011 (set (match_operand:HI 3 "register_operand" "")
8012 (umod:HI (match_dup 1) (match_dup 2)))
8014 (clobber (reg:CC FLAGS_REG))])]
8015 "TARGET_HIMODE_MATH"
8016 "operands[4] = gen_reg_rtx (HImode);")
8018 (define_insn "*udivmodhi_noext"
8019 [(set (match_operand:HI 0 "register_operand" "=a")
8020 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8021 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8022 (set (match_operand:HI 3 "register_operand" "=d")
8023 (umod:HI (match_dup 1) (match_dup 2)))
8024 (use (match_operand:HI 4 "register_operand" "3"))
8025 (clobber (reg:CC FLAGS_REG))]
8028 [(set_attr "type" "idiv")
8029 (set_attr "mode" "HI")])
8031 ;; We cannot use div/idiv for double division, because it causes
8032 ;; "division by zero" on the overflow and that's not what we expect
8033 ;; from truncate. Because true (non truncating) double division is
8034 ;; never generated, we can't create this insn anyway.
8037 ; [(set (match_operand:SI 0 "register_operand" "=a")
8039 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8041 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8042 ; (set (match_operand:SI 3 "register_operand" "=d")
8044 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8045 ; (clobber (reg:CC FLAGS_REG))]
8047 ; "div{l}\t{%2, %0|%0, %2}"
8048 ; [(set_attr "type" "idiv")])
8050 ;;- Logical AND instructions
8052 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8053 ;; Note that this excludes ah.
8055 (define_insn "*testdi_1_rex64"
8056 [(set (reg FLAGS_REG)
8058 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8059 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8061 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8062 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8064 test{l}\t{%k1, %k0|%k0, %k1}
8065 test{l}\t{%k1, %k0|%k0, %k1}
8066 test{q}\t{%1, %0|%0, %1}
8067 test{q}\t{%1, %0|%0, %1}
8068 test{q}\t{%1, %0|%0, %1}"
8069 [(set_attr "type" "test")
8070 (set_attr "modrm" "0,1,0,1,1")
8071 (set_attr "mode" "SI,SI,DI,DI,DI")
8072 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8074 (define_insn "testsi_1"
8075 [(set (reg FLAGS_REG)
8077 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8078 (match_operand:SI 1 "general_operand" "in,in,rin"))
8080 "ix86_match_ccmode (insn, CCNOmode)
8081 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8082 "test{l}\t{%1, %0|%0, %1}"
8083 [(set_attr "type" "test")
8084 (set_attr "modrm" "0,1,1")
8085 (set_attr "mode" "SI")
8086 (set_attr "pent_pair" "uv,np,uv")])
8088 (define_expand "testsi_ccno_1"
8089 [(set (reg:CCNO FLAGS_REG)
8091 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8092 (match_operand:SI 1 "nonmemory_operand" ""))
8097 (define_insn "*testhi_1"
8098 [(set (reg FLAGS_REG)
8099 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8100 (match_operand:HI 1 "general_operand" "n,n,rn"))
8102 "ix86_match_ccmode (insn, CCNOmode)
8103 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8104 "test{w}\t{%1, %0|%0, %1}"
8105 [(set_attr "type" "test")
8106 (set_attr "modrm" "0,1,1")
8107 (set_attr "mode" "HI")
8108 (set_attr "pent_pair" "uv,np,uv")])
8110 (define_expand "testqi_ccz_1"
8111 [(set (reg:CCZ FLAGS_REG)
8112 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8113 (match_operand:QI 1 "nonmemory_operand" ""))
8118 (define_insn "*testqi_1_maybe_si"
8119 [(set (reg FLAGS_REG)
8122 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8123 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8125 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8126 && ix86_match_ccmode (insn,
8127 CONST_INT_P (operands[1])
8128 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8130 if (which_alternative == 3)
8132 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8133 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8134 return "test{l}\t{%1, %k0|%k0, %1}";
8136 return "test{b}\t{%1, %0|%0, %1}";
8138 [(set_attr "type" "test")
8139 (set_attr "modrm" "0,1,1,1")
8140 (set_attr "mode" "QI,QI,QI,SI")
8141 (set_attr "pent_pair" "uv,np,uv,np")])
8143 (define_insn "*testqi_1"
8144 [(set (reg FLAGS_REG)
8147 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8148 (match_operand:QI 1 "general_operand" "n,n,qn"))
8150 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8151 && ix86_match_ccmode (insn, CCNOmode)"
8152 "test{b}\t{%1, %0|%0, %1}"
8153 [(set_attr "type" "test")
8154 (set_attr "modrm" "0,1,1")
8155 (set_attr "mode" "QI")
8156 (set_attr "pent_pair" "uv,np,uv")])
8158 (define_expand "testqi_ext_ccno_0"
8159 [(set (reg:CCNO FLAGS_REG)
8163 (match_operand 0 "ext_register_operand" "")
8166 (match_operand 1 "const_int_operand" ""))
8171 (define_insn "*testqi_ext_0"
8172 [(set (reg FLAGS_REG)
8176 (match_operand 0 "ext_register_operand" "Q")
8179 (match_operand 1 "const_int_operand" "n"))
8181 "ix86_match_ccmode (insn, CCNOmode)"
8182 "test{b}\t{%1, %h0|%h0, %1}"
8183 [(set_attr "type" "test")
8184 (set_attr "mode" "QI")
8185 (set_attr "length_immediate" "1")
8186 (set_attr "pent_pair" "np")])
8188 (define_insn "*testqi_ext_1"
8189 [(set (reg FLAGS_REG)
8193 (match_operand 0 "ext_register_operand" "Q")
8197 (match_operand:QI 1 "general_operand" "Qm")))
8199 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8200 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8201 "test{b}\t{%1, %h0|%h0, %1}"
8202 [(set_attr "type" "test")
8203 (set_attr "mode" "QI")])
8205 (define_insn "*testqi_ext_1_rex64"
8206 [(set (reg FLAGS_REG)
8210 (match_operand 0 "ext_register_operand" "Q")
8214 (match_operand:QI 1 "register_operand" "Q")))
8216 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8217 "test{b}\t{%1, %h0|%h0, %1}"
8218 [(set_attr "type" "test")
8219 (set_attr "mode" "QI")])
8221 (define_insn "*testqi_ext_2"
8222 [(set (reg FLAGS_REG)
8226 (match_operand 0 "ext_register_operand" "Q")
8230 (match_operand 1 "ext_register_operand" "Q")
8234 "ix86_match_ccmode (insn, CCNOmode)"
8235 "test{b}\t{%h1, %h0|%h0, %h1}"
8236 [(set_attr "type" "test")
8237 (set_attr "mode" "QI")])
8239 ;; Combine likes to form bit extractions for some tests. Humor it.
8240 (define_insn "*testqi_ext_3"
8241 [(set (reg FLAGS_REG)
8242 (compare (zero_extract:SI
8243 (match_operand 0 "nonimmediate_operand" "rm")
8244 (match_operand:SI 1 "const_int_operand" "")
8245 (match_operand:SI 2 "const_int_operand" ""))
8247 "ix86_match_ccmode (insn, CCNOmode)
8248 && INTVAL (operands[1]) > 0
8249 && INTVAL (operands[2]) >= 0
8250 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8251 && (GET_MODE (operands[0]) == SImode
8252 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8253 || GET_MODE (operands[0]) == HImode
8254 || GET_MODE (operands[0]) == QImode)"
8257 (define_insn "*testqi_ext_3_rex64"
8258 [(set (reg FLAGS_REG)
8259 (compare (zero_extract:DI
8260 (match_operand 0 "nonimmediate_operand" "rm")
8261 (match_operand:DI 1 "const_int_operand" "")
8262 (match_operand:DI 2 "const_int_operand" ""))
8265 && ix86_match_ccmode (insn, CCNOmode)
8266 && INTVAL (operands[1]) > 0
8267 && INTVAL (operands[2]) >= 0
8268 /* Ensure that resulting mask is zero or sign extended operand. */
8269 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8270 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8271 && INTVAL (operands[1]) > 32))
8272 && (GET_MODE (operands[0]) == SImode
8273 || GET_MODE (operands[0]) == DImode
8274 || GET_MODE (operands[0]) == HImode
8275 || GET_MODE (operands[0]) == QImode)"
8279 [(set (match_operand 0 "flags_reg_operand" "")
8280 (match_operator 1 "compare_operator"
8282 (match_operand 2 "nonimmediate_operand" "")
8283 (match_operand 3 "const_int_operand" "")
8284 (match_operand 4 "const_int_operand" ""))
8286 "ix86_match_ccmode (insn, CCNOmode)"
8287 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8289 rtx val = operands[2];
8290 HOST_WIDE_INT len = INTVAL (operands[3]);
8291 HOST_WIDE_INT pos = INTVAL (operands[4]);
8293 enum machine_mode mode, submode;
8295 mode = GET_MODE (val);
8298 /* ??? Combine likes to put non-volatile mem extractions in QImode
8299 no matter the size of the test. So find a mode that works. */
8300 if (! MEM_VOLATILE_P (val))
8302 mode = smallest_mode_for_size (pos + len, MODE_INT);
8303 val = adjust_address (val, mode, 0);
8306 else if (GET_CODE (val) == SUBREG
8307 && (submode = GET_MODE (SUBREG_REG (val)),
8308 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8309 && pos + len <= GET_MODE_BITSIZE (submode))
8311 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8313 val = SUBREG_REG (val);
8315 else if (mode == HImode && pos + len <= 8)
8317 /* Small HImode tests can be converted to QImode. */
8319 val = gen_lowpart (QImode, val);
8322 if (len == HOST_BITS_PER_WIDE_INT)
8325 mask = ((HOST_WIDE_INT)1 << len) - 1;
8328 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8331 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8332 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8333 ;; this is relatively important trick.
8334 ;; Do the conversion only post-reload to avoid limiting of the register class
8337 [(set (match_operand 0 "flags_reg_operand" "")
8338 (match_operator 1 "compare_operator"
8339 [(and (match_operand 2 "register_operand" "")
8340 (match_operand 3 "const_int_operand" ""))
8343 && QI_REG_P (operands[2])
8344 && GET_MODE (operands[2]) != QImode
8345 && ((ix86_match_ccmode (insn, CCZmode)
8346 && !(INTVAL (operands[3]) & ~(255 << 8)))
8347 || (ix86_match_ccmode (insn, CCNOmode)
8348 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8351 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8354 "operands[2] = gen_lowpart (SImode, operands[2]);
8355 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8358 [(set (match_operand 0 "flags_reg_operand" "")
8359 (match_operator 1 "compare_operator"
8360 [(and (match_operand 2 "nonimmediate_operand" "")
8361 (match_operand 3 "const_int_operand" ""))
8364 && GET_MODE (operands[2]) != QImode
8365 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8366 && ((ix86_match_ccmode (insn, CCZmode)
8367 && !(INTVAL (operands[3]) & ~255))
8368 || (ix86_match_ccmode (insn, CCNOmode)
8369 && !(INTVAL (operands[3]) & ~127)))"
8371 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8373 "operands[2] = gen_lowpart (QImode, operands[2]);
8374 operands[3] = gen_lowpart (QImode, operands[3]);")
8377 ;; %%% This used to optimize known byte-wide and operations to memory,
8378 ;; and sometimes to QImode registers. If this is considered useful,
8379 ;; it should be done with splitters.
8381 (define_expand "anddi3"
8382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8383 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8384 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8385 (clobber (reg:CC FLAGS_REG))]
8387 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8389 (define_insn "*anddi_1_rex64"
8390 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8391 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8392 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8396 switch (get_attr_type (insn))
8400 enum machine_mode mode;
8402 gcc_assert (CONST_INT_P (operands[2]));
8403 if (INTVAL (operands[2]) == 0xff)
8407 gcc_assert (INTVAL (operands[2]) == 0xffff);
8411 operands[1] = gen_lowpart (mode, operands[1]);
8413 return "movz{bq|x}\t{%1,%0|%0, %1}";
8415 return "movz{wq|x}\t{%1,%0|%0, %1}";
8419 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8420 if (get_attr_mode (insn) == MODE_SI)
8421 return "and{l}\t{%k2, %k0|%k0, %k2}";
8423 return "and{q}\t{%2, %0|%0, %2}";
8426 [(set_attr "type" "alu,alu,alu,imovx")
8427 (set_attr "length_immediate" "*,*,*,0")
8428 (set_attr "mode" "SI,DI,DI,DI")])
8430 (define_insn "*anddi_2"
8431 [(set (reg FLAGS_REG)
8432 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8433 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8435 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8436 (and:DI (match_dup 1) (match_dup 2)))]
8437 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8438 && ix86_binary_operator_ok (AND, DImode, operands)"
8440 and{l}\t{%k2, %k0|%k0, %k2}
8441 and{q}\t{%2, %0|%0, %2}
8442 and{q}\t{%2, %0|%0, %2}"
8443 [(set_attr "type" "alu")
8444 (set_attr "mode" "SI,DI,DI")])
8446 (define_expand "andsi3"
8447 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8448 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8449 (match_operand:SI 2 "general_operand" "")))
8450 (clobber (reg:CC FLAGS_REG))]
8452 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8454 (define_insn "*andsi_1"
8455 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8456 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8457 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8458 (clobber (reg:CC FLAGS_REG))]
8459 "ix86_binary_operator_ok (AND, SImode, operands)"
8461 switch (get_attr_type (insn))
8465 enum machine_mode mode;
8467 gcc_assert (CONST_INT_P (operands[2]));
8468 if (INTVAL (operands[2]) == 0xff)
8472 gcc_assert (INTVAL (operands[2]) == 0xffff);
8476 operands[1] = gen_lowpart (mode, operands[1]);
8478 return "movz{bl|x}\t{%1,%0|%0, %1}";
8480 return "movz{wl|x}\t{%1,%0|%0, %1}";
8484 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8485 return "and{l}\t{%2, %0|%0, %2}";
8488 [(set_attr "type" "alu,alu,imovx")
8489 (set_attr "length_immediate" "*,*,0")
8490 (set_attr "mode" "SI")])
8493 [(set (match_operand 0 "register_operand" "")
8495 (const_int -65536)))
8496 (clobber (reg:CC FLAGS_REG))]
8497 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8498 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8499 "operands[1] = gen_lowpart (HImode, operands[0]);")
8502 [(set (match_operand 0 "ext_register_operand" "")
8505 (clobber (reg:CC FLAGS_REG))]
8506 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8507 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8508 "operands[1] = gen_lowpart (QImode, operands[0]);")
8511 [(set (match_operand 0 "ext_register_operand" "")
8513 (const_int -65281)))
8514 (clobber (reg:CC FLAGS_REG))]
8515 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8516 [(parallel [(set (zero_extract:SI (match_dup 0)
8520 (zero_extract:SI (match_dup 0)
8523 (zero_extract:SI (match_dup 0)
8526 (clobber (reg:CC FLAGS_REG))])]
8527 "operands[0] = gen_lowpart (SImode, operands[0]);")
8529 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8530 (define_insn "*andsi_1_zext"
8531 [(set (match_operand:DI 0 "register_operand" "=r")
8533 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8534 (match_operand:SI 2 "general_operand" "rim"))))
8535 (clobber (reg:CC FLAGS_REG))]
8536 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8537 "and{l}\t{%2, %k0|%k0, %2}"
8538 [(set_attr "type" "alu")
8539 (set_attr "mode" "SI")])
8541 (define_insn "*andsi_2"
8542 [(set (reg FLAGS_REG)
8543 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8544 (match_operand:SI 2 "general_operand" "rim,ri"))
8546 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8547 (and:SI (match_dup 1) (match_dup 2)))]
8548 "ix86_match_ccmode (insn, CCNOmode)
8549 && ix86_binary_operator_ok (AND, SImode, operands)"
8550 "and{l}\t{%2, %0|%0, %2}"
8551 [(set_attr "type" "alu")
8552 (set_attr "mode" "SI")])
8554 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8555 (define_insn "*andsi_2_zext"
8556 [(set (reg FLAGS_REG)
8557 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8558 (match_operand:SI 2 "general_operand" "rim"))
8560 (set (match_operand:DI 0 "register_operand" "=r")
8561 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8562 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8563 && ix86_binary_operator_ok (AND, SImode, operands)"
8564 "and{l}\t{%2, %k0|%k0, %2}"
8565 [(set_attr "type" "alu")
8566 (set_attr "mode" "SI")])
8568 (define_expand "andhi3"
8569 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8570 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8571 (match_operand:HI 2 "general_operand" "")))
8572 (clobber (reg:CC FLAGS_REG))]
8573 "TARGET_HIMODE_MATH"
8574 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8576 (define_insn "*andhi_1"
8577 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8578 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8579 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "ix86_binary_operator_ok (AND, HImode, operands)"
8583 switch (get_attr_type (insn))
8586 gcc_assert (CONST_INT_P (operands[2]));
8587 gcc_assert (INTVAL (operands[2]) == 0xff);
8588 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8593 return "and{w}\t{%2, %0|%0, %2}";
8596 [(set_attr "type" "alu,alu,imovx")
8597 (set_attr "length_immediate" "*,*,0")
8598 (set_attr "mode" "HI,HI,SI")])
8600 (define_insn "*andhi_2"
8601 [(set (reg FLAGS_REG)
8602 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8603 (match_operand:HI 2 "general_operand" "rim,ri"))
8605 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8606 (and:HI (match_dup 1) (match_dup 2)))]
8607 "ix86_match_ccmode (insn, CCNOmode)
8608 && ix86_binary_operator_ok (AND, HImode, operands)"
8609 "and{w}\t{%2, %0|%0, %2}"
8610 [(set_attr "type" "alu")
8611 (set_attr "mode" "HI")])
8613 (define_expand "andqi3"
8614 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8615 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8616 (match_operand:QI 2 "general_operand" "")))
8617 (clobber (reg:CC FLAGS_REG))]
8618 "TARGET_QIMODE_MATH"
8619 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8621 ;; %%% Potential partial reg stall on alternative 2. What to do?
8622 (define_insn "*andqi_1"
8623 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8624 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8625 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8626 (clobber (reg:CC FLAGS_REG))]
8627 "ix86_binary_operator_ok (AND, QImode, operands)"
8629 and{b}\t{%2, %0|%0, %2}
8630 and{b}\t{%2, %0|%0, %2}
8631 and{l}\t{%k2, %k0|%k0, %k2}"
8632 [(set_attr "type" "alu")
8633 (set_attr "mode" "QI,QI,SI")])
8635 (define_insn "*andqi_1_slp"
8636 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8637 (and:QI (match_dup 0)
8638 (match_operand:QI 1 "general_operand" "qi,qmi")))
8639 (clobber (reg:CC FLAGS_REG))]
8640 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8641 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8642 "and{b}\t{%1, %0|%0, %1}"
8643 [(set_attr "type" "alu1")
8644 (set_attr "mode" "QI")])
8646 (define_insn "*andqi_2_maybe_si"
8647 [(set (reg FLAGS_REG)
8649 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8650 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8652 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8653 (and:QI (match_dup 1) (match_dup 2)))]
8654 "ix86_binary_operator_ok (AND, QImode, operands)
8655 && ix86_match_ccmode (insn,
8656 CONST_INT_P (operands[2])
8657 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8659 if (which_alternative == 2)
8661 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8662 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8663 return "and{l}\t{%2, %k0|%k0, %2}";
8665 return "and{b}\t{%2, %0|%0, %2}";
8667 [(set_attr "type" "alu")
8668 (set_attr "mode" "QI,QI,SI")])
8670 (define_insn "*andqi_2"
8671 [(set (reg FLAGS_REG)
8673 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8674 (match_operand:QI 2 "general_operand" "qim,qi"))
8676 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8677 (and:QI (match_dup 1) (match_dup 2)))]
8678 "ix86_match_ccmode (insn, CCNOmode)
8679 && ix86_binary_operator_ok (AND, QImode, operands)"
8680 "and{b}\t{%2, %0|%0, %2}"
8681 [(set_attr "type" "alu")
8682 (set_attr "mode" "QI")])
8684 (define_insn "*andqi_2_slp"
8685 [(set (reg FLAGS_REG)
8687 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8688 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8690 (set (strict_low_part (match_dup 0))
8691 (and:QI (match_dup 0) (match_dup 1)))]
8692 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8693 && ix86_match_ccmode (insn, CCNOmode)
8694 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8695 "and{b}\t{%1, %0|%0, %1}"
8696 [(set_attr "type" "alu1")
8697 (set_attr "mode" "QI")])
8699 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8700 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8701 ;; for a QImode operand, which of course failed.
8703 (define_insn "andqi_ext_0"
8704 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8709 (match_operand 1 "ext_register_operand" "0")
8712 (match_operand 2 "const_int_operand" "n")))
8713 (clobber (reg:CC FLAGS_REG))]
8715 "and{b}\t{%2, %h0|%h0, %2}"
8716 [(set_attr "type" "alu")
8717 (set_attr "length_immediate" "1")
8718 (set_attr "mode" "QI")])
8720 ;; Generated by peephole translating test to and. This shows up
8721 ;; often in fp comparisons.
8723 (define_insn "*andqi_ext_0_cc"
8724 [(set (reg FLAGS_REG)
8728 (match_operand 1 "ext_register_operand" "0")
8731 (match_operand 2 "const_int_operand" "n"))
8733 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8742 "ix86_match_ccmode (insn, CCNOmode)"
8743 "and{b}\t{%2, %h0|%h0, %2}"
8744 [(set_attr "type" "alu")
8745 (set_attr "length_immediate" "1")
8746 (set_attr "mode" "QI")])
8748 (define_insn "*andqi_ext_1"
8749 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8754 (match_operand 1 "ext_register_operand" "0")
8758 (match_operand:QI 2 "general_operand" "Qm"))))
8759 (clobber (reg:CC FLAGS_REG))]
8761 "and{b}\t{%2, %h0|%h0, %2}"
8762 [(set_attr "type" "alu")
8763 (set_attr "length_immediate" "0")
8764 (set_attr "mode" "QI")])
8766 (define_insn "*andqi_ext_1_rex64"
8767 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8772 (match_operand 1 "ext_register_operand" "0")
8776 (match_operand 2 "ext_register_operand" "Q"))))
8777 (clobber (reg:CC FLAGS_REG))]
8779 "and{b}\t{%2, %h0|%h0, %2}"
8780 [(set_attr "type" "alu")
8781 (set_attr "length_immediate" "0")
8782 (set_attr "mode" "QI")])
8784 (define_insn "*andqi_ext_2"
8785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8790 (match_operand 1 "ext_register_operand" "%0")
8794 (match_operand 2 "ext_register_operand" "Q")
8797 (clobber (reg:CC FLAGS_REG))]
8799 "and{b}\t{%h2, %h0|%h0, %h2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "length_immediate" "0")
8802 (set_attr "mode" "QI")])
8804 ;; Convert wide AND instructions with immediate operand to shorter QImode
8805 ;; equivalents when possible.
8806 ;; Don't do the splitting with memory operands, since it introduces risk
8807 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8808 ;; for size, but that can (should?) be handled by generic code instead.
8810 [(set (match_operand 0 "register_operand" "")
8811 (and (match_operand 1 "register_operand" "")
8812 (match_operand 2 "const_int_operand" "")))
8813 (clobber (reg:CC FLAGS_REG))]
8815 && QI_REG_P (operands[0])
8816 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8817 && !(~INTVAL (operands[2]) & ~(255 << 8))
8818 && GET_MODE (operands[0]) != QImode"
8819 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8820 (and:SI (zero_extract:SI (match_dup 1)
8821 (const_int 8) (const_int 8))
8823 (clobber (reg:CC FLAGS_REG))])]
8824 "operands[0] = gen_lowpart (SImode, operands[0]);
8825 operands[1] = gen_lowpart (SImode, operands[1]);
8826 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8828 ;; Since AND can be encoded with sign extended immediate, this is only
8829 ;; profitable when 7th bit is not set.
8831 [(set (match_operand 0 "register_operand" "")
8832 (and (match_operand 1 "general_operand" "")
8833 (match_operand 2 "const_int_operand" "")))
8834 (clobber (reg:CC FLAGS_REG))]
8836 && ANY_QI_REG_P (operands[0])
8837 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8838 && !(~INTVAL (operands[2]) & ~255)
8839 && !(INTVAL (operands[2]) & 128)
8840 && GET_MODE (operands[0]) != QImode"
8841 [(parallel [(set (strict_low_part (match_dup 0))
8842 (and:QI (match_dup 1)
8844 (clobber (reg:CC FLAGS_REG))])]
8845 "operands[0] = gen_lowpart (QImode, operands[0]);
8846 operands[1] = gen_lowpart (QImode, operands[1]);
8847 operands[2] = gen_lowpart (QImode, operands[2]);")
8849 ;; Logical inclusive OR instructions
8851 ;; %%% This used to optimize known byte-wide and operations to memory.
8852 ;; If this is considered useful, it should be done with splitters.
8854 (define_expand "iordi3"
8855 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8856 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8857 (match_operand:DI 2 "x86_64_general_operand" "")))
8858 (clobber (reg:CC FLAGS_REG))]
8860 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8862 (define_insn "*iordi_1_rex64"
8863 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8864 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8865 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8866 (clobber (reg:CC FLAGS_REG))]
8868 && ix86_binary_operator_ok (IOR, DImode, operands)"
8869 "or{q}\t{%2, %0|%0, %2}"
8870 [(set_attr "type" "alu")
8871 (set_attr "mode" "DI")])
8873 (define_insn "*iordi_2_rex64"
8874 [(set (reg FLAGS_REG)
8875 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8876 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8878 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8879 (ior:DI (match_dup 1) (match_dup 2)))]
8881 && ix86_match_ccmode (insn, CCNOmode)
8882 && ix86_binary_operator_ok (IOR, DImode, operands)"
8883 "or{q}\t{%2, %0|%0, %2}"
8884 [(set_attr "type" "alu")
8885 (set_attr "mode" "DI")])
8887 (define_insn "*iordi_3_rex64"
8888 [(set (reg FLAGS_REG)
8889 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8890 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8892 (clobber (match_scratch:DI 0 "=r"))]
8894 && ix86_match_ccmode (insn, CCNOmode)
8895 && ix86_binary_operator_ok (IOR, DImode, operands)"
8896 "or{q}\t{%2, %0|%0, %2}"
8897 [(set_attr "type" "alu")
8898 (set_attr "mode" "DI")])
8901 (define_expand "iorsi3"
8902 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8903 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8904 (match_operand:SI 2 "general_operand" "")))
8905 (clobber (reg:CC FLAGS_REG))]
8907 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8909 (define_insn "*iorsi_1"
8910 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8911 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8912 (match_operand:SI 2 "general_operand" "ri,rmi")))
8913 (clobber (reg:CC FLAGS_REG))]
8914 "ix86_binary_operator_ok (IOR, SImode, operands)"
8915 "or{l}\t{%2, %0|%0, %2}"
8916 [(set_attr "type" "alu")
8917 (set_attr "mode" "SI")])
8919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8920 (define_insn "*iorsi_1_zext"
8921 [(set (match_operand:DI 0 "register_operand" "=rm")
8923 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8924 (match_operand:SI 2 "general_operand" "rim"))))
8925 (clobber (reg:CC FLAGS_REG))]
8926 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8927 "or{l}\t{%2, %k0|%k0, %2}"
8928 [(set_attr "type" "alu")
8929 (set_attr "mode" "SI")])
8931 (define_insn "*iorsi_1_zext_imm"
8932 [(set (match_operand:DI 0 "register_operand" "=rm")
8933 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8934 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8935 (clobber (reg:CC FLAGS_REG))]
8937 "or{l}\t{%2, %k0|%k0, %2}"
8938 [(set_attr "type" "alu")
8939 (set_attr "mode" "SI")])
8941 (define_insn "*iorsi_2"
8942 [(set (reg FLAGS_REG)
8943 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8944 (match_operand:SI 2 "general_operand" "rim,ri"))
8946 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8947 (ior:SI (match_dup 1) (match_dup 2)))]
8948 "ix86_match_ccmode (insn, CCNOmode)
8949 && ix86_binary_operator_ok (IOR, SImode, operands)"
8950 "or{l}\t{%2, %0|%0, %2}"
8951 [(set_attr "type" "alu")
8952 (set_attr "mode" "SI")])
8954 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8955 ;; ??? Special case for immediate operand is missing - it is tricky.
8956 (define_insn "*iorsi_2_zext"
8957 [(set (reg FLAGS_REG)
8958 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8959 (match_operand:SI 2 "general_operand" "rim"))
8961 (set (match_operand:DI 0 "register_operand" "=r")
8962 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8963 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8964 && ix86_binary_operator_ok (IOR, SImode, operands)"
8965 "or{l}\t{%2, %k0|%k0, %2}"
8966 [(set_attr "type" "alu")
8967 (set_attr "mode" "SI")])
8969 (define_insn "*iorsi_2_zext_imm"
8970 [(set (reg FLAGS_REG)
8971 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8974 (set (match_operand:DI 0 "register_operand" "=r")
8975 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8976 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977 && ix86_binary_operator_ok (IOR, SImode, operands)"
8978 "or{l}\t{%2, %k0|%k0, %2}"
8979 [(set_attr "type" "alu")
8980 (set_attr "mode" "SI")])
8982 (define_insn "*iorsi_3"
8983 [(set (reg FLAGS_REG)
8984 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985 (match_operand:SI 2 "general_operand" "rim"))
8987 (clobber (match_scratch:SI 0 "=r"))]
8988 "ix86_match_ccmode (insn, CCNOmode)
8989 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8990 "or{l}\t{%2, %0|%0, %2}"
8991 [(set_attr "type" "alu")
8992 (set_attr "mode" "SI")])
8994 (define_expand "iorhi3"
8995 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8996 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8997 (match_operand:HI 2 "general_operand" "")))
8998 (clobber (reg:CC FLAGS_REG))]
8999 "TARGET_HIMODE_MATH"
9000 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9002 (define_insn "*iorhi_1"
9003 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9004 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9005 (match_operand:HI 2 "general_operand" "rmi,ri")))
9006 (clobber (reg:CC FLAGS_REG))]
9007 "ix86_binary_operator_ok (IOR, HImode, operands)"
9008 "or{w}\t{%2, %0|%0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "HI")])
9012 (define_insn "*iorhi_2"
9013 [(set (reg FLAGS_REG)
9014 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9015 (match_operand:HI 2 "general_operand" "rim,ri"))
9017 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9018 (ior:HI (match_dup 1) (match_dup 2)))]
9019 "ix86_match_ccmode (insn, CCNOmode)
9020 && ix86_binary_operator_ok (IOR, HImode, operands)"
9021 "or{w}\t{%2, %0|%0, %2}"
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "HI")])
9025 (define_insn "*iorhi_3"
9026 [(set (reg FLAGS_REG)
9027 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9028 (match_operand:HI 2 "general_operand" "rim"))
9030 (clobber (match_scratch:HI 0 "=r"))]
9031 "ix86_match_ccmode (insn, CCNOmode)
9032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9033 "or{w}\t{%2, %0|%0, %2}"
9034 [(set_attr "type" "alu")
9035 (set_attr "mode" "HI")])
9037 (define_expand "iorqi3"
9038 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9039 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9040 (match_operand:QI 2 "general_operand" "")))
9041 (clobber (reg:CC FLAGS_REG))]
9042 "TARGET_QIMODE_MATH"
9043 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9045 ;; %%% Potential partial reg stall on alternative 2. What to do?
9046 (define_insn "*iorqi_1"
9047 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9048 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9049 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9050 (clobber (reg:CC FLAGS_REG))]
9051 "ix86_binary_operator_ok (IOR, QImode, operands)"
9053 or{b}\t{%2, %0|%0, %2}
9054 or{b}\t{%2, %0|%0, %2}
9055 or{l}\t{%k2, %k0|%k0, %k2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "mode" "QI,QI,SI")])
9059 (define_insn "*iorqi_1_slp"
9060 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9061 (ior:QI (match_dup 0)
9062 (match_operand:QI 1 "general_operand" "qmi,qi")))
9063 (clobber (reg:CC FLAGS_REG))]
9064 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9065 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9066 "or{b}\t{%1, %0|%0, %1}"
9067 [(set_attr "type" "alu1")
9068 (set_attr "mode" "QI")])
9070 (define_insn "*iorqi_2"
9071 [(set (reg FLAGS_REG)
9072 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9073 (match_operand:QI 2 "general_operand" "qim,qi"))
9075 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9076 (ior:QI (match_dup 1) (match_dup 2)))]
9077 "ix86_match_ccmode (insn, CCNOmode)
9078 && ix86_binary_operator_ok (IOR, QImode, operands)"
9079 "or{b}\t{%2, %0|%0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "mode" "QI")])
9083 (define_insn "*iorqi_2_slp"
9084 [(set (reg FLAGS_REG)
9085 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9086 (match_operand:QI 1 "general_operand" "qim,qi"))
9088 (set (strict_low_part (match_dup 0))
9089 (ior:QI (match_dup 0) (match_dup 1)))]
9090 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9091 && ix86_match_ccmode (insn, CCNOmode)
9092 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9093 "or{b}\t{%1, %0|%0, %1}"
9094 [(set_attr "type" "alu1")
9095 (set_attr "mode" "QI")])
9097 (define_insn "*iorqi_3"
9098 [(set (reg FLAGS_REG)
9099 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9100 (match_operand:QI 2 "general_operand" "qim"))
9102 (clobber (match_scratch:QI 0 "=q"))]
9103 "ix86_match_ccmode (insn, CCNOmode)
9104 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9105 "or{b}\t{%2, %0|%0, %2}"
9106 [(set_attr "type" "alu")
9107 (set_attr "mode" "QI")])
9109 (define_insn "iorqi_ext_0"
9110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9115 (match_operand 1 "ext_register_operand" "0")
9118 (match_operand 2 "const_int_operand" "n")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9121 "or{b}\t{%2, %h0|%h0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "length_immediate" "1")
9124 (set_attr "mode" "QI")])
9126 (define_insn "*iorqi_ext_1"
9127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9132 (match_operand 1 "ext_register_operand" "0")
9136 (match_operand:QI 2 "general_operand" "Qm"))))
9137 (clobber (reg:CC FLAGS_REG))]
9139 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9140 "or{b}\t{%2, %h0|%h0, %2}"
9141 [(set_attr "type" "alu")
9142 (set_attr "length_immediate" "0")
9143 (set_attr "mode" "QI")])
9145 (define_insn "*iorqi_ext_1_rex64"
9146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9151 (match_operand 1 "ext_register_operand" "0")
9155 (match_operand 2 "ext_register_operand" "Q"))))
9156 (clobber (reg:CC FLAGS_REG))]
9158 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9159 "or{b}\t{%2, %h0|%h0, %2}"
9160 [(set_attr "type" "alu")
9161 (set_attr "length_immediate" "0")
9162 (set_attr "mode" "QI")])
9164 (define_insn "*iorqi_ext_2"
9165 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9169 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9172 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9175 (clobber (reg:CC FLAGS_REG))]
9176 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177 "ior{b}\t{%h2, %h0|%h0, %h2}"
9178 [(set_attr "type" "alu")
9179 (set_attr "length_immediate" "0")
9180 (set_attr "mode" "QI")])
9183 [(set (match_operand 0 "register_operand" "")
9184 (ior (match_operand 1 "register_operand" "")
9185 (match_operand 2 "const_int_operand" "")))
9186 (clobber (reg:CC FLAGS_REG))]
9188 && QI_REG_P (operands[0])
9189 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9190 && !(INTVAL (operands[2]) & ~(255 << 8))
9191 && GET_MODE (operands[0]) != QImode"
9192 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9193 (ior:SI (zero_extract:SI (match_dup 1)
9194 (const_int 8) (const_int 8))
9196 (clobber (reg:CC FLAGS_REG))])]
9197 "operands[0] = gen_lowpart (SImode, operands[0]);
9198 operands[1] = gen_lowpart (SImode, operands[1]);
9199 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9201 ;; Since OR can be encoded with sign extended immediate, this is only
9202 ;; profitable when 7th bit is set.
9204 [(set (match_operand 0 "register_operand" "")
9205 (ior (match_operand 1 "general_operand" "")
9206 (match_operand 2 "const_int_operand" "")))
9207 (clobber (reg:CC FLAGS_REG))]
9209 && ANY_QI_REG_P (operands[0])
9210 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9211 && !(INTVAL (operands[2]) & ~255)
9212 && (INTVAL (operands[2]) & 128)
9213 && GET_MODE (operands[0]) != QImode"
9214 [(parallel [(set (strict_low_part (match_dup 0))
9215 (ior:QI (match_dup 1)
9217 (clobber (reg:CC FLAGS_REG))])]
9218 "operands[0] = gen_lowpart (QImode, operands[0]);
9219 operands[1] = gen_lowpart (QImode, operands[1]);
9220 operands[2] = gen_lowpart (QImode, operands[2]);")
9222 ;; Logical XOR instructions
9224 ;; %%% This used to optimize known byte-wide and operations to memory.
9225 ;; If this is considered useful, it should be done with splitters.
9227 (define_expand "xordi3"
9228 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9229 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9230 (match_operand:DI 2 "x86_64_general_operand" "")))
9231 (clobber (reg:CC FLAGS_REG))]
9233 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9235 (define_insn "*xordi_1_rex64"
9236 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9237 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9238 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9239 (clobber (reg:CC FLAGS_REG))]
9241 && ix86_binary_operator_ok (XOR, DImode, operands)"
9243 xor{q}\t{%2, %0|%0, %2}
9244 xor{q}\t{%2, %0|%0, %2}"
9245 [(set_attr "type" "alu")
9246 (set_attr "mode" "DI,DI")])
9248 (define_insn "*xordi_2_rex64"
9249 [(set (reg FLAGS_REG)
9250 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9251 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9253 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9254 (xor:DI (match_dup 1) (match_dup 2)))]
9256 && ix86_match_ccmode (insn, CCNOmode)
9257 && ix86_binary_operator_ok (XOR, DImode, operands)"
9259 xor{q}\t{%2, %0|%0, %2}
9260 xor{q}\t{%2, %0|%0, %2}"
9261 [(set_attr "type" "alu")
9262 (set_attr "mode" "DI,DI")])
9264 (define_insn "*xordi_3_rex64"
9265 [(set (reg FLAGS_REG)
9266 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9267 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9269 (clobber (match_scratch:DI 0 "=r"))]
9271 && ix86_match_ccmode (insn, CCNOmode)
9272 && ix86_binary_operator_ok (XOR, DImode, operands)"
9273 "xor{q}\t{%2, %0|%0, %2}"
9274 [(set_attr "type" "alu")
9275 (set_attr "mode" "DI")])
9277 (define_expand "xorsi3"
9278 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9279 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9280 (match_operand:SI 2 "general_operand" "")))
9281 (clobber (reg:CC FLAGS_REG))]
9283 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9285 (define_insn "*xorsi_1"
9286 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9287 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9288 (match_operand:SI 2 "general_operand" "ri,rm")))
9289 (clobber (reg:CC FLAGS_REG))]
9290 "ix86_binary_operator_ok (XOR, SImode, operands)"
9291 "xor{l}\t{%2, %0|%0, %2}"
9292 [(set_attr "type" "alu")
9293 (set_attr "mode" "SI")])
9295 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9296 ;; Add speccase for immediates
9297 (define_insn "*xorsi_1_zext"
9298 [(set (match_operand:DI 0 "register_operand" "=r")
9300 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9301 (match_operand:SI 2 "general_operand" "rim"))))
9302 (clobber (reg:CC FLAGS_REG))]
9303 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9304 "xor{l}\t{%2, %k0|%k0, %2}"
9305 [(set_attr "type" "alu")
9306 (set_attr "mode" "SI")])
9308 (define_insn "*xorsi_1_zext_imm"
9309 [(set (match_operand:DI 0 "register_operand" "=r")
9310 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9311 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9312 (clobber (reg:CC FLAGS_REG))]
9313 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9314 "xor{l}\t{%2, %k0|%k0, %2}"
9315 [(set_attr "type" "alu")
9316 (set_attr "mode" "SI")])
9318 (define_insn "*xorsi_2"
9319 [(set (reg FLAGS_REG)
9320 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9321 (match_operand:SI 2 "general_operand" "rim,ri"))
9323 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9324 (xor:SI (match_dup 1) (match_dup 2)))]
9325 "ix86_match_ccmode (insn, CCNOmode)
9326 && ix86_binary_operator_ok (XOR, SImode, operands)"
9327 "xor{l}\t{%2, %0|%0, %2}"
9328 [(set_attr "type" "alu")
9329 (set_attr "mode" "SI")])
9331 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9332 ;; ??? Special case for immediate operand is missing - it is tricky.
9333 (define_insn "*xorsi_2_zext"
9334 [(set (reg FLAGS_REG)
9335 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9336 (match_operand:SI 2 "general_operand" "rim"))
9338 (set (match_operand:DI 0 "register_operand" "=r")
9339 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9340 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9341 && ix86_binary_operator_ok (XOR, SImode, operands)"
9342 "xor{l}\t{%2, %k0|%k0, %2}"
9343 [(set_attr "type" "alu")
9344 (set_attr "mode" "SI")])
9346 (define_insn "*xorsi_2_zext_imm"
9347 [(set (reg FLAGS_REG)
9348 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9349 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9351 (set (match_operand:DI 0 "register_operand" "=r")
9352 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9353 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9354 && ix86_binary_operator_ok (XOR, SImode, operands)"
9355 "xor{l}\t{%2, %k0|%k0, %2}"
9356 [(set_attr "type" "alu")
9357 (set_attr "mode" "SI")])
9359 (define_insn "*xorsi_3"
9360 [(set (reg FLAGS_REG)
9361 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9362 (match_operand:SI 2 "general_operand" "rim"))
9364 (clobber (match_scratch:SI 0 "=r"))]
9365 "ix86_match_ccmode (insn, CCNOmode)
9366 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9367 "xor{l}\t{%2, %0|%0, %2}"
9368 [(set_attr "type" "alu")
9369 (set_attr "mode" "SI")])
9371 (define_expand "xorhi3"
9372 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9373 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9374 (match_operand:HI 2 "general_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "TARGET_HIMODE_MATH"
9377 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9379 (define_insn "*xorhi_1"
9380 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9381 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9382 (match_operand:HI 2 "general_operand" "rmi,ri")))
9383 (clobber (reg:CC FLAGS_REG))]
9384 "ix86_binary_operator_ok (XOR, HImode, operands)"
9385 "xor{w}\t{%2, %0|%0, %2}"
9386 [(set_attr "type" "alu")
9387 (set_attr "mode" "HI")])
9389 (define_insn "*xorhi_2"
9390 [(set (reg FLAGS_REG)
9391 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9392 (match_operand:HI 2 "general_operand" "rim,ri"))
9394 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9395 (xor:HI (match_dup 1) (match_dup 2)))]
9396 "ix86_match_ccmode (insn, CCNOmode)
9397 && ix86_binary_operator_ok (XOR, HImode, operands)"
9398 "xor{w}\t{%2, %0|%0, %2}"
9399 [(set_attr "type" "alu")
9400 (set_attr "mode" "HI")])
9402 (define_insn "*xorhi_3"
9403 [(set (reg FLAGS_REG)
9404 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9405 (match_operand:HI 2 "general_operand" "rim"))
9407 (clobber (match_scratch:HI 0 "=r"))]
9408 "ix86_match_ccmode (insn, CCNOmode)
9409 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9410 "xor{w}\t{%2, %0|%0, %2}"
9411 [(set_attr "type" "alu")
9412 (set_attr "mode" "HI")])
9414 (define_expand "xorqi3"
9415 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9416 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9417 (match_operand:QI 2 "general_operand" "")))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "TARGET_QIMODE_MATH"
9420 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9422 ;; %%% Potential partial reg stall on alternative 2. What to do?
9423 (define_insn "*xorqi_1"
9424 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9425 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9426 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9427 (clobber (reg:CC FLAGS_REG))]
9428 "ix86_binary_operator_ok (XOR, QImode, operands)"
9430 xor{b}\t{%2, %0|%0, %2}
9431 xor{b}\t{%2, %0|%0, %2}
9432 xor{l}\t{%k2, %k0|%k0, %k2}"
9433 [(set_attr "type" "alu")
9434 (set_attr "mode" "QI,QI,SI")])
9436 (define_insn "*xorqi_1_slp"
9437 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9438 (xor:QI (match_dup 0)
9439 (match_operand:QI 1 "general_operand" "qi,qmi")))
9440 (clobber (reg:CC FLAGS_REG))]
9441 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9443 "xor{b}\t{%1, %0|%0, %1}"
9444 [(set_attr "type" "alu1")
9445 (set_attr "mode" "QI")])
9447 (define_insn "xorqi_ext_0"
9448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9453 (match_operand 1 "ext_register_operand" "0")
9456 (match_operand 2 "const_int_operand" "n")))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9459 "xor{b}\t{%2, %h0|%h0, %2}"
9460 [(set_attr "type" "alu")
9461 (set_attr "length_immediate" "1")
9462 (set_attr "mode" "QI")])
9464 (define_insn "*xorqi_ext_1"
9465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9470 (match_operand 1 "ext_register_operand" "0")
9474 (match_operand:QI 2 "general_operand" "Qm"))))
9475 (clobber (reg:CC FLAGS_REG))]
9477 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9478 "xor{b}\t{%2, %h0|%h0, %2}"
9479 [(set_attr "type" "alu")
9480 (set_attr "length_immediate" "0")
9481 (set_attr "mode" "QI")])
9483 (define_insn "*xorqi_ext_1_rex64"
9484 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9489 (match_operand 1 "ext_register_operand" "0")
9493 (match_operand 2 "ext_register_operand" "Q"))))
9494 (clobber (reg:CC FLAGS_REG))]
9496 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9497 "xor{b}\t{%2, %h0|%h0, %2}"
9498 [(set_attr "type" "alu")
9499 (set_attr "length_immediate" "0")
9500 (set_attr "mode" "QI")])
9502 (define_insn "*xorqi_ext_2"
9503 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9507 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9510 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9513 (clobber (reg:CC FLAGS_REG))]
9514 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9515 "xor{b}\t{%h2, %h0|%h0, %h2}"
9516 [(set_attr "type" "alu")
9517 (set_attr "length_immediate" "0")
9518 (set_attr "mode" "QI")])
9520 (define_insn "*xorqi_cc_1"
9521 [(set (reg FLAGS_REG)
9523 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9524 (match_operand:QI 2 "general_operand" "qim,qi"))
9526 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9527 (xor:QI (match_dup 1) (match_dup 2)))]
9528 "ix86_match_ccmode (insn, CCNOmode)
9529 && ix86_binary_operator_ok (XOR, QImode, operands)"
9530 "xor{b}\t{%2, %0|%0, %2}"
9531 [(set_attr "type" "alu")
9532 (set_attr "mode" "QI")])
9534 (define_insn "*xorqi_2_slp"
9535 [(set (reg FLAGS_REG)
9536 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9537 (match_operand:QI 1 "general_operand" "qim,qi"))
9539 (set (strict_low_part (match_dup 0))
9540 (xor:QI (match_dup 0) (match_dup 1)))]
9541 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9542 && ix86_match_ccmode (insn, CCNOmode)
9543 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9544 "xor{b}\t{%1, %0|%0, %1}"
9545 [(set_attr "type" "alu1")
9546 (set_attr "mode" "QI")])
9548 (define_insn "*xorqi_cc_2"
9549 [(set (reg FLAGS_REG)
9551 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9552 (match_operand:QI 2 "general_operand" "qim"))
9554 (clobber (match_scratch:QI 0 "=q"))]
9555 "ix86_match_ccmode (insn, CCNOmode)
9556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9557 "xor{b}\t{%2, %0|%0, %2}"
9558 [(set_attr "type" "alu")
9559 (set_attr "mode" "QI")])
9561 (define_insn "*xorqi_cc_ext_1"
9562 [(set (reg FLAGS_REG)
9566 (match_operand 1 "ext_register_operand" "0")
9569 (match_operand:QI 2 "general_operand" "qmn"))
9571 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9575 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9577 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9578 "xor{b}\t{%2, %h0|%h0, %2}"
9579 [(set_attr "type" "alu")
9580 (set_attr "mode" "QI")])
9582 (define_insn "*xorqi_cc_ext_1_rex64"
9583 [(set (reg FLAGS_REG)
9587 (match_operand 1 "ext_register_operand" "0")
9590 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9592 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9596 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9599 "xor{b}\t{%2, %h0|%h0, %2}"
9600 [(set_attr "type" "alu")
9601 (set_attr "mode" "QI")])
9603 (define_expand "xorqi_cc_ext_1"
9605 (set (reg:CCNO FLAGS_REG)
9609 (match_operand 1 "ext_register_operand" "")
9612 (match_operand:QI 2 "general_operand" ""))
9614 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9618 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9624 [(set (match_operand 0 "register_operand" "")
9625 (xor (match_operand 1 "register_operand" "")
9626 (match_operand 2 "const_int_operand" "")))
9627 (clobber (reg:CC FLAGS_REG))]
9629 && QI_REG_P (operands[0])
9630 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9631 && !(INTVAL (operands[2]) & ~(255 << 8))
9632 && GET_MODE (operands[0]) != QImode"
9633 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9634 (xor:SI (zero_extract:SI (match_dup 1)
9635 (const_int 8) (const_int 8))
9637 (clobber (reg:CC FLAGS_REG))])]
9638 "operands[0] = gen_lowpart (SImode, operands[0]);
9639 operands[1] = gen_lowpart (SImode, operands[1]);
9640 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9642 ;; Since XOR can be encoded with sign extended immediate, this is only
9643 ;; profitable when 7th bit is set.
9645 [(set (match_operand 0 "register_operand" "")
9646 (xor (match_operand 1 "general_operand" "")
9647 (match_operand 2 "const_int_operand" "")))
9648 (clobber (reg:CC FLAGS_REG))]
9650 && ANY_QI_REG_P (operands[0])
9651 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9652 && !(INTVAL (operands[2]) & ~255)
9653 && (INTVAL (operands[2]) & 128)
9654 && GET_MODE (operands[0]) != QImode"
9655 [(parallel [(set (strict_low_part (match_dup 0))
9656 (xor:QI (match_dup 1)
9658 (clobber (reg:CC FLAGS_REG))])]
9659 "operands[0] = gen_lowpart (QImode, operands[0]);
9660 operands[1] = gen_lowpart (QImode, operands[1]);
9661 operands[2] = gen_lowpart (QImode, operands[2]);")
9663 ;; Negation instructions
9665 (define_expand "negti2"
9666 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9667 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9668 (clobber (reg:CC FLAGS_REG))])]
9670 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9672 (define_insn "*negti2_1"
9673 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9674 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9675 (clobber (reg:CC FLAGS_REG))]
9677 && ix86_unary_operator_ok (NEG, TImode, operands)"
9681 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9682 (neg:TI (match_operand:TI 1 "general_operand" "")))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "TARGET_64BIT && reload_completed"
9686 [(set (reg:CCZ FLAGS_REG)
9687 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9688 (set (match_dup 0) (neg:DI (match_dup 2)))])
9691 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9694 (clobber (reg:CC FLAGS_REG))])
9697 (neg:DI (match_dup 1)))
9698 (clobber (reg:CC FLAGS_REG))])]
9699 "split_ti (operands+1, 1, operands+2, operands+3);
9700 split_ti (operands+0, 1, operands+0, operands+1);")
9702 (define_expand "negdi2"
9703 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9704 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9705 (clobber (reg:CC FLAGS_REG))])]
9707 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9709 (define_insn "*negdi2_1"
9710 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9711 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9712 (clobber (reg:CC FLAGS_REG))]
9714 && ix86_unary_operator_ok (NEG, DImode, operands)"
9718 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9719 (neg:DI (match_operand:DI 1 "general_operand" "")))
9720 (clobber (reg:CC FLAGS_REG))]
9721 "!TARGET_64BIT && reload_completed"
9723 [(set (reg:CCZ FLAGS_REG)
9724 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9725 (set (match_dup 0) (neg:SI (match_dup 2)))])
9728 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9731 (clobber (reg:CC FLAGS_REG))])
9734 (neg:SI (match_dup 1)))
9735 (clobber (reg:CC FLAGS_REG))])]
9736 "split_di (operands+1, 1, operands+2, operands+3);
9737 split_di (operands+0, 1, operands+0, operands+1);")
9739 (define_insn "*negdi2_1_rex64"
9740 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9741 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9742 (clobber (reg:CC FLAGS_REG))]
9743 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9745 [(set_attr "type" "negnot")
9746 (set_attr "mode" "DI")])
9748 ;; The problem with neg is that it does not perform (compare x 0),
9749 ;; it really performs (compare 0 x), which leaves us with the zero
9750 ;; flag being the only useful item.
9752 (define_insn "*negdi2_cmpz_rex64"
9753 [(set (reg:CCZ FLAGS_REG)
9754 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9756 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9757 (neg:DI (match_dup 1)))]
9758 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9760 [(set_attr "type" "negnot")
9761 (set_attr "mode" "DI")])
9764 (define_expand "negsi2"
9765 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9766 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9767 (clobber (reg:CC FLAGS_REG))])]
9769 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9771 (define_insn "*negsi2_1"
9772 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9773 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "ix86_unary_operator_ok (NEG, SImode, operands)"
9777 [(set_attr "type" "negnot")
9778 (set_attr "mode" "SI")])
9780 ;; Combine is quite creative about this pattern.
9781 (define_insn "*negsi2_1_zext"
9782 [(set (match_operand:DI 0 "register_operand" "=r")
9783 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9786 (clobber (reg:CC FLAGS_REG))]
9787 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9789 [(set_attr "type" "negnot")
9790 (set_attr "mode" "SI")])
9792 ;; The problem with neg is that it does not perform (compare x 0),
9793 ;; it really performs (compare 0 x), which leaves us with the zero
9794 ;; flag being the only useful item.
9796 (define_insn "*negsi2_cmpz"
9797 [(set (reg:CCZ FLAGS_REG)
9798 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9800 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9801 (neg:SI (match_dup 1)))]
9802 "ix86_unary_operator_ok (NEG, SImode, operands)"
9804 [(set_attr "type" "negnot")
9805 (set_attr "mode" "SI")])
9807 (define_insn "*negsi2_cmpz_zext"
9808 [(set (reg:CCZ FLAGS_REG)
9809 (compare:CCZ (lshiftrt:DI
9811 (match_operand:DI 1 "register_operand" "0")
9815 (set (match_operand:DI 0 "register_operand" "=r")
9816 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9819 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9821 [(set_attr "type" "negnot")
9822 (set_attr "mode" "SI")])
9824 (define_expand "neghi2"
9825 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9826 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9827 (clobber (reg:CC FLAGS_REG))])]
9828 "TARGET_HIMODE_MATH"
9829 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9831 (define_insn "*neghi2_1"
9832 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9833 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "ix86_unary_operator_ok (NEG, HImode, operands)"
9837 [(set_attr "type" "negnot")
9838 (set_attr "mode" "HI")])
9840 (define_insn "*neghi2_cmpz"
9841 [(set (reg:CCZ FLAGS_REG)
9842 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9844 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9845 (neg:HI (match_dup 1)))]
9846 "ix86_unary_operator_ok (NEG, HImode, operands)"
9848 [(set_attr "type" "negnot")
9849 (set_attr "mode" "HI")])
9851 (define_expand "negqi2"
9852 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9853 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9854 (clobber (reg:CC FLAGS_REG))])]
9855 "TARGET_QIMODE_MATH"
9856 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9858 (define_insn "*negqi2_1"
9859 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9860 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "ix86_unary_operator_ok (NEG, QImode, operands)"
9864 [(set_attr "type" "negnot")
9865 (set_attr "mode" "QI")])
9867 (define_insn "*negqi2_cmpz"
9868 [(set (reg:CCZ FLAGS_REG)
9869 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9871 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9872 (neg:QI (match_dup 1)))]
9873 "ix86_unary_operator_ok (NEG, QImode, operands)"
9875 [(set_attr "type" "negnot")
9876 (set_attr "mode" "QI")])
9878 ;; Changing of sign for FP values is doable using integer unit too.
9880 (define_expand "negsf2"
9881 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9882 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9883 "TARGET_80387 || TARGET_SSE_MATH"
9884 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9886 (define_expand "abssf2"
9887 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9888 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9889 "TARGET_80387 || TARGET_SSE_MATH"
9890 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9892 (define_insn "*absnegsf2_mixed"
9893 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9894 (match_operator:SF 3 "absneg_operator"
9895 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9896 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9897 (clobber (reg:CC FLAGS_REG))]
9898 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9899 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9902 (define_insn "*absnegsf2_sse"
9903 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9904 (match_operator:SF 3 "absneg_operator"
9905 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9906 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9907 (clobber (reg:CC FLAGS_REG))]
9909 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9912 (define_insn "*absnegsf2_i387"
9913 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9914 (match_operator:SF 3 "absneg_operator"
9915 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9916 (use (match_operand 2 "" ""))
9917 (clobber (reg:CC FLAGS_REG))]
9918 "TARGET_80387 && !TARGET_SSE_MATH
9919 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9922 (define_expand "copysignsf3"
9923 [(match_operand:SF 0 "register_operand" "")
9924 (match_operand:SF 1 "nonmemory_operand" "")
9925 (match_operand:SF 2 "register_operand" "")]
9928 ix86_expand_copysign (operands);
9932 (define_insn_and_split "copysignsf3_const"
9933 [(set (match_operand:SF 0 "register_operand" "=x")
9935 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9936 (match_operand:SF 2 "register_operand" "0")
9937 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9941 "&& reload_completed"
9944 ix86_split_copysign_const (operands);
9948 (define_insn "copysignsf3_var"
9949 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9951 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9952 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9953 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9954 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9956 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9961 [(set (match_operand:SF 0 "register_operand" "")
9963 [(match_operand:SF 2 "register_operand" "")
9964 (match_operand:SF 3 "register_operand" "")
9965 (match_operand:V4SF 4 "" "")
9966 (match_operand:V4SF 5 "" "")]
9968 (clobber (match_scratch:V4SF 1 ""))]
9969 "TARGET_SSE_MATH && reload_completed"
9972 ix86_split_copysign_var (operands);
9976 (define_expand "negdf2"
9977 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9978 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9979 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9980 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9982 (define_expand "absdf2"
9983 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9984 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9985 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9986 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9988 (define_insn "*absnegdf2_mixed"
9989 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
9990 (match_operator:DF 3 "absneg_operator"
9991 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9992 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
9993 (clobber (reg:CC FLAGS_REG))]
9994 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9995 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9998 (define_insn "*absnegdf2_sse"
9999 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10000 (match_operator:DF 3 "absneg_operator"
10001 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10002 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10003 (clobber (reg:CC FLAGS_REG))]
10004 "TARGET_SSE2 && TARGET_SSE_MATH
10005 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10008 (define_insn "*absnegdf2_i387"
10009 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10010 (match_operator:DF 3 "absneg_operator"
10011 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10012 (use (match_operand 2 "" ""))
10013 (clobber (reg:CC FLAGS_REG))]
10014 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10015 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10018 (define_expand "copysigndf3"
10019 [(match_operand:DF 0 "register_operand" "")
10020 (match_operand:DF 1 "nonmemory_operand" "")
10021 (match_operand:DF 2 "register_operand" "")]
10022 "TARGET_SSE2 && TARGET_SSE_MATH"
10024 ix86_expand_copysign (operands);
10028 (define_insn_and_split "copysigndf3_const"
10029 [(set (match_operand:DF 0 "register_operand" "=x")
10031 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
10032 (match_operand:DF 2 "register_operand" "0")
10033 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10035 "TARGET_SSE2 && TARGET_SSE_MATH"
10037 "&& reload_completed"
10040 ix86_split_copysign_const (operands);
10044 (define_insn "copysigndf3_var"
10045 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
10047 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
10048 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
10049 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10050 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10052 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
10053 "TARGET_SSE2 && TARGET_SSE_MATH"
10057 [(set (match_operand:DF 0 "register_operand" "")
10059 [(match_operand:DF 2 "register_operand" "")
10060 (match_operand:DF 3 "register_operand" "")
10061 (match_operand:V2DF 4 "" "")
10062 (match_operand:V2DF 5 "" "")]
10064 (clobber (match_scratch:V2DF 1 ""))]
10065 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10068 ix86_split_copysign_var (operands);
10072 (define_expand "negxf2"
10073 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10074 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10076 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10078 (define_expand "absxf2"
10079 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10080 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10082 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10084 (define_insn "*absnegxf2_i387"
10085 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10086 (match_operator:XF 3 "absneg_operator"
10087 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10088 (use (match_operand 2 "" ""))
10089 (clobber (reg:CC FLAGS_REG))]
10091 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10094 ;; Splitters for fp abs and neg.
10097 [(set (match_operand 0 "fp_register_operand" "")
10098 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10099 (use (match_operand 2 "" ""))
10100 (clobber (reg:CC FLAGS_REG))]
10102 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10105 [(set (match_operand 0 "register_operand" "")
10106 (match_operator 3 "absneg_operator"
10107 [(match_operand 1 "register_operand" "")]))
10108 (use (match_operand 2 "nonimmediate_operand" ""))
10109 (clobber (reg:CC FLAGS_REG))]
10110 "reload_completed && SSE_REG_P (operands[0])"
10111 [(set (match_dup 0) (match_dup 3))]
10113 enum machine_mode mode = GET_MODE (operands[0]);
10114 enum machine_mode vmode = GET_MODE (operands[2]);
10117 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10118 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10119 if (operands_match_p (operands[0], operands[2]))
10122 operands[1] = operands[2];
10125 if (GET_CODE (operands[3]) == ABS)
10126 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10128 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10133 [(set (match_operand:SF 0 "register_operand" "")
10134 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10135 (use (match_operand:V4SF 2 "" ""))
10136 (clobber (reg:CC FLAGS_REG))]
10138 [(parallel [(set (match_dup 0) (match_dup 1))
10139 (clobber (reg:CC FLAGS_REG))])]
10142 operands[0] = gen_lowpart (SImode, operands[0]);
10143 if (GET_CODE (operands[1]) == ABS)
10145 tmp = gen_int_mode (0x7fffffff, SImode);
10146 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10150 tmp = gen_int_mode (0x80000000, SImode);
10151 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10157 [(set (match_operand:DF 0 "register_operand" "")
10158 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10159 (use (match_operand 2 "" ""))
10160 (clobber (reg:CC FLAGS_REG))]
10162 [(parallel [(set (match_dup 0) (match_dup 1))
10163 (clobber (reg:CC FLAGS_REG))])]
10168 tmp = gen_lowpart (DImode, operands[0]);
10169 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10172 if (GET_CODE (operands[1]) == ABS)
10175 tmp = gen_rtx_NOT (DImode, tmp);
10179 operands[0] = gen_highpart (SImode, operands[0]);
10180 if (GET_CODE (operands[1]) == ABS)
10182 tmp = gen_int_mode (0x7fffffff, SImode);
10183 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10187 tmp = gen_int_mode (0x80000000, SImode);
10188 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10195 [(set (match_operand:XF 0 "register_operand" "")
10196 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10197 (use (match_operand 2 "" ""))
10198 (clobber (reg:CC FLAGS_REG))]
10200 [(parallel [(set (match_dup 0) (match_dup 1))
10201 (clobber (reg:CC FLAGS_REG))])]
10204 operands[0] = gen_rtx_REG (SImode,
10205 true_regnum (operands[0])
10206 + (TARGET_64BIT ? 1 : 2));
10207 if (GET_CODE (operands[1]) == ABS)
10209 tmp = GEN_INT (0x7fff);
10210 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10214 tmp = GEN_INT (0x8000);
10215 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10221 [(set (match_operand 0 "memory_operand" "")
10222 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10223 (use (match_operand 2 "" ""))
10224 (clobber (reg:CC FLAGS_REG))]
10226 [(parallel [(set (match_dup 0) (match_dup 1))
10227 (clobber (reg:CC FLAGS_REG))])]
10229 enum machine_mode mode = GET_MODE (operands[0]);
10230 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10233 operands[0] = adjust_address (operands[0], QImode, size - 1);
10234 if (GET_CODE (operands[1]) == ABS)
10236 tmp = gen_int_mode (0x7f, QImode);
10237 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10241 tmp = gen_int_mode (0x80, QImode);
10242 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10247 ;; Conditionalize these after reload. If they match before reload, we
10248 ;; lose the clobber and ability to use integer instructions.
10250 (define_insn "*negsf2_1"
10251 [(set (match_operand:SF 0 "register_operand" "=f")
10252 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10253 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10255 [(set_attr "type" "fsgn")
10256 (set_attr "mode" "SF")])
10258 (define_insn "*negdf2_1"
10259 [(set (match_operand:DF 0 "register_operand" "=f")
10260 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10261 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10263 [(set_attr "type" "fsgn")
10264 (set_attr "mode" "DF")])
10266 (define_insn "*negxf2_1"
10267 [(set (match_operand:XF 0 "register_operand" "=f")
10268 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10271 [(set_attr "type" "fsgn")
10272 (set_attr "mode" "XF")])
10274 (define_insn "*abssf2_1"
10275 [(set (match_operand:SF 0 "register_operand" "=f")
10276 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10277 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10279 [(set_attr "type" "fsgn")
10280 (set_attr "mode" "SF")])
10282 (define_insn "*absdf2_1"
10283 [(set (match_operand:DF 0 "register_operand" "=f")
10284 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10285 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10287 [(set_attr "type" "fsgn")
10288 (set_attr "mode" "DF")])
10290 (define_insn "*absxf2_1"
10291 [(set (match_operand:XF 0 "register_operand" "=f")
10292 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10295 [(set_attr "type" "fsgn")
10296 (set_attr "mode" "DF")])
10298 (define_insn "*negextendsfdf2"
10299 [(set (match_operand:DF 0 "register_operand" "=f")
10300 (neg:DF (float_extend:DF
10301 (match_operand:SF 1 "register_operand" "0"))))]
10302 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10304 [(set_attr "type" "fsgn")
10305 (set_attr "mode" "DF")])
10307 (define_insn "*negextenddfxf2"
10308 [(set (match_operand:XF 0 "register_operand" "=f")
10309 (neg:XF (float_extend:XF
10310 (match_operand:DF 1 "register_operand" "0"))))]
10313 [(set_attr "type" "fsgn")
10314 (set_attr "mode" "XF")])
10316 (define_insn "*negextendsfxf2"
10317 [(set (match_operand:XF 0 "register_operand" "=f")
10318 (neg:XF (float_extend:XF
10319 (match_operand:SF 1 "register_operand" "0"))))]
10322 [(set_attr "type" "fsgn")
10323 (set_attr "mode" "XF")])
10325 (define_insn "*absextendsfdf2"
10326 [(set (match_operand:DF 0 "register_operand" "=f")
10327 (abs:DF (float_extend:DF
10328 (match_operand:SF 1 "register_operand" "0"))))]
10329 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10331 [(set_attr "type" "fsgn")
10332 (set_attr "mode" "DF")])
10334 (define_insn "*absextenddfxf2"
10335 [(set (match_operand:XF 0 "register_operand" "=f")
10336 (abs:XF (float_extend:XF
10337 (match_operand:DF 1 "register_operand" "0"))))]
10340 [(set_attr "type" "fsgn")
10341 (set_attr "mode" "XF")])
10343 (define_insn "*absextendsfxf2"
10344 [(set (match_operand:XF 0 "register_operand" "=f")
10345 (abs:XF (float_extend:XF
10346 (match_operand:SF 1 "register_operand" "0"))))]
10349 [(set_attr "type" "fsgn")
10350 (set_attr "mode" "XF")])
10352 ;; One complement instructions
10354 (define_expand "one_cmpldi2"
10355 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10356 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10358 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10360 (define_insn "*one_cmpldi2_1_rex64"
10361 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10363 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10365 [(set_attr "type" "negnot")
10366 (set_attr "mode" "DI")])
10368 (define_insn "*one_cmpldi2_2_rex64"
10369 [(set (reg FLAGS_REG)
10370 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10372 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10373 (not:DI (match_dup 1)))]
10374 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10375 && ix86_unary_operator_ok (NOT, DImode, operands)"
10377 [(set_attr "type" "alu1")
10378 (set_attr "mode" "DI")])
10381 [(set (match_operand 0 "flags_reg_operand" "")
10382 (match_operator 2 "compare_operator"
10383 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10385 (set (match_operand:DI 1 "nonimmediate_operand" "")
10386 (not:DI (match_dup 3)))]
10387 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10388 [(parallel [(set (match_dup 0)
10390 [(xor:DI (match_dup 3) (const_int -1))
10393 (xor:DI (match_dup 3) (const_int -1)))])]
10396 (define_expand "one_cmplsi2"
10397 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10398 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10400 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10402 (define_insn "*one_cmplsi2_1"
10403 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10404 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10405 "ix86_unary_operator_ok (NOT, SImode, operands)"
10407 [(set_attr "type" "negnot")
10408 (set_attr "mode" "SI")])
10410 ;; ??? Currently never generated - xor is used instead.
10411 (define_insn "*one_cmplsi2_1_zext"
10412 [(set (match_operand:DI 0 "register_operand" "=r")
10413 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10414 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10416 [(set_attr "type" "negnot")
10417 (set_attr "mode" "SI")])
10419 (define_insn "*one_cmplsi2_2"
10420 [(set (reg FLAGS_REG)
10421 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10423 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10424 (not:SI (match_dup 1)))]
10425 "ix86_match_ccmode (insn, CCNOmode)
10426 && ix86_unary_operator_ok (NOT, SImode, operands)"
10428 [(set_attr "type" "alu1")
10429 (set_attr "mode" "SI")])
10432 [(set (match_operand 0 "flags_reg_operand" "")
10433 (match_operator 2 "compare_operator"
10434 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10436 (set (match_operand:SI 1 "nonimmediate_operand" "")
10437 (not:SI (match_dup 3)))]
10438 "ix86_match_ccmode (insn, CCNOmode)"
10439 [(parallel [(set (match_dup 0)
10440 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10443 (xor:SI (match_dup 3) (const_int -1)))])]
10446 ;; ??? Currently never generated - xor is used instead.
10447 (define_insn "*one_cmplsi2_2_zext"
10448 [(set (reg FLAGS_REG)
10449 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10451 (set (match_operand:DI 0 "register_operand" "=r")
10452 (zero_extend:DI (not:SI (match_dup 1))))]
10453 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10454 && ix86_unary_operator_ok (NOT, SImode, operands)"
10456 [(set_attr "type" "alu1")
10457 (set_attr "mode" "SI")])
10460 [(set (match_operand 0 "flags_reg_operand" "")
10461 (match_operator 2 "compare_operator"
10462 [(not:SI (match_operand:SI 3 "register_operand" ""))
10464 (set (match_operand:DI 1 "register_operand" "")
10465 (zero_extend:DI (not:SI (match_dup 3))))]
10466 "ix86_match_ccmode (insn, CCNOmode)"
10467 [(parallel [(set (match_dup 0)
10468 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10471 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10474 (define_expand "one_cmplhi2"
10475 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10476 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10477 "TARGET_HIMODE_MATH"
10478 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10480 (define_insn "*one_cmplhi2_1"
10481 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10482 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10483 "ix86_unary_operator_ok (NOT, HImode, operands)"
10485 [(set_attr "type" "negnot")
10486 (set_attr "mode" "HI")])
10488 (define_insn "*one_cmplhi2_2"
10489 [(set (reg FLAGS_REG)
10490 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10492 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10493 (not:HI (match_dup 1)))]
10494 "ix86_match_ccmode (insn, CCNOmode)
10495 && ix86_unary_operator_ok (NEG, HImode, operands)"
10497 [(set_attr "type" "alu1")
10498 (set_attr "mode" "HI")])
10501 [(set (match_operand 0 "flags_reg_operand" "")
10502 (match_operator 2 "compare_operator"
10503 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10505 (set (match_operand:HI 1 "nonimmediate_operand" "")
10506 (not:HI (match_dup 3)))]
10507 "ix86_match_ccmode (insn, CCNOmode)"
10508 [(parallel [(set (match_dup 0)
10509 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10512 (xor:HI (match_dup 3) (const_int -1)))])]
10515 ;; %%% Potential partial reg stall on alternative 1. What to do?
10516 (define_expand "one_cmplqi2"
10517 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10518 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10519 "TARGET_QIMODE_MATH"
10520 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10522 (define_insn "*one_cmplqi2_1"
10523 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10524 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10525 "ix86_unary_operator_ok (NOT, QImode, operands)"
10529 [(set_attr "type" "negnot")
10530 (set_attr "mode" "QI,SI")])
10532 (define_insn "*one_cmplqi2_2"
10533 [(set (reg FLAGS_REG)
10534 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10536 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10537 (not:QI (match_dup 1)))]
10538 "ix86_match_ccmode (insn, CCNOmode)
10539 && ix86_unary_operator_ok (NOT, QImode, operands)"
10541 [(set_attr "type" "alu1")
10542 (set_attr "mode" "QI")])
10545 [(set (match_operand 0 "flags_reg_operand" "")
10546 (match_operator 2 "compare_operator"
10547 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10549 (set (match_operand:QI 1 "nonimmediate_operand" "")
10550 (not:QI (match_dup 3)))]
10551 "ix86_match_ccmode (insn, CCNOmode)"
10552 [(parallel [(set (match_dup 0)
10553 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10556 (xor:QI (match_dup 3) (const_int -1)))])]
10559 ;; Arithmetic shift instructions
10561 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10562 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10563 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10564 ;; from the assembler input.
10566 ;; This instruction shifts the target reg/mem as usual, but instead of
10567 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10568 ;; is a left shift double, bits are taken from the high order bits of
10569 ;; reg, else if the insn is a shift right double, bits are taken from the
10570 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10571 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10573 ;; Since sh[lr]d does not change the `reg' operand, that is done
10574 ;; separately, making all shifts emit pairs of shift double and normal
10575 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10576 ;; support a 63 bit shift, each shift where the count is in a reg expands
10577 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10579 ;; If the shift count is a constant, we need never emit more than one
10580 ;; shift pair, instead using moves and sign extension for counts greater
10583 (define_expand "ashlti3"
10584 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10585 (ashift:TI (match_operand:TI 1 "register_operand" "")
10586 (match_operand:QI 2 "nonmemory_operand" "")))
10587 (clobber (reg:CC FLAGS_REG))])]
10590 if (! immediate_operand (operands[2], QImode))
10592 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10595 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10599 (define_insn "ashlti3_1"
10600 [(set (match_operand:TI 0 "register_operand" "=r")
10601 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10602 (match_operand:QI 2 "register_operand" "c")))
10603 (clobber (match_scratch:DI 3 "=&r"))
10604 (clobber (reg:CC FLAGS_REG))]
10607 [(set_attr "type" "multi")])
10609 (define_insn "*ashlti3_2"
10610 [(set (match_operand:TI 0 "register_operand" "=r")
10611 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10612 (match_operand:QI 2 "immediate_operand" "O")))
10613 (clobber (reg:CC FLAGS_REG))]
10616 [(set_attr "type" "multi")])
10619 [(set (match_operand:TI 0 "register_operand" "")
10620 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10621 (match_operand:QI 2 "register_operand" "")))
10622 (clobber (match_scratch:DI 3 ""))
10623 (clobber (reg:CC FLAGS_REG))]
10624 "TARGET_64BIT && reload_completed"
10626 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10629 [(set (match_operand:TI 0 "register_operand" "")
10630 (ashift:TI (match_operand:TI 1 "register_operand" "")
10631 (match_operand:QI 2 "immediate_operand" "")))
10632 (clobber (reg:CC FLAGS_REG))]
10633 "TARGET_64BIT && reload_completed"
10635 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10637 (define_insn "x86_64_shld"
10638 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10639 (ior:DI (ashift:DI (match_dup 0)
10640 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10641 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10642 (minus:QI (const_int 64) (match_dup 2)))))
10643 (clobber (reg:CC FLAGS_REG))]
10646 shld{q}\t{%2, %1, %0|%0, %1, %2}
10647 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10648 [(set_attr "type" "ishift")
10649 (set_attr "prefix_0f" "1")
10650 (set_attr "mode" "DI")
10651 (set_attr "athlon_decode" "vector")
10652 (set_attr "amdfam10_decode" "vector")])
10654 (define_expand "x86_64_shift_adj"
10655 [(set (reg:CCZ FLAGS_REG)
10656 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10659 (set (match_operand:DI 0 "register_operand" "")
10660 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10661 (match_operand:DI 1 "register_operand" "")
10664 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10665 (match_operand:DI 3 "register_operand" "r")
10670 (define_expand "ashldi3"
10671 [(set (match_operand:DI 0 "shiftdi_operand" "")
10672 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10673 (match_operand:QI 2 "nonmemory_operand" "")))]
10675 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10677 (define_insn "*ashldi3_1_rex64"
10678 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10679 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10680 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10681 (clobber (reg:CC FLAGS_REG))]
10682 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10684 switch (get_attr_type (insn))
10687 gcc_assert (operands[2] == const1_rtx);
10688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10689 return "add{q}\t{%0, %0|%0, %0}";
10692 gcc_assert (CONST_INT_P (operands[2]));
10693 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10694 operands[1] = gen_rtx_MULT (DImode, operands[1],
10695 GEN_INT (1 << INTVAL (operands[2])));
10696 return "lea{q}\t{%a1, %0|%0, %a1}";
10699 if (REG_P (operands[2]))
10700 return "sal{q}\t{%b2, %0|%0, %b2}";
10701 else if (operands[2] == const1_rtx
10702 && (TARGET_SHIFT1 || optimize_size))
10703 return "sal{q}\t%0";
10705 return "sal{q}\t{%2, %0|%0, %2}";
10708 [(set (attr "type")
10709 (cond [(eq_attr "alternative" "1")
10710 (const_string "lea")
10711 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10713 (match_operand 0 "register_operand" ""))
10714 (match_operand 2 "const1_operand" ""))
10715 (const_string "alu")
10717 (const_string "ishift")))
10718 (set_attr "mode" "DI")])
10720 ;; Convert lea to the lea pattern to avoid flags dependency.
10722 [(set (match_operand:DI 0 "register_operand" "")
10723 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10724 (match_operand:QI 2 "immediate_operand" "")))
10725 (clobber (reg:CC FLAGS_REG))]
10726 "TARGET_64BIT && reload_completed
10727 && true_regnum (operands[0]) != true_regnum (operands[1])"
10728 [(set (match_dup 0)
10729 (mult:DI (match_dup 1)
10731 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10733 ;; This pattern can't accept a variable shift count, since shifts by
10734 ;; zero don't affect the flags. We assume that shifts by constant
10735 ;; zero are optimized away.
10736 (define_insn "*ashldi3_cmp_rex64"
10737 [(set (reg FLAGS_REG)
10739 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10740 (match_operand:QI 2 "immediate_operand" "e"))
10742 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10743 (ashift:DI (match_dup 1) (match_dup 2)))]
10744 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10745 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10747 || !TARGET_PARTIAL_FLAG_REG_STALL
10748 || (operands[2] == const1_rtx
10750 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10752 switch (get_attr_type (insn))
10755 gcc_assert (operands[2] == const1_rtx);
10756 return "add{q}\t{%0, %0|%0, %0}";
10759 if (REG_P (operands[2]))
10760 return "sal{q}\t{%b2, %0|%0, %b2}";
10761 else if (operands[2] == const1_rtx
10762 && (TARGET_SHIFT1 || optimize_size))
10763 return "sal{q}\t%0";
10765 return "sal{q}\t{%2, %0|%0, %2}";
10768 [(set (attr "type")
10769 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10771 (match_operand 0 "register_operand" ""))
10772 (match_operand 2 "const1_operand" ""))
10773 (const_string "alu")
10775 (const_string "ishift")))
10776 (set_attr "mode" "DI")])
10778 (define_insn "*ashldi3_cconly_rex64"
10779 [(set (reg FLAGS_REG)
10781 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10782 (match_operand:QI 2 "immediate_operand" "e"))
10784 (clobber (match_scratch:DI 0 "=r"))]
10785 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10786 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10788 || !TARGET_PARTIAL_FLAG_REG_STALL
10789 || (operands[2] == const1_rtx
10791 || TARGET_DOUBLE_WITH_ADD)))"
10793 switch (get_attr_type (insn))
10796 gcc_assert (operands[2] == const1_rtx);
10797 return "add{q}\t{%0, %0|%0, %0}";
10800 if (REG_P (operands[2]))
10801 return "sal{q}\t{%b2, %0|%0, %b2}";
10802 else if (operands[2] == const1_rtx
10803 && (TARGET_SHIFT1 || optimize_size))
10804 return "sal{q}\t%0";
10806 return "sal{q}\t{%2, %0|%0, %2}";
10809 [(set (attr "type")
10810 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10812 (match_operand 0 "register_operand" ""))
10813 (match_operand 2 "const1_operand" ""))
10814 (const_string "alu")
10816 (const_string "ishift")))
10817 (set_attr "mode" "DI")])
10819 (define_insn "*ashldi3_1"
10820 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10821 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10822 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10823 (clobber (reg:CC FLAGS_REG))]
10826 [(set_attr "type" "multi")])
10828 ;; By default we don't ask for a scratch register, because when DImode
10829 ;; values are manipulated, registers are already at a premium. But if
10830 ;; we have one handy, we won't turn it away.
10832 [(match_scratch:SI 3 "r")
10833 (parallel [(set (match_operand:DI 0 "register_operand" "")
10834 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10835 (match_operand:QI 2 "nonmemory_operand" "")))
10836 (clobber (reg:CC FLAGS_REG))])
10838 "!TARGET_64BIT && TARGET_CMOVE"
10840 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10843 [(set (match_operand:DI 0 "register_operand" "")
10844 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10845 (match_operand:QI 2 "nonmemory_operand" "")))
10846 (clobber (reg:CC FLAGS_REG))]
10847 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10848 ? flow2_completed : reload_completed)"
10850 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10852 (define_insn "x86_shld_1"
10853 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10854 (ior:SI (ashift:SI (match_dup 0)
10855 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10856 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10857 (minus:QI (const_int 32) (match_dup 2)))))
10858 (clobber (reg:CC FLAGS_REG))]
10861 shld{l}\t{%2, %1, %0|%0, %1, %2}
10862 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10863 [(set_attr "type" "ishift")
10864 (set_attr "prefix_0f" "1")
10865 (set_attr "mode" "SI")
10866 (set_attr "pent_pair" "np")
10867 (set_attr "athlon_decode" "vector")
10868 (set_attr "amdfam10_decode" "vector")])
10870 (define_expand "x86_shift_adj_1"
10871 [(set (reg:CCZ FLAGS_REG)
10872 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10875 (set (match_operand:SI 0 "register_operand" "")
10876 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10877 (match_operand:SI 1 "register_operand" "")
10880 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10881 (match_operand:SI 3 "register_operand" "r")
10886 (define_expand "x86_shift_adj_2"
10887 [(use (match_operand:SI 0 "register_operand" ""))
10888 (use (match_operand:SI 1 "register_operand" ""))
10889 (use (match_operand:QI 2 "register_operand" ""))]
10892 rtx label = gen_label_rtx ();
10895 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10897 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10898 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10899 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10900 gen_rtx_LABEL_REF (VOIDmode, label),
10902 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10903 JUMP_LABEL (tmp) = label;
10905 emit_move_insn (operands[0], operands[1]);
10906 ix86_expand_clear (operands[1]);
10908 emit_label (label);
10909 LABEL_NUSES (label) = 1;
10914 (define_expand "ashlsi3"
10915 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10916 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10917 (match_operand:QI 2 "nonmemory_operand" "")))
10918 (clobber (reg:CC FLAGS_REG))]
10920 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10922 (define_insn "*ashlsi3_1"
10923 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10924 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10925 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10929 switch (get_attr_type (insn))
10932 gcc_assert (operands[2] == const1_rtx);
10933 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10934 return "add{l}\t{%0, %0|%0, %0}";
10940 if (REG_P (operands[2]))
10941 return "sal{l}\t{%b2, %0|%0, %b2}";
10942 else if (operands[2] == const1_rtx
10943 && (TARGET_SHIFT1 || optimize_size))
10944 return "sal{l}\t%0";
10946 return "sal{l}\t{%2, %0|%0, %2}";
10949 [(set (attr "type")
10950 (cond [(eq_attr "alternative" "1")
10951 (const_string "lea")
10952 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10954 (match_operand 0 "register_operand" ""))
10955 (match_operand 2 "const1_operand" ""))
10956 (const_string "alu")
10958 (const_string "ishift")))
10959 (set_attr "mode" "SI")])
10961 ;; Convert lea to the lea pattern to avoid flags dependency.
10963 [(set (match_operand 0 "register_operand" "")
10964 (ashift (match_operand 1 "index_register_operand" "")
10965 (match_operand:QI 2 "const_int_operand" "")))
10966 (clobber (reg:CC FLAGS_REG))]
10968 && true_regnum (operands[0]) != true_regnum (operands[1])
10969 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10973 enum machine_mode mode = GET_MODE (operands[0]);
10975 if (GET_MODE_SIZE (mode) < 4)
10976 operands[0] = gen_lowpart (SImode, operands[0]);
10978 operands[1] = gen_lowpart (Pmode, operands[1]);
10979 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10981 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10982 if (Pmode != SImode)
10983 pat = gen_rtx_SUBREG (SImode, pat, 0);
10984 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10988 ;; Rare case of shifting RSP is handled by generating move and shift
10990 [(set (match_operand 0 "register_operand" "")
10991 (ashift (match_operand 1 "register_operand" "")
10992 (match_operand:QI 2 "const_int_operand" "")))
10993 (clobber (reg:CC FLAGS_REG))]
10995 && true_regnum (operands[0]) != true_regnum (operands[1])"
10999 emit_move_insn (operands[0], operands[1]);
11000 pat = gen_rtx_SET (VOIDmode, operands[0],
11001 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11002 operands[0], operands[2]));
11003 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11004 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11008 (define_insn "*ashlsi3_1_zext"
11009 [(set (match_operand:DI 0 "register_operand" "=r,r")
11010 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11011 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11012 (clobber (reg:CC FLAGS_REG))]
11013 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11015 switch (get_attr_type (insn))
11018 gcc_assert (operands[2] == const1_rtx);
11019 return "add{l}\t{%k0, %k0|%k0, %k0}";
11025 if (REG_P (operands[2]))
11026 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11027 else if (operands[2] == const1_rtx
11028 && (TARGET_SHIFT1 || optimize_size))
11029 return "sal{l}\t%k0";
11031 return "sal{l}\t{%2, %k0|%k0, %2}";
11034 [(set (attr "type")
11035 (cond [(eq_attr "alternative" "1")
11036 (const_string "lea")
11037 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11039 (match_operand 2 "const1_operand" ""))
11040 (const_string "alu")
11042 (const_string "ishift")))
11043 (set_attr "mode" "SI")])
11045 ;; Convert lea to the lea pattern to avoid flags dependency.
11047 [(set (match_operand:DI 0 "register_operand" "")
11048 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11049 (match_operand:QI 2 "const_int_operand" ""))))
11050 (clobber (reg:CC FLAGS_REG))]
11051 "TARGET_64BIT && reload_completed
11052 && true_regnum (operands[0]) != true_regnum (operands[1])"
11053 [(set (match_dup 0) (zero_extend:DI
11054 (subreg:SI (mult:SI (match_dup 1)
11055 (match_dup 2)) 0)))]
11057 operands[1] = gen_lowpart (Pmode, operands[1]);
11058 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11061 ;; This pattern can't accept a variable shift count, since shifts by
11062 ;; zero don't affect the flags. We assume that shifts by constant
11063 ;; zero are optimized away.
11064 (define_insn "*ashlsi3_cmp"
11065 [(set (reg FLAGS_REG)
11067 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11068 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11070 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11071 (ashift:SI (match_dup 1) (match_dup 2)))]
11072 "ix86_match_ccmode (insn, CCGOCmode)
11073 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11075 || !TARGET_PARTIAL_FLAG_REG_STALL
11076 || (operands[2] == const1_rtx
11078 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11080 switch (get_attr_type (insn))
11083 gcc_assert (operands[2] == const1_rtx);
11084 return "add{l}\t{%0, %0|%0, %0}";
11087 if (REG_P (operands[2]))
11088 return "sal{l}\t{%b2, %0|%0, %b2}";
11089 else if (operands[2] == const1_rtx
11090 && (TARGET_SHIFT1 || optimize_size))
11091 return "sal{l}\t%0";
11093 return "sal{l}\t{%2, %0|%0, %2}";
11096 [(set (attr "type")
11097 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11099 (match_operand 0 "register_operand" ""))
11100 (match_operand 2 "const1_operand" ""))
11101 (const_string "alu")
11103 (const_string "ishift")))
11104 (set_attr "mode" "SI")])
11106 (define_insn "*ashlsi3_cconly"
11107 [(set (reg FLAGS_REG)
11109 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11110 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11112 (clobber (match_scratch:SI 0 "=r"))]
11113 "ix86_match_ccmode (insn, CCGOCmode)
11114 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11116 || !TARGET_PARTIAL_FLAG_REG_STALL
11117 || (operands[2] == const1_rtx
11119 || TARGET_DOUBLE_WITH_ADD)))"
11121 switch (get_attr_type (insn))
11124 gcc_assert (operands[2] == const1_rtx);
11125 return "add{l}\t{%0, %0|%0, %0}";
11128 if (REG_P (operands[2]))
11129 return "sal{l}\t{%b2, %0|%0, %b2}";
11130 else if (operands[2] == const1_rtx
11131 && (TARGET_SHIFT1 || optimize_size))
11132 return "sal{l}\t%0";
11134 return "sal{l}\t{%2, %0|%0, %2}";
11137 [(set (attr "type")
11138 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11140 (match_operand 0 "register_operand" ""))
11141 (match_operand 2 "const1_operand" ""))
11142 (const_string "alu")
11144 (const_string "ishift")))
11145 (set_attr "mode" "SI")])
11147 (define_insn "*ashlsi3_cmp_zext"
11148 [(set (reg FLAGS_REG)
11150 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11151 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11153 (set (match_operand:DI 0 "register_operand" "=r")
11154 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11155 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11158 || !TARGET_PARTIAL_FLAG_REG_STALL
11159 || (operands[2] == const1_rtx
11161 || TARGET_DOUBLE_WITH_ADD)))"
11163 switch (get_attr_type (insn))
11166 gcc_assert (operands[2] == const1_rtx);
11167 return "add{l}\t{%k0, %k0|%k0, %k0}";
11170 if (REG_P (operands[2]))
11171 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11172 else if (operands[2] == const1_rtx
11173 && (TARGET_SHIFT1 || optimize_size))
11174 return "sal{l}\t%k0";
11176 return "sal{l}\t{%2, %k0|%k0, %2}";
11179 [(set (attr "type")
11180 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11182 (match_operand 2 "const1_operand" ""))
11183 (const_string "alu")
11185 (const_string "ishift")))
11186 (set_attr "mode" "SI")])
11188 (define_expand "ashlhi3"
11189 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11190 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11191 (match_operand:QI 2 "nonmemory_operand" "")))
11192 (clobber (reg:CC FLAGS_REG))]
11193 "TARGET_HIMODE_MATH"
11194 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11196 (define_insn "*ashlhi3_1_lea"
11197 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11198 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11199 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11200 (clobber (reg:CC FLAGS_REG))]
11201 "!TARGET_PARTIAL_REG_STALL
11202 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11204 switch (get_attr_type (insn))
11209 gcc_assert (operands[2] == const1_rtx);
11210 return "add{w}\t{%0, %0|%0, %0}";
11213 if (REG_P (operands[2]))
11214 return "sal{w}\t{%b2, %0|%0, %b2}";
11215 else if (operands[2] == const1_rtx
11216 && (TARGET_SHIFT1 || optimize_size))
11217 return "sal{w}\t%0";
11219 return "sal{w}\t{%2, %0|%0, %2}";
11222 [(set (attr "type")
11223 (cond [(eq_attr "alternative" "1")
11224 (const_string "lea")
11225 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11227 (match_operand 0 "register_operand" ""))
11228 (match_operand 2 "const1_operand" ""))
11229 (const_string "alu")
11231 (const_string "ishift")))
11232 (set_attr "mode" "HI,SI")])
11234 (define_insn "*ashlhi3_1"
11235 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11236 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11237 (match_operand:QI 2 "nonmemory_operand" "cI")))
11238 (clobber (reg:CC FLAGS_REG))]
11239 "TARGET_PARTIAL_REG_STALL
11240 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11242 switch (get_attr_type (insn))
11245 gcc_assert (operands[2] == const1_rtx);
11246 return "add{w}\t{%0, %0|%0, %0}";
11249 if (REG_P (operands[2]))
11250 return "sal{w}\t{%b2, %0|%0, %b2}";
11251 else if (operands[2] == const1_rtx
11252 && (TARGET_SHIFT1 || optimize_size))
11253 return "sal{w}\t%0";
11255 return "sal{w}\t{%2, %0|%0, %2}";
11258 [(set (attr "type")
11259 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11261 (match_operand 0 "register_operand" ""))
11262 (match_operand 2 "const1_operand" ""))
11263 (const_string "alu")
11265 (const_string "ishift")))
11266 (set_attr "mode" "HI")])
11268 ;; This pattern can't accept a variable shift count, since shifts by
11269 ;; zero don't affect the flags. We assume that shifts by constant
11270 ;; zero are optimized away.
11271 (define_insn "*ashlhi3_cmp"
11272 [(set (reg FLAGS_REG)
11274 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11275 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11277 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11278 (ashift:HI (match_dup 1) (match_dup 2)))]
11279 "ix86_match_ccmode (insn, CCGOCmode)
11280 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11282 || !TARGET_PARTIAL_FLAG_REG_STALL
11283 || (operands[2] == const1_rtx
11285 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11287 switch (get_attr_type (insn))
11290 gcc_assert (operands[2] == const1_rtx);
11291 return "add{w}\t{%0, %0|%0, %0}";
11294 if (REG_P (operands[2]))
11295 return "sal{w}\t{%b2, %0|%0, %b2}";
11296 else if (operands[2] == const1_rtx
11297 && (TARGET_SHIFT1 || optimize_size))
11298 return "sal{w}\t%0";
11300 return "sal{w}\t{%2, %0|%0, %2}";
11303 [(set (attr "type")
11304 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11306 (match_operand 0 "register_operand" ""))
11307 (match_operand 2 "const1_operand" ""))
11308 (const_string "alu")
11310 (const_string "ishift")))
11311 (set_attr "mode" "HI")])
11313 (define_insn "*ashlhi3_cconly"
11314 [(set (reg FLAGS_REG)
11316 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11317 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11319 (clobber (match_scratch:HI 0 "=r"))]
11320 "ix86_match_ccmode (insn, CCGOCmode)
11321 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11323 || !TARGET_PARTIAL_FLAG_REG_STALL
11324 || (operands[2] == const1_rtx
11326 || TARGET_DOUBLE_WITH_ADD)))"
11328 switch (get_attr_type (insn))
11331 gcc_assert (operands[2] == const1_rtx);
11332 return "add{w}\t{%0, %0|%0, %0}";
11335 if (REG_P (operands[2]))
11336 return "sal{w}\t{%b2, %0|%0, %b2}";
11337 else if (operands[2] == const1_rtx
11338 && (TARGET_SHIFT1 || optimize_size))
11339 return "sal{w}\t%0";
11341 return "sal{w}\t{%2, %0|%0, %2}";
11344 [(set (attr "type")
11345 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11347 (match_operand 0 "register_operand" ""))
11348 (match_operand 2 "const1_operand" ""))
11349 (const_string "alu")
11351 (const_string "ishift")))
11352 (set_attr "mode" "HI")])
11354 (define_expand "ashlqi3"
11355 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11356 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11357 (match_operand:QI 2 "nonmemory_operand" "")))
11358 (clobber (reg:CC FLAGS_REG))]
11359 "TARGET_QIMODE_MATH"
11360 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11362 ;; %%% Potential partial reg stall on alternative 2. What to do?
11364 (define_insn "*ashlqi3_1_lea"
11365 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11366 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11367 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11368 (clobber (reg:CC FLAGS_REG))]
11369 "!TARGET_PARTIAL_REG_STALL
11370 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11372 switch (get_attr_type (insn))
11377 gcc_assert (operands[2] == const1_rtx);
11378 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11379 return "add{l}\t{%k0, %k0|%k0, %k0}";
11381 return "add{b}\t{%0, %0|%0, %0}";
11384 if (REG_P (operands[2]))
11386 if (get_attr_mode (insn) == MODE_SI)
11387 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11389 return "sal{b}\t{%b2, %0|%0, %b2}";
11391 else if (operands[2] == const1_rtx
11392 && (TARGET_SHIFT1 || optimize_size))
11394 if (get_attr_mode (insn) == MODE_SI)
11395 return "sal{l}\t%0";
11397 return "sal{b}\t%0";
11401 if (get_attr_mode (insn) == MODE_SI)
11402 return "sal{l}\t{%2, %k0|%k0, %2}";
11404 return "sal{b}\t{%2, %0|%0, %2}";
11408 [(set (attr "type")
11409 (cond [(eq_attr "alternative" "2")
11410 (const_string "lea")
11411 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11413 (match_operand 0 "register_operand" ""))
11414 (match_operand 2 "const1_operand" ""))
11415 (const_string "alu")
11417 (const_string "ishift")))
11418 (set_attr "mode" "QI,SI,SI")])
11420 (define_insn "*ashlqi3_1"
11421 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11422 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11423 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11424 (clobber (reg:CC FLAGS_REG))]
11425 "TARGET_PARTIAL_REG_STALL
11426 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11428 switch (get_attr_type (insn))
11431 gcc_assert (operands[2] == const1_rtx);
11432 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11433 return "add{l}\t{%k0, %k0|%k0, %k0}";
11435 return "add{b}\t{%0, %0|%0, %0}";
11438 if (REG_P (operands[2]))
11440 if (get_attr_mode (insn) == MODE_SI)
11441 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11443 return "sal{b}\t{%b2, %0|%0, %b2}";
11445 else if (operands[2] == const1_rtx
11446 && (TARGET_SHIFT1 || optimize_size))
11448 if (get_attr_mode (insn) == MODE_SI)
11449 return "sal{l}\t%0";
11451 return "sal{b}\t%0";
11455 if (get_attr_mode (insn) == MODE_SI)
11456 return "sal{l}\t{%2, %k0|%k0, %2}";
11458 return "sal{b}\t{%2, %0|%0, %2}";
11462 [(set (attr "type")
11463 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11465 (match_operand 0 "register_operand" ""))
11466 (match_operand 2 "const1_operand" ""))
11467 (const_string "alu")
11469 (const_string "ishift")))
11470 (set_attr "mode" "QI,SI")])
11472 ;; This pattern can't accept a variable shift count, since shifts by
11473 ;; zero don't affect the flags. We assume that shifts by constant
11474 ;; zero are optimized away.
11475 (define_insn "*ashlqi3_cmp"
11476 [(set (reg FLAGS_REG)
11478 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11479 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11481 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11482 (ashift:QI (match_dup 1) (match_dup 2)))]
11483 "ix86_match_ccmode (insn, CCGOCmode)
11484 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11486 || !TARGET_PARTIAL_FLAG_REG_STALL
11487 || (operands[2] == const1_rtx
11489 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11491 switch (get_attr_type (insn))
11494 gcc_assert (operands[2] == const1_rtx);
11495 return "add{b}\t{%0, %0|%0, %0}";
11498 if (REG_P (operands[2]))
11499 return "sal{b}\t{%b2, %0|%0, %b2}";
11500 else if (operands[2] == const1_rtx
11501 && (TARGET_SHIFT1 || optimize_size))
11502 return "sal{b}\t%0";
11504 return "sal{b}\t{%2, %0|%0, %2}";
11507 [(set (attr "type")
11508 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11510 (match_operand 0 "register_operand" ""))
11511 (match_operand 2 "const1_operand" ""))
11512 (const_string "alu")
11514 (const_string "ishift")))
11515 (set_attr "mode" "QI")])
11517 (define_insn "*ashlqi3_cconly"
11518 [(set (reg FLAGS_REG)
11520 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11521 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11523 (clobber (match_scratch:QI 0 "=q"))]
11524 "ix86_match_ccmode (insn, CCGOCmode)
11525 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11527 || !TARGET_PARTIAL_FLAG_REG_STALL
11528 || (operands[2] == const1_rtx
11530 || TARGET_DOUBLE_WITH_ADD)))"
11532 switch (get_attr_type (insn))
11535 gcc_assert (operands[2] == const1_rtx);
11536 return "add{b}\t{%0, %0|%0, %0}";
11539 if (REG_P (operands[2]))
11540 return "sal{b}\t{%b2, %0|%0, %b2}";
11541 else if (operands[2] == const1_rtx
11542 && (TARGET_SHIFT1 || optimize_size))
11543 return "sal{b}\t%0";
11545 return "sal{b}\t{%2, %0|%0, %2}";
11548 [(set (attr "type")
11549 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11551 (match_operand 0 "register_operand" ""))
11552 (match_operand 2 "const1_operand" ""))
11553 (const_string "alu")
11555 (const_string "ishift")))
11556 (set_attr "mode" "QI")])
11558 ;; See comment above `ashldi3' about how this works.
11560 (define_expand "ashrti3"
11561 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11562 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11563 (match_operand:QI 2 "nonmemory_operand" "")))
11564 (clobber (reg:CC FLAGS_REG))])]
11567 if (! immediate_operand (operands[2], QImode))
11569 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11572 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11576 (define_insn "ashrti3_1"
11577 [(set (match_operand:TI 0 "register_operand" "=r")
11578 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11579 (match_operand:QI 2 "register_operand" "c")))
11580 (clobber (match_scratch:DI 3 "=&r"))
11581 (clobber (reg:CC FLAGS_REG))]
11584 [(set_attr "type" "multi")])
11586 (define_insn "*ashrti3_2"
11587 [(set (match_operand:TI 0 "register_operand" "=r")
11588 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11589 (match_operand:QI 2 "immediate_operand" "O")))
11590 (clobber (reg:CC FLAGS_REG))]
11593 [(set_attr "type" "multi")])
11596 [(set (match_operand:TI 0 "register_operand" "")
11597 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11598 (match_operand:QI 2 "register_operand" "")))
11599 (clobber (match_scratch:DI 3 ""))
11600 (clobber (reg:CC FLAGS_REG))]
11601 "TARGET_64BIT && reload_completed"
11603 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11606 [(set (match_operand:TI 0 "register_operand" "")
11607 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11608 (match_operand:QI 2 "immediate_operand" "")))
11609 (clobber (reg:CC FLAGS_REG))]
11610 "TARGET_64BIT && reload_completed"
11612 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11614 (define_insn "x86_64_shrd"
11615 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11616 (ior:DI (ashiftrt:DI (match_dup 0)
11617 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11618 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11619 (minus:QI (const_int 64) (match_dup 2)))))
11620 (clobber (reg:CC FLAGS_REG))]
11623 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11624 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11625 [(set_attr "type" "ishift")
11626 (set_attr "prefix_0f" "1")
11627 (set_attr "mode" "DI")
11628 (set_attr "athlon_decode" "vector")
11629 (set_attr "amdfam10_decode" "vector")])
11631 (define_expand "ashrdi3"
11632 [(set (match_operand:DI 0 "shiftdi_operand" "")
11633 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11634 (match_operand:QI 2 "nonmemory_operand" "")))]
11636 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11638 (define_insn "*ashrdi3_63_rex64"
11639 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11640 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11641 (match_operand:DI 2 "const_int_operand" "i,i")))
11642 (clobber (reg:CC FLAGS_REG))]
11643 "TARGET_64BIT && INTVAL (operands[2]) == 63
11644 && (TARGET_USE_CLTD || optimize_size)
11645 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11648 sar{q}\t{%2, %0|%0, %2}"
11649 [(set_attr "type" "imovx,ishift")
11650 (set_attr "prefix_0f" "0,*")
11651 (set_attr "length_immediate" "0,*")
11652 (set_attr "modrm" "0,1")
11653 (set_attr "mode" "DI")])
11655 (define_insn "*ashrdi3_1_one_bit_rex64"
11656 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11657 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11658 (match_operand:QI 2 "const1_operand" "")))
11659 (clobber (reg:CC FLAGS_REG))]
11660 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11661 && (TARGET_SHIFT1 || optimize_size)"
11663 [(set_attr "type" "ishift")
11664 (set (attr "length")
11665 (if_then_else (match_operand:DI 0 "register_operand" "")
11667 (const_string "*")))])
11669 (define_insn "*ashrdi3_1_rex64"
11670 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11671 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11672 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11673 (clobber (reg:CC FLAGS_REG))]
11674 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11676 sar{q}\t{%2, %0|%0, %2}
11677 sar{q}\t{%b2, %0|%0, %b2}"
11678 [(set_attr "type" "ishift")
11679 (set_attr "mode" "DI")])
11681 ;; This pattern can't accept a variable shift count, since shifts by
11682 ;; zero don't affect the flags. We assume that shifts by constant
11683 ;; zero are optimized away.
11684 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11685 [(set (reg FLAGS_REG)
11687 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11688 (match_operand:QI 2 "const1_operand" ""))
11690 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11691 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11692 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11693 && (TARGET_SHIFT1 || optimize_size)
11694 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11696 [(set_attr "type" "ishift")
11697 (set (attr "length")
11698 (if_then_else (match_operand:DI 0 "register_operand" "")
11700 (const_string "*")))])
11702 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11703 [(set (reg FLAGS_REG)
11705 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11706 (match_operand:QI 2 "const1_operand" ""))
11708 (clobber (match_scratch:DI 0 "=r"))]
11709 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11710 && (TARGET_SHIFT1 || optimize_size)
11711 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11713 [(set_attr "type" "ishift")
11714 (set_attr "length" "2")])
11716 ;; This pattern can't accept a variable shift count, since shifts by
11717 ;; zero don't affect the flags. We assume that shifts by constant
11718 ;; zero are optimized away.
11719 (define_insn "*ashrdi3_cmp_rex64"
11720 [(set (reg FLAGS_REG)
11722 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11723 (match_operand:QI 2 "const_int_operand" "n"))
11725 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11726 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11727 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11728 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11730 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11731 "sar{q}\t{%2, %0|%0, %2}"
11732 [(set_attr "type" "ishift")
11733 (set_attr "mode" "DI")])
11735 (define_insn "*ashrdi3_cconly_rex64"
11736 [(set (reg FLAGS_REG)
11738 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11739 (match_operand:QI 2 "const_int_operand" "n"))
11741 (clobber (match_scratch:DI 0 "=r"))]
11742 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11743 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11745 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11746 "sar{q}\t{%2, %0|%0, %2}"
11747 [(set_attr "type" "ishift")
11748 (set_attr "mode" "DI")])
11750 (define_insn "*ashrdi3_1"
11751 [(set (match_operand:DI 0 "register_operand" "=r")
11752 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11753 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11754 (clobber (reg:CC FLAGS_REG))]
11757 [(set_attr "type" "multi")])
11759 ;; By default we don't ask for a scratch register, because when DImode
11760 ;; values are manipulated, registers are already at a premium. But if
11761 ;; we have one handy, we won't turn it away.
11763 [(match_scratch:SI 3 "r")
11764 (parallel [(set (match_operand:DI 0 "register_operand" "")
11765 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11766 (match_operand:QI 2 "nonmemory_operand" "")))
11767 (clobber (reg:CC FLAGS_REG))])
11769 "!TARGET_64BIT && TARGET_CMOVE"
11771 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11774 [(set (match_operand:DI 0 "register_operand" "")
11775 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11776 (match_operand:QI 2 "nonmemory_operand" "")))
11777 (clobber (reg:CC FLAGS_REG))]
11778 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11779 ? flow2_completed : reload_completed)"
11781 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11783 (define_insn "x86_shrd_1"
11784 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11785 (ior:SI (ashiftrt:SI (match_dup 0)
11786 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11787 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11788 (minus:QI (const_int 32) (match_dup 2)))))
11789 (clobber (reg:CC FLAGS_REG))]
11792 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11793 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11794 [(set_attr "type" "ishift")
11795 (set_attr "prefix_0f" "1")
11796 (set_attr "pent_pair" "np")
11797 (set_attr "mode" "SI")])
11799 (define_expand "x86_shift_adj_3"
11800 [(use (match_operand:SI 0 "register_operand" ""))
11801 (use (match_operand:SI 1 "register_operand" ""))
11802 (use (match_operand:QI 2 "register_operand" ""))]
11805 rtx label = gen_label_rtx ();
11808 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11810 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11811 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11812 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11813 gen_rtx_LABEL_REF (VOIDmode, label),
11815 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11816 JUMP_LABEL (tmp) = label;
11818 emit_move_insn (operands[0], operands[1]);
11819 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11821 emit_label (label);
11822 LABEL_NUSES (label) = 1;
11827 (define_insn "ashrsi3_31"
11828 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11829 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11830 (match_operand:SI 2 "const_int_operand" "i,i")))
11831 (clobber (reg:CC FLAGS_REG))]
11832 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11833 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11836 sar{l}\t{%2, %0|%0, %2}"
11837 [(set_attr "type" "imovx,ishift")
11838 (set_attr "prefix_0f" "0,*")
11839 (set_attr "length_immediate" "0,*")
11840 (set_attr "modrm" "0,1")
11841 (set_attr "mode" "SI")])
11843 (define_insn "*ashrsi3_31_zext"
11844 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11845 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11846 (match_operand:SI 2 "const_int_operand" "i,i"))))
11847 (clobber (reg:CC FLAGS_REG))]
11848 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11849 && INTVAL (operands[2]) == 31
11850 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11853 sar{l}\t{%2, %k0|%k0, %2}"
11854 [(set_attr "type" "imovx,ishift")
11855 (set_attr "prefix_0f" "0,*")
11856 (set_attr "length_immediate" "0,*")
11857 (set_attr "modrm" "0,1")
11858 (set_attr "mode" "SI")])
11860 (define_expand "ashrsi3"
11861 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11862 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11863 (match_operand:QI 2 "nonmemory_operand" "")))
11864 (clobber (reg:CC FLAGS_REG))]
11866 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11868 (define_insn "*ashrsi3_1_one_bit"
11869 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11870 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11871 (match_operand:QI 2 "const1_operand" "")))
11872 (clobber (reg:CC FLAGS_REG))]
11873 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11874 && (TARGET_SHIFT1 || optimize_size)"
11876 [(set_attr "type" "ishift")
11877 (set (attr "length")
11878 (if_then_else (match_operand:SI 0 "register_operand" "")
11880 (const_string "*")))])
11882 (define_insn "*ashrsi3_1_one_bit_zext"
11883 [(set (match_operand:DI 0 "register_operand" "=r")
11884 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11885 (match_operand:QI 2 "const1_operand" ""))))
11886 (clobber (reg:CC FLAGS_REG))]
11887 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11888 && (TARGET_SHIFT1 || optimize_size)"
11890 [(set_attr "type" "ishift")
11891 (set_attr "length" "2")])
11893 (define_insn "*ashrsi3_1"
11894 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11895 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11896 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11897 (clobber (reg:CC FLAGS_REG))]
11898 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11900 sar{l}\t{%2, %0|%0, %2}
11901 sar{l}\t{%b2, %0|%0, %b2}"
11902 [(set_attr "type" "ishift")
11903 (set_attr "mode" "SI")])
11905 (define_insn "*ashrsi3_1_zext"
11906 [(set (match_operand:DI 0 "register_operand" "=r,r")
11907 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11908 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11909 (clobber (reg:CC FLAGS_REG))]
11910 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11912 sar{l}\t{%2, %k0|%k0, %2}
11913 sar{l}\t{%b2, %k0|%k0, %b2}"
11914 [(set_attr "type" "ishift")
11915 (set_attr "mode" "SI")])
11917 ;; This pattern can't accept a variable shift count, since shifts by
11918 ;; zero don't affect the flags. We assume that shifts by constant
11919 ;; zero are optimized away.
11920 (define_insn "*ashrsi3_one_bit_cmp"
11921 [(set (reg FLAGS_REG)
11923 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11924 (match_operand:QI 2 "const1_operand" ""))
11926 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11927 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11928 "ix86_match_ccmode (insn, CCGOCmode)
11929 && (TARGET_SHIFT1 || optimize_size)
11930 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11932 [(set_attr "type" "ishift")
11933 (set (attr "length")
11934 (if_then_else (match_operand:SI 0 "register_operand" "")
11936 (const_string "*")))])
11938 (define_insn "*ashrsi3_one_bit_cconly"
11939 [(set (reg FLAGS_REG)
11941 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11942 (match_operand:QI 2 "const1_operand" ""))
11944 (clobber (match_scratch:SI 0 "=r"))]
11945 "ix86_match_ccmode (insn, CCGOCmode)
11946 && (TARGET_SHIFT1 || optimize_size)
11947 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11949 [(set_attr "type" "ishift")
11950 (set_attr "length" "2")])
11952 (define_insn "*ashrsi3_one_bit_cmp_zext"
11953 [(set (reg FLAGS_REG)
11955 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11956 (match_operand:QI 2 "const1_operand" ""))
11958 (set (match_operand:DI 0 "register_operand" "=r")
11959 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11960 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11961 && (TARGET_SHIFT1 || optimize_size)
11962 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11964 [(set_attr "type" "ishift")
11965 (set_attr "length" "2")])
11967 ;; This pattern can't accept a variable shift count, since shifts by
11968 ;; zero don't affect the flags. We assume that shifts by constant
11969 ;; zero are optimized away.
11970 (define_insn "*ashrsi3_cmp"
11971 [(set (reg FLAGS_REG)
11973 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11974 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11976 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11977 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11978 "ix86_match_ccmode (insn, CCGOCmode)
11979 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11981 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11982 "sar{l}\t{%2, %0|%0, %2}"
11983 [(set_attr "type" "ishift")
11984 (set_attr "mode" "SI")])
11986 (define_insn "*ashrsi3_cconly"
11987 [(set (reg FLAGS_REG)
11989 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11990 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11992 (clobber (match_scratch:SI 0 "=r"))]
11993 "ix86_match_ccmode (insn, CCGOCmode)
11994 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11996 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11997 "sar{l}\t{%2, %0|%0, %2}"
11998 [(set_attr "type" "ishift")
11999 (set_attr "mode" "SI")])
12001 (define_insn "*ashrsi3_cmp_zext"
12002 [(set (reg FLAGS_REG)
12004 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12005 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12007 (set (match_operand:DI 0 "register_operand" "=r")
12008 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12009 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12010 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12012 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12013 "sar{l}\t{%2, %k0|%k0, %2}"
12014 [(set_attr "type" "ishift")
12015 (set_attr "mode" "SI")])
12017 (define_expand "ashrhi3"
12018 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12019 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12020 (match_operand:QI 2 "nonmemory_operand" "")))
12021 (clobber (reg:CC FLAGS_REG))]
12022 "TARGET_HIMODE_MATH"
12023 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12025 (define_insn "*ashrhi3_1_one_bit"
12026 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12027 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12028 (match_operand:QI 2 "const1_operand" "")))
12029 (clobber (reg:CC FLAGS_REG))]
12030 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12031 && (TARGET_SHIFT1 || optimize_size)"
12033 [(set_attr "type" "ishift")
12034 (set (attr "length")
12035 (if_then_else (match_operand 0 "register_operand" "")
12037 (const_string "*")))])
12039 (define_insn "*ashrhi3_1"
12040 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12041 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12042 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12043 (clobber (reg:CC FLAGS_REG))]
12044 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12046 sar{w}\t{%2, %0|%0, %2}
12047 sar{w}\t{%b2, %0|%0, %b2}"
12048 [(set_attr "type" "ishift")
12049 (set_attr "mode" "HI")])
12051 ;; This pattern can't accept a variable shift count, since shifts by
12052 ;; zero don't affect the flags. We assume that shifts by constant
12053 ;; zero are optimized away.
12054 (define_insn "*ashrhi3_one_bit_cmp"
12055 [(set (reg FLAGS_REG)
12057 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12058 (match_operand:QI 2 "const1_operand" ""))
12060 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12061 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12062 "ix86_match_ccmode (insn, CCGOCmode)
12063 && (TARGET_SHIFT1 || optimize_size)
12064 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12066 [(set_attr "type" "ishift")
12067 (set (attr "length")
12068 (if_then_else (match_operand 0 "register_operand" "")
12070 (const_string "*")))])
12072 (define_insn "*ashrhi3_one_bit_cconly"
12073 [(set (reg FLAGS_REG)
12075 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12076 (match_operand:QI 2 "const1_operand" ""))
12078 (clobber (match_scratch:HI 0 "=r"))]
12079 "ix86_match_ccmode (insn, CCGOCmode)
12080 && (TARGET_SHIFT1 || optimize_size)
12081 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12083 [(set_attr "type" "ishift")
12084 (set_attr "length" "2")])
12086 ;; This pattern can't accept a variable shift count, since shifts by
12087 ;; zero don't affect the flags. We assume that shifts by constant
12088 ;; zero are optimized away.
12089 (define_insn "*ashrhi3_cmp"
12090 [(set (reg FLAGS_REG)
12092 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12093 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12095 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12096 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12097 "ix86_match_ccmode (insn, CCGOCmode)
12098 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12100 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12101 "sar{w}\t{%2, %0|%0, %2}"
12102 [(set_attr "type" "ishift")
12103 (set_attr "mode" "HI")])
12105 (define_insn "*ashrhi3_cconly"
12106 [(set (reg FLAGS_REG)
12108 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12109 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12111 (clobber (match_scratch:HI 0 "=r"))]
12112 "ix86_match_ccmode (insn, CCGOCmode)
12113 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12115 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12116 "sar{w}\t{%2, %0|%0, %2}"
12117 [(set_attr "type" "ishift")
12118 (set_attr "mode" "HI")])
12120 (define_expand "ashrqi3"
12121 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12122 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12123 (match_operand:QI 2 "nonmemory_operand" "")))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "TARGET_QIMODE_MATH"
12126 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12128 (define_insn "*ashrqi3_1_one_bit"
12129 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12130 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12131 (match_operand:QI 2 "const1_operand" "")))
12132 (clobber (reg:CC FLAGS_REG))]
12133 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12134 && (TARGET_SHIFT1 || optimize_size)"
12136 [(set_attr "type" "ishift")
12137 (set (attr "length")
12138 (if_then_else (match_operand 0 "register_operand" "")
12140 (const_string "*")))])
12142 (define_insn "*ashrqi3_1_one_bit_slp"
12143 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12144 (ashiftrt:QI (match_dup 0)
12145 (match_operand:QI 1 "const1_operand" "")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12148 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12149 && (TARGET_SHIFT1 || optimize_size)"
12151 [(set_attr "type" "ishift1")
12152 (set (attr "length")
12153 (if_then_else (match_operand 0 "register_operand" "")
12155 (const_string "*")))])
12157 (define_insn "*ashrqi3_1"
12158 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12159 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12160 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12161 (clobber (reg:CC FLAGS_REG))]
12162 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12164 sar{b}\t{%2, %0|%0, %2}
12165 sar{b}\t{%b2, %0|%0, %b2}"
12166 [(set_attr "type" "ishift")
12167 (set_attr "mode" "QI")])
12169 (define_insn "*ashrqi3_1_slp"
12170 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12171 (ashiftrt:QI (match_dup 0)
12172 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12173 (clobber (reg:CC FLAGS_REG))]
12174 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12175 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12177 sar{b}\t{%1, %0|%0, %1}
12178 sar{b}\t{%b1, %0|%0, %b1}"
12179 [(set_attr "type" "ishift1")
12180 (set_attr "mode" "QI")])
12182 ;; This pattern can't accept a variable shift count, since shifts by
12183 ;; zero don't affect the flags. We assume that shifts by constant
12184 ;; zero are optimized away.
12185 (define_insn "*ashrqi3_one_bit_cmp"
12186 [(set (reg FLAGS_REG)
12188 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12189 (match_operand:QI 2 "const1_operand" "I"))
12191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12192 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12193 "ix86_match_ccmode (insn, CCGOCmode)
12194 && (TARGET_SHIFT1 || optimize_size)
12195 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12197 [(set_attr "type" "ishift")
12198 (set (attr "length")
12199 (if_then_else (match_operand 0 "register_operand" "")
12201 (const_string "*")))])
12203 (define_insn "*ashrqi3_one_bit_cconly"
12204 [(set (reg FLAGS_REG)
12206 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12207 (match_operand:QI 2 "const1_operand" "I"))
12209 (clobber (match_scratch:QI 0 "=q"))]
12210 "ix86_match_ccmode (insn, CCGOCmode)
12211 && (TARGET_SHIFT1 || optimize_size)
12212 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12214 [(set_attr "type" "ishift")
12215 (set_attr "length" "2")])
12217 ;; This pattern can't accept a variable shift count, since shifts by
12218 ;; zero don't affect the flags. We assume that shifts by constant
12219 ;; zero are optimized away.
12220 (define_insn "*ashrqi3_cmp"
12221 [(set (reg FLAGS_REG)
12223 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12224 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12226 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12227 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12228 "ix86_match_ccmode (insn, CCGOCmode)
12229 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12231 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12232 "sar{b}\t{%2, %0|%0, %2}"
12233 [(set_attr "type" "ishift")
12234 (set_attr "mode" "QI")])
12236 (define_insn "*ashrqi3_cconly"
12237 [(set (reg FLAGS_REG)
12239 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12240 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12242 (clobber (match_scratch:QI 0 "=q"))]
12243 "ix86_match_ccmode (insn, CCGOCmode)
12244 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12246 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12247 "sar{b}\t{%2, %0|%0, %2}"
12248 [(set_attr "type" "ishift")
12249 (set_attr "mode" "QI")])
12252 ;; Logical shift instructions
12254 ;; See comment above `ashldi3' about how this works.
12256 (define_expand "lshrti3"
12257 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12258 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12259 (match_operand:QI 2 "nonmemory_operand" "")))
12260 (clobber (reg:CC FLAGS_REG))])]
12263 if (! immediate_operand (operands[2], QImode))
12265 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12268 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12272 (define_insn "lshrti3_1"
12273 [(set (match_operand:TI 0 "register_operand" "=r")
12274 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12275 (match_operand:QI 2 "register_operand" "c")))
12276 (clobber (match_scratch:DI 3 "=&r"))
12277 (clobber (reg:CC FLAGS_REG))]
12280 [(set_attr "type" "multi")])
12282 (define_insn "*lshrti3_2"
12283 [(set (match_operand:TI 0 "register_operand" "=r")
12284 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12285 (match_operand:QI 2 "immediate_operand" "O")))
12286 (clobber (reg:CC FLAGS_REG))]
12289 [(set_attr "type" "multi")])
12292 [(set (match_operand:TI 0 "register_operand" "")
12293 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12294 (match_operand:QI 2 "register_operand" "")))
12295 (clobber (match_scratch:DI 3 ""))
12296 (clobber (reg:CC FLAGS_REG))]
12297 "TARGET_64BIT && reload_completed"
12299 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12302 [(set (match_operand:TI 0 "register_operand" "")
12303 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12304 (match_operand:QI 2 "immediate_operand" "")))
12305 (clobber (reg:CC FLAGS_REG))]
12306 "TARGET_64BIT && reload_completed"
12308 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12310 (define_expand "lshrdi3"
12311 [(set (match_operand:DI 0 "shiftdi_operand" "")
12312 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12313 (match_operand:QI 2 "nonmemory_operand" "")))]
12315 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12317 (define_insn "*lshrdi3_1_one_bit_rex64"
12318 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12319 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12320 (match_operand:QI 2 "const1_operand" "")))
12321 (clobber (reg:CC FLAGS_REG))]
12322 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12323 && (TARGET_SHIFT1 || optimize_size)"
12325 [(set_attr "type" "ishift")
12326 (set (attr "length")
12327 (if_then_else (match_operand:DI 0 "register_operand" "")
12329 (const_string "*")))])
12331 (define_insn "*lshrdi3_1_rex64"
12332 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12333 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12334 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12335 (clobber (reg:CC FLAGS_REG))]
12336 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12338 shr{q}\t{%2, %0|%0, %2}
12339 shr{q}\t{%b2, %0|%0, %b2}"
12340 [(set_attr "type" "ishift")
12341 (set_attr "mode" "DI")])
12343 ;; This pattern can't accept a variable shift count, since shifts by
12344 ;; zero don't affect the flags. We assume that shifts by constant
12345 ;; zero are optimized away.
12346 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12347 [(set (reg FLAGS_REG)
12349 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12350 (match_operand:QI 2 "const1_operand" ""))
12352 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12353 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12354 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12355 && (TARGET_SHIFT1 || optimize_size)
12356 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12358 [(set_attr "type" "ishift")
12359 (set (attr "length")
12360 (if_then_else (match_operand:DI 0 "register_operand" "")
12362 (const_string "*")))])
12364 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12365 [(set (reg FLAGS_REG)
12367 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const1_operand" ""))
12370 (clobber (match_scratch:DI 0 "=r"))]
12371 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12372 && (TARGET_SHIFT1 || optimize_size)
12373 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12375 [(set_attr "type" "ishift")
12376 (set_attr "length" "2")])
12378 ;; This pattern can't accept a variable shift count, since shifts by
12379 ;; zero don't affect the flags. We assume that shifts by constant
12380 ;; zero are optimized away.
12381 (define_insn "*lshrdi3_cmp_rex64"
12382 [(set (reg FLAGS_REG)
12384 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12385 (match_operand:QI 2 "const_int_operand" "e"))
12387 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12388 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12389 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12390 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12392 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12393 "shr{q}\t{%2, %0|%0, %2}"
12394 [(set_attr "type" "ishift")
12395 (set_attr "mode" "DI")])
12397 (define_insn "*lshrdi3_cconly_rex64"
12398 [(set (reg FLAGS_REG)
12400 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12401 (match_operand:QI 2 "const_int_operand" "e"))
12403 (clobber (match_scratch:DI 0 "=r"))]
12404 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12405 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12407 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12408 "shr{q}\t{%2, %0|%0, %2}"
12409 [(set_attr "type" "ishift")
12410 (set_attr "mode" "DI")])
12412 (define_insn "*lshrdi3_1"
12413 [(set (match_operand:DI 0 "register_operand" "=r")
12414 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12415 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12416 (clobber (reg:CC FLAGS_REG))]
12419 [(set_attr "type" "multi")])
12421 ;; By default we don't ask for a scratch register, because when DImode
12422 ;; values are manipulated, registers are already at a premium. But if
12423 ;; we have one handy, we won't turn it away.
12425 [(match_scratch:SI 3 "r")
12426 (parallel [(set (match_operand:DI 0 "register_operand" "")
12427 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12428 (match_operand:QI 2 "nonmemory_operand" "")))
12429 (clobber (reg:CC FLAGS_REG))])
12431 "!TARGET_64BIT && TARGET_CMOVE"
12433 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12436 [(set (match_operand:DI 0 "register_operand" "")
12437 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12438 (match_operand:QI 2 "nonmemory_operand" "")))
12439 (clobber (reg:CC FLAGS_REG))]
12440 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12441 ? flow2_completed : reload_completed)"
12443 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12445 (define_expand "lshrsi3"
12446 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12447 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12448 (match_operand:QI 2 "nonmemory_operand" "")))
12449 (clobber (reg:CC FLAGS_REG))]
12451 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12453 (define_insn "*lshrsi3_1_one_bit"
12454 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12455 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12456 (match_operand:QI 2 "const1_operand" "")))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12459 && (TARGET_SHIFT1 || optimize_size)"
12461 [(set_attr "type" "ishift")
12462 (set (attr "length")
12463 (if_then_else (match_operand:SI 0 "register_operand" "")
12465 (const_string "*")))])
12467 (define_insn "*lshrsi3_1_one_bit_zext"
12468 [(set (match_operand:DI 0 "register_operand" "=r")
12469 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12470 (match_operand:QI 2 "const1_operand" "")))
12471 (clobber (reg:CC FLAGS_REG))]
12472 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12473 && (TARGET_SHIFT1 || optimize_size)"
12475 [(set_attr "type" "ishift")
12476 (set_attr "length" "2")])
12478 (define_insn "*lshrsi3_1"
12479 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12480 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12481 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12482 (clobber (reg:CC FLAGS_REG))]
12483 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12485 shr{l}\t{%2, %0|%0, %2}
12486 shr{l}\t{%b2, %0|%0, %b2}"
12487 [(set_attr "type" "ishift")
12488 (set_attr "mode" "SI")])
12490 (define_insn "*lshrsi3_1_zext"
12491 [(set (match_operand:DI 0 "register_operand" "=r,r")
12493 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12494 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12495 (clobber (reg:CC FLAGS_REG))]
12496 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12498 shr{l}\t{%2, %k0|%k0, %2}
12499 shr{l}\t{%b2, %k0|%k0, %b2}"
12500 [(set_attr "type" "ishift")
12501 (set_attr "mode" "SI")])
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags. We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*lshrsi3_one_bit_cmp"
12507 [(set (reg FLAGS_REG)
12509 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510 (match_operand:QI 2 "const1_operand" ""))
12512 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12514 "ix86_match_ccmode (insn, CCGOCmode)
12515 && (TARGET_SHIFT1 || optimize_size)
12516 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12518 [(set_attr "type" "ishift")
12519 (set (attr "length")
12520 (if_then_else (match_operand:SI 0 "register_operand" "")
12522 (const_string "*")))])
12524 (define_insn "*lshrsi3_one_bit_cconly"
12525 [(set (reg FLAGS_REG)
12527 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12528 (match_operand:QI 2 "const1_operand" ""))
12530 (clobber (match_scratch:SI 0 "=r"))]
12531 "ix86_match_ccmode (insn, CCGOCmode)
12532 && (TARGET_SHIFT1 || optimize_size)
12533 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12535 [(set_attr "type" "ishift")
12536 (set_attr "length" "2")])
12538 (define_insn "*lshrsi3_cmp_one_bit_zext"
12539 [(set (reg FLAGS_REG)
12541 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12542 (match_operand:QI 2 "const1_operand" ""))
12544 (set (match_operand:DI 0 "register_operand" "=r")
12545 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12546 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12547 && (TARGET_SHIFT1 || optimize_size)
12548 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12550 [(set_attr "type" "ishift")
12551 (set_attr "length" "2")])
12553 ;; This pattern can't accept a variable shift count, since shifts by
12554 ;; zero don't affect the flags. We assume that shifts by constant
12555 ;; zero are optimized away.
12556 (define_insn "*lshrsi3_cmp"
12557 [(set (reg FLAGS_REG)
12559 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12560 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12562 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12563 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12564 "ix86_match_ccmode (insn, CCGOCmode)
12565 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12567 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12568 "shr{l}\t{%2, %0|%0, %2}"
12569 [(set_attr "type" "ishift")
12570 (set_attr "mode" "SI")])
12572 (define_insn "*lshrsi3_cconly"
12573 [(set (reg FLAGS_REG)
12575 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12576 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12578 (clobber (match_scratch:SI 0 "=r"))]
12579 "ix86_match_ccmode (insn, CCGOCmode)
12580 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12582 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12583 "shr{l}\t{%2, %0|%0, %2}"
12584 [(set_attr "type" "ishift")
12585 (set_attr "mode" "SI")])
12587 (define_insn "*lshrsi3_cmp_zext"
12588 [(set (reg FLAGS_REG)
12590 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12591 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12593 (set (match_operand:DI 0 "register_operand" "=r")
12594 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12595 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12596 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12598 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12599 "shr{l}\t{%2, %k0|%k0, %2}"
12600 [(set_attr "type" "ishift")
12601 (set_attr "mode" "SI")])
12603 (define_expand "lshrhi3"
12604 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12605 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12606 (match_operand:QI 2 "nonmemory_operand" "")))
12607 (clobber (reg:CC FLAGS_REG))]
12608 "TARGET_HIMODE_MATH"
12609 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12611 (define_insn "*lshrhi3_1_one_bit"
12612 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12613 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12614 (match_operand:QI 2 "const1_operand" "")))
12615 (clobber (reg:CC FLAGS_REG))]
12616 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12617 && (TARGET_SHIFT1 || optimize_size)"
12619 [(set_attr "type" "ishift")
12620 (set (attr "length")
12621 (if_then_else (match_operand 0 "register_operand" "")
12623 (const_string "*")))])
12625 (define_insn "*lshrhi3_1"
12626 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12627 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12628 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12629 (clobber (reg:CC FLAGS_REG))]
12630 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12632 shr{w}\t{%2, %0|%0, %2}
12633 shr{w}\t{%b2, %0|%0, %b2}"
12634 [(set_attr "type" "ishift")
12635 (set_attr "mode" "HI")])
12637 ;; This pattern can't accept a variable shift count, since shifts by
12638 ;; zero don't affect the flags. We assume that shifts by constant
12639 ;; zero are optimized away.
12640 (define_insn "*lshrhi3_one_bit_cmp"
12641 [(set (reg FLAGS_REG)
12643 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12644 (match_operand:QI 2 "const1_operand" ""))
12646 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12647 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12648 "ix86_match_ccmode (insn, CCGOCmode)
12649 && (TARGET_SHIFT1 || optimize_size)
12650 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12652 [(set_attr "type" "ishift")
12653 (set (attr "length")
12654 (if_then_else (match_operand:SI 0 "register_operand" "")
12656 (const_string "*")))])
12658 (define_insn "*lshrhi3_one_bit_cconly"
12659 [(set (reg FLAGS_REG)
12661 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12662 (match_operand:QI 2 "const1_operand" ""))
12664 (clobber (match_scratch:HI 0 "=r"))]
12665 "ix86_match_ccmode (insn, CCGOCmode)
12666 && (TARGET_SHIFT1 || optimize_size)
12667 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12669 [(set_attr "type" "ishift")
12670 (set_attr "length" "2")])
12672 ;; This pattern can't accept a variable shift count, since shifts by
12673 ;; zero don't affect the flags. We assume that shifts by constant
12674 ;; zero are optimized away.
12675 (define_insn "*lshrhi3_cmp"
12676 [(set (reg FLAGS_REG)
12678 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12679 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12681 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12682 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12683 "ix86_match_ccmode (insn, CCGOCmode)
12684 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12686 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12687 "shr{w}\t{%2, %0|%0, %2}"
12688 [(set_attr "type" "ishift")
12689 (set_attr "mode" "HI")])
12691 (define_insn "*lshrhi3_cconly"
12692 [(set (reg FLAGS_REG)
12694 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12695 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12697 (clobber (match_scratch:HI 0 "=r"))]
12698 "ix86_match_ccmode (insn, CCGOCmode)
12699 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12701 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12702 "shr{w}\t{%2, %0|%0, %2}"
12703 [(set_attr "type" "ishift")
12704 (set_attr "mode" "HI")])
12706 (define_expand "lshrqi3"
12707 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12708 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12709 (match_operand:QI 2 "nonmemory_operand" "")))
12710 (clobber (reg:CC FLAGS_REG))]
12711 "TARGET_QIMODE_MATH"
12712 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12714 (define_insn "*lshrqi3_1_one_bit"
12715 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12716 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12717 (match_operand:QI 2 "const1_operand" "")))
12718 (clobber (reg:CC FLAGS_REG))]
12719 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12720 && (TARGET_SHIFT1 || optimize_size)"
12722 [(set_attr "type" "ishift")
12723 (set (attr "length")
12724 (if_then_else (match_operand 0 "register_operand" "")
12726 (const_string "*")))])
12728 (define_insn "*lshrqi3_1_one_bit_slp"
12729 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12730 (lshiftrt:QI (match_dup 0)
12731 (match_operand:QI 1 "const1_operand" "")))
12732 (clobber (reg:CC FLAGS_REG))]
12733 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12734 && (TARGET_SHIFT1 || optimize_size)"
12736 [(set_attr "type" "ishift1")
12737 (set (attr "length")
12738 (if_then_else (match_operand 0 "register_operand" "")
12740 (const_string "*")))])
12742 (define_insn "*lshrqi3_1"
12743 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12744 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12745 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12746 (clobber (reg:CC FLAGS_REG))]
12747 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12749 shr{b}\t{%2, %0|%0, %2}
12750 shr{b}\t{%b2, %0|%0, %b2}"
12751 [(set_attr "type" "ishift")
12752 (set_attr "mode" "QI")])
12754 (define_insn "*lshrqi3_1_slp"
12755 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12756 (lshiftrt:QI (match_dup 0)
12757 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12758 (clobber (reg:CC FLAGS_REG))]
12759 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12760 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12762 shr{b}\t{%1, %0|%0, %1}
12763 shr{b}\t{%b1, %0|%0, %b1}"
12764 [(set_attr "type" "ishift1")
12765 (set_attr "mode" "QI")])
12767 ;; This pattern can't accept a variable shift count, since shifts by
12768 ;; zero don't affect the flags. We assume that shifts by constant
12769 ;; zero are optimized away.
12770 (define_insn "*lshrqi2_one_bit_cmp"
12771 [(set (reg FLAGS_REG)
12773 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12774 (match_operand:QI 2 "const1_operand" ""))
12776 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12777 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12778 "ix86_match_ccmode (insn, CCGOCmode)
12779 && (TARGET_SHIFT1 || optimize_size)
12780 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12782 [(set_attr "type" "ishift")
12783 (set (attr "length")
12784 (if_then_else (match_operand:SI 0 "register_operand" "")
12786 (const_string "*")))])
12788 (define_insn "*lshrqi2_one_bit_cconly"
12789 [(set (reg FLAGS_REG)
12791 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12792 (match_operand:QI 2 "const1_operand" ""))
12794 (clobber (match_scratch:QI 0 "=q"))]
12795 "ix86_match_ccmode (insn, CCGOCmode)
12796 && (TARGET_SHIFT1 || optimize_size)
12797 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12799 [(set_attr "type" "ishift")
12800 (set_attr "length" "2")])
12802 ;; This pattern can't accept a variable shift count, since shifts by
12803 ;; zero don't affect the flags. We assume that shifts by constant
12804 ;; zero are optimized away.
12805 (define_insn "*lshrqi2_cmp"
12806 [(set (reg FLAGS_REG)
12808 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12809 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12811 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12812 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12813 "ix86_match_ccmode (insn, CCGOCmode)
12814 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12816 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12817 "shr{b}\t{%2, %0|%0, %2}"
12818 [(set_attr "type" "ishift")
12819 (set_attr "mode" "QI")])
12821 (define_insn "*lshrqi2_cconly"
12822 [(set (reg FLAGS_REG)
12824 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12825 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12827 (clobber (match_scratch:QI 0 "=q"))]
12828 "ix86_match_ccmode (insn, CCGOCmode)
12829 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12831 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12832 "shr{b}\t{%2, %0|%0, %2}"
12833 [(set_attr "type" "ishift")
12834 (set_attr "mode" "QI")])
12836 ;; Rotate instructions
12838 (define_expand "rotldi3"
12839 [(set (match_operand:DI 0 "shiftdi_operand" "")
12840 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12841 (match_operand:QI 2 "nonmemory_operand" "")))
12842 (clobber (reg:CC FLAGS_REG))]
12847 ix86_expand_binary_operator (ROTATE, DImode, operands);
12850 if (!const_1_to_31_operand (operands[2], VOIDmode))
12852 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12856 ;; Implement rotation using two double-precision shift instructions
12857 ;; and a scratch register.
12858 (define_insn_and_split "ix86_rotldi3"
12859 [(set (match_operand:DI 0 "register_operand" "=r")
12860 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12861 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12862 (clobber (reg:CC FLAGS_REG))
12863 (clobber (match_scratch:SI 3 "=&r"))]
12866 "&& reload_completed"
12867 [(set (match_dup 3) (match_dup 4))
12869 [(set (match_dup 4)
12870 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12871 (lshiftrt:SI (match_dup 5)
12872 (minus:QI (const_int 32) (match_dup 2)))))
12873 (clobber (reg:CC FLAGS_REG))])
12875 [(set (match_dup 5)
12876 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12877 (lshiftrt:SI (match_dup 3)
12878 (minus:QI (const_int 32) (match_dup 2)))))
12879 (clobber (reg:CC FLAGS_REG))])]
12880 "split_di (operands, 1, operands + 4, operands + 5);")
12882 (define_insn "*rotlsi3_1_one_bit_rex64"
12883 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12884 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12885 (match_operand:QI 2 "const1_operand" "")))
12886 (clobber (reg:CC FLAGS_REG))]
12887 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12888 && (TARGET_SHIFT1 || optimize_size)"
12890 [(set_attr "type" "rotate")
12891 (set (attr "length")
12892 (if_then_else (match_operand:DI 0 "register_operand" "")
12894 (const_string "*")))])
12896 (define_insn "*rotldi3_1_rex64"
12897 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12898 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12899 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12900 (clobber (reg:CC FLAGS_REG))]
12901 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12903 rol{q}\t{%2, %0|%0, %2}
12904 rol{q}\t{%b2, %0|%0, %b2}"
12905 [(set_attr "type" "rotate")
12906 (set_attr "mode" "DI")])
12908 (define_expand "rotlsi3"
12909 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12910 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12911 (match_operand:QI 2 "nonmemory_operand" "")))
12912 (clobber (reg:CC FLAGS_REG))]
12914 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12916 (define_insn "*rotlsi3_1_one_bit"
12917 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12918 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12919 (match_operand:QI 2 "const1_operand" "")))
12920 (clobber (reg:CC FLAGS_REG))]
12921 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12922 && (TARGET_SHIFT1 || optimize_size)"
12924 [(set_attr "type" "rotate")
12925 (set (attr "length")
12926 (if_then_else (match_operand:SI 0 "register_operand" "")
12928 (const_string "*")))])
12930 (define_insn "*rotlsi3_1_one_bit_zext"
12931 [(set (match_operand:DI 0 "register_operand" "=r")
12933 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12934 (match_operand:QI 2 "const1_operand" ""))))
12935 (clobber (reg:CC FLAGS_REG))]
12936 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12937 && (TARGET_SHIFT1 || optimize_size)"
12939 [(set_attr "type" "rotate")
12940 (set_attr "length" "2")])
12942 (define_insn "*rotlsi3_1"
12943 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12944 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12945 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12946 (clobber (reg:CC FLAGS_REG))]
12947 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12949 rol{l}\t{%2, %0|%0, %2}
12950 rol{l}\t{%b2, %0|%0, %b2}"
12951 [(set_attr "type" "rotate")
12952 (set_attr "mode" "SI")])
12954 (define_insn "*rotlsi3_1_zext"
12955 [(set (match_operand:DI 0 "register_operand" "=r,r")
12957 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12958 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12962 rol{l}\t{%2, %k0|%k0, %2}
12963 rol{l}\t{%b2, %k0|%k0, %b2}"
12964 [(set_attr "type" "rotate")
12965 (set_attr "mode" "SI")])
12967 (define_expand "rotlhi3"
12968 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12969 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12970 (match_operand:QI 2 "nonmemory_operand" "")))
12971 (clobber (reg:CC FLAGS_REG))]
12972 "TARGET_HIMODE_MATH"
12973 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12975 (define_insn "*rotlhi3_1_one_bit"
12976 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12977 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12978 (match_operand:QI 2 "const1_operand" "")))
12979 (clobber (reg:CC FLAGS_REG))]
12980 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12981 && (TARGET_SHIFT1 || optimize_size)"
12983 [(set_attr "type" "rotate")
12984 (set (attr "length")
12985 (if_then_else (match_operand 0 "register_operand" "")
12987 (const_string "*")))])
12989 (define_insn "*rotlhi3_1"
12990 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12991 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12992 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12993 (clobber (reg:CC FLAGS_REG))]
12994 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12996 rol{w}\t{%2, %0|%0, %2}
12997 rol{w}\t{%b2, %0|%0, %b2}"
12998 [(set_attr "type" "rotate")
12999 (set_attr "mode" "HI")])
13001 (define_expand "rotlqi3"
13002 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13003 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13004 (match_operand:QI 2 "nonmemory_operand" "")))
13005 (clobber (reg:CC FLAGS_REG))]
13006 "TARGET_QIMODE_MATH"
13007 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13009 (define_insn "*rotlqi3_1_one_bit_slp"
13010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13011 (rotate:QI (match_dup 0)
13012 (match_operand:QI 1 "const1_operand" "")))
13013 (clobber (reg:CC FLAGS_REG))]
13014 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13015 && (TARGET_SHIFT1 || optimize_size)"
13017 [(set_attr "type" "rotate1")
13018 (set (attr "length")
13019 (if_then_else (match_operand 0 "register_operand" "")
13021 (const_string "*")))])
13023 (define_insn "*rotlqi3_1_one_bit"
13024 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13025 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13026 (match_operand:QI 2 "const1_operand" "")))
13027 (clobber (reg:CC FLAGS_REG))]
13028 "ix86_binary_operator_ok (ROTATE, QImode, operands)
13029 && (TARGET_SHIFT1 || optimize_size)"
13031 [(set_attr "type" "rotate")
13032 (set (attr "length")
13033 (if_then_else (match_operand 0 "register_operand" "")
13035 (const_string "*")))])
13037 (define_insn "*rotlqi3_1_slp"
13038 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13039 (rotate:QI (match_dup 0)
13040 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13041 (clobber (reg:CC FLAGS_REG))]
13042 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13043 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13045 rol{b}\t{%1, %0|%0, %1}
13046 rol{b}\t{%b1, %0|%0, %b1}"
13047 [(set_attr "type" "rotate1")
13048 (set_attr "mode" "QI")])
13050 (define_insn "*rotlqi3_1"
13051 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13052 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13053 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13054 (clobber (reg:CC FLAGS_REG))]
13055 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13057 rol{b}\t{%2, %0|%0, %2}
13058 rol{b}\t{%b2, %0|%0, %b2}"
13059 [(set_attr "type" "rotate")
13060 (set_attr "mode" "QI")])
13062 (define_expand "rotrdi3"
13063 [(set (match_operand:DI 0 "shiftdi_operand" "")
13064 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13065 (match_operand:QI 2 "nonmemory_operand" "")))
13066 (clobber (reg:CC FLAGS_REG))]
13071 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13074 if (!const_1_to_31_operand (operands[2], VOIDmode))
13076 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13080 ;; Implement rotation using two double-precision shift instructions
13081 ;; and a scratch register.
13082 (define_insn_and_split "ix86_rotrdi3"
13083 [(set (match_operand:DI 0 "register_operand" "=r")
13084 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13085 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13086 (clobber (reg:CC FLAGS_REG))
13087 (clobber (match_scratch:SI 3 "=&r"))]
13090 "&& reload_completed"
13091 [(set (match_dup 3) (match_dup 4))
13093 [(set (match_dup 4)
13094 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13095 (ashift:SI (match_dup 5)
13096 (minus:QI (const_int 32) (match_dup 2)))))
13097 (clobber (reg:CC FLAGS_REG))])
13099 [(set (match_dup 5)
13100 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13101 (ashift:SI (match_dup 3)
13102 (minus:QI (const_int 32) (match_dup 2)))))
13103 (clobber (reg:CC FLAGS_REG))])]
13104 "split_di (operands, 1, operands + 4, operands + 5);")
13106 (define_insn "*rotrdi3_1_one_bit_rex64"
13107 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13108 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13109 (match_operand:QI 2 "const1_operand" "")))
13110 (clobber (reg:CC FLAGS_REG))]
13111 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13112 && (TARGET_SHIFT1 || optimize_size)"
13114 [(set_attr "type" "rotate")
13115 (set (attr "length")
13116 (if_then_else (match_operand:DI 0 "register_operand" "")
13118 (const_string "*")))])
13120 (define_insn "*rotrdi3_1_rex64"
13121 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13122 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13123 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13124 (clobber (reg:CC FLAGS_REG))]
13125 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13127 ror{q}\t{%2, %0|%0, %2}
13128 ror{q}\t{%b2, %0|%0, %b2}"
13129 [(set_attr "type" "rotate")
13130 (set_attr "mode" "DI")])
13132 (define_expand "rotrsi3"
13133 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13134 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13135 (match_operand:QI 2 "nonmemory_operand" "")))
13136 (clobber (reg:CC FLAGS_REG))]
13138 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13140 (define_insn "*rotrsi3_1_one_bit"
13141 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13142 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13143 (match_operand:QI 2 "const1_operand" "")))
13144 (clobber (reg:CC FLAGS_REG))]
13145 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13146 && (TARGET_SHIFT1 || optimize_size)"
13148 [(set_attr "type" "rotate")
13149 (set (attr "length")
13150 (if_then_else (match_operand:SI 0 "register_operand" "")
13152 (const_string "*")))])
13154 (define_insn "*rotrsi3_1_one_bit_zext"
13155 [(set (match_operand:DI 0 "register_operand" "=r")
13157 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13158 (match_operand:QI 2 "const1_operand" ""))))
13159 (clobber (reg:CC FLAGS_REG))]
13160 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13161 && (TARGET_SHIFT1 || optimize_size)"
13163 [(set_attr "type" "rotate")
13164 (set (attr "length")
13165 (if_then_else (match_operand:SI 0 "register_operand" "")
13167 (const_string "*")))])
13169 (define_insn "*rotrsi3_1"
13170 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13171 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13172 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13173 (clobber (reg:CC FLAGS_REG))]
13174 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13176 ror{l}\t{%2, %0|%0, %2}
13177 ror{l}\t{%b2, %0|%0, %b2}"
13178 [(set_attr "type" "rotate")
13179 (set_attr "mode" "SI")])
13181 (define_insn "*rotrsi3_1_zext"
13182 [(set (match_operand:DI 0 "register_operand" "=r,r")
13184 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13185 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13186 (clobber (reg:CC FLAGS_REG))]
13187 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13189 ror{l}\t{%2, %k0|%k0, %2}
13190 ror{l}\t{%b2, %k0|%k0, %b2}"
13191 [(set_attr "type" "rotate")
13192 (set_attr "mode" "SI")])
13194 (define_expand "rotrhi3"
13195 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13196 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13197 (match_operand:QI 2 "nonmemory_operand" "")))
13198 (clobber (reg:CC FLAGS_REG))]
13199 "TARGET_HIMODE_MATH"
13200 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13202 (define_insn "*rotrhi3_one_bit"
13203 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13204 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13205 (match_operand:QI 2 "const1_operand" "")))
13206 (clobber (reg:CC FLAGS_REG))]
13207 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13208 && (TARGET_SHIFT1 || optimize_size)"
13210 [(set_attr "type" "rotate")
13211 (set (attr "length")
13212 (if_then_else (match_operand 0 "register_operand" "")
13214 (const_string "*")))])
13216 (define_insn "*rotrhi3"
13217 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13218 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13219 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13220 (clobber (reg:CC FLAGS_REG))]
13221 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13223 ror{w}\t{%2, %0|%0, %2}
13224 ror{w}\t{%b2, %0|%0, %b2}"
13225 [(set_attr "type" "rotate")
13226 (set_attr "mode" "HI")])
13228 (define_expand "rotrqi3"
13229 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13230 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13231 (match_operand:QI 2 "nonmemory_operand" "")))
13232 (clobber (reg:CC FLAGS_REG))]
13233 "TARGET_QIMODE_MATH"
13234 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13236 (define_insn "*rotrqi3_1_one_bit"
13237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13238 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13239 (match_operand:QI 2 "const1_operand" "")))
13240 (clobber (reg:CC FLAGS_REG))]
13241 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13242 && (TARGET_SHIFT1 || optimize_size)"
13244 [(set_attr "type" "rotate")
13245 (set (attr "length")
13246 (if_then_else (match_operand 0 "register_operand" "")
13248 (const_string "*")))])
13250 (define_insn "*rotrqi3_1_one_bit_slp"
13251 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13252 (rotatert:QI (match_dup 0)
13253 (match_operand:QI 1 "const1_operand" "")))
13254 (clobber (reg:CC FLAGS_REG))]
13255 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13256 && (TARGET_SHIFT1 || optimize_size)"
13258 [(set_attr "type" "rotate1")
13259 (set (attr "length")
13260 (if_then_else (match_operand 0 "register_operand" "")
13262 (const_string "*")))])
13264 (define_insn "*rotrqi3_1"
13265 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13266 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13267 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13268 (clobber (reg:CC FLAGS_REG))]
13269 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13271 ror{b}\t{%2, %0|%0, %2}
13272 ror{b}\t{%b2, %0|%0, %b2}"
13273 [(set_attr "type" "rotate")
13274 (set_attr "mode" "QI")])
13276 (define_insn "*rotrqi3_1_slp"
13277 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13278 (rotatert:QI (match_dup 0)
13279 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13280 (clobber (reg:CC FLAGS_REG))]
13281 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13282 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13284 ror{b}\t{%1, %0|%0, %1}
13285 ror{b}\t{%b1, %0|%0, %b1}"
13286 [(set_attr "type" "rotate1")
13287 (set_attr "mode" "QI")])
13289 ;; Bit set / bit test instructions
13291 (define_expand "extv"
13292 [(set (match_operand:SI 0 "register_operand" "")
13293 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13294 (match_operand:SI 2 "const8_operand" "")
13295 (match_operand:SI 3 "const8_operand" "")))]
13298 /* Handle extractions from %ah et al. */
13299 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13302 /* From mips.md: extract_bit_field doesn't verify that our source
13303 matches the predicate, so check it again here. */
13304 if (! ext_register_operand (operands[1], VOIDmode))
13308 (define_expand "extzv"
13309 [(set (match_operand:SI 0 "register_operand" "")
13310 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13311 (match_operand:SI 2 "const8_operand" "")
13312 (match_operand:SI 3 "const8_operand" "")))]
13315 /* Handle extractions from %ah et al. */
13316 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13319 /* From mips.md: extract_bit_field doesn't verify that our source
13320 matches the predicate, so check it again here. */
13321 if (! ext_register_operand (operands[1], VOIDmode))
13325 (define_expand "insv"
13326 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13327 (match_operand 1 "const8_operand" "")
13328 (match_operand 2 "const8_operand" ""))
13329 (match_operand 3 "register_operand" ""))]
13332 /* Handle insertions to %ah et al. */
13333 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13336 /* From mips.md: insert_bit_field doesn't verify that our source
13337 matches the predicate, so check it again here. */
13338 if (! ext_register_operand (operands[0], VOIDmode))
13342 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13344 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13349 ;; %%% bts, btr, btc, bt.
13350 ;; In general these instructions are *slow* when applied to memory,
13351 ;; since they enforce atomic operation. When applied to registers,
13352 ;; it depends on the cpu implementation. They're never faster than
13353 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13354 ;; no point. But in 64-bit, we can't hold the relevant immediates
13355 ;; within the instruction itself, so operating on bits in the high
13356 ;; 32-bits of a register becomes easier.
13358 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13359 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13360 ;; negdf respectively, so they can never be disabled entirely.
13362 (define_insn "*btsq"
13363 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13365 (match_operand:DI 1 "const_0_to_63_operand" ""))
13367 (clobber (reg:CC FLAGS_REG))]
13368 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13370 [(set_attr "type" "alu1")])
13372 (define_insn "*btrq"
13373 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13375 (match_operand:DI 1 "const_0_to_63_operand" ""))
13377 (clobber (reg:CC FLAGS_REG))]
13378 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13380 [(set_attr "type" "alu1")])
13382 (define_insn "*btcq"
13383 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13385 (match_operand:DI 1 "const_0_to_63_operand" ""))
13386 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13387 (clobber (reg:CC FLAGS_REG))]
13388 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13390 [(set_attr "type" "alu1")])
13392 ;; Allow Nocona to avoid these instructions if a register is available.
13395 [(match_scratch:DI 2 "r")
13396 (parallel [(set (zero_extract:DI
13397 (match_operand:DI 0 "register_operand" "")
13399 (match_operand:DI 1 "const_0_to_63_operand" ""))
13401 (clobber (reg:CC FLAGS_REG))])]
13402 "TARGET_64BIT && !TARGET_USE_BT"
13405 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13408 if (HOST_BITS_PER_WIDE_INT >= 64)
13409 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13410 else if (i < HOST_BITS_PER_WIDE_INT)
13411 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13413 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13415 op1 = immed_double_const (lo, hi, DImode);
13418 emit_move_insn (operands[2], op1);
13422 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13427 [(match_scratch:DI 2 "r")
13428 (parallel [(set (zero_extract:DI
13429 (match_operand:DI 0 "register_operand" "")
13431 (match_operand:DI 1 "const_0_to_63_operand" ""))
13433 (clobber (reg:CC FLAGS_REG))])]
13434 "TARGET_64BIT && !TARGET_USE_BT"
13437 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13440 if (HOST_BITS_PER_WIDE_INT >= 64)
13441 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13442 else if (i < HOST_BITS_PER_WIDE_INT)
13443 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13445 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13447 op1 = immed_double_const (~lo, ~hi, DImode);
13450 emit_move_insn (operands[2], op1);
13454 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13459 [(match_scratch:DI 2 "r")
13460 (parallel [(set (zero_extract:DI
13461 (match_operand:DI 0 "register_operand" "")
13463 (match_operand:DI 1 "const_0_to_63_operand" ""))
13464 (not:DI (zero_extract:DI
13465 (match_dup 0) (const_int 1) (match_dup 1))))
13466 (clobber (reg:CC FLAGS_REG))])]
13467 "TARGET_64BIT && !TARGET_USE_BT"
13470 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13473 if (HOST_BITS_PER_WIDE_INT >= 64)
13474 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13475 else if (i < HOST_BITS_PER_WIDE_INT)
13476 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13478 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13480 op1 = immed_double_const (lo, hi, DImode);
13483 emit_move_insn (operands[2], op1);
13487 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13491 ;; Store-flag instructions.
13493 ;; For all sCOND expanders, also expand the compare or test insn that
13494 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13496 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13497 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13498 ;; way, which can later delete the movzx if only QImode is needed.
13500 (define_expand "seq"
13501 [(set (match_operand:QI 0 "register_operand" "")
13502 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13504 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13506 (define_expand "sne"
13507 [(set (match_operand:QI 0 "register_operand" "")
13508 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13510 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13512 (define_expand "sgt"
13513 [(set (match_operand:QI 0 "register_operand" "")
13514 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13516 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13518 (define_expand "sgtu"
13519 [(set (match_operand:QI 0 "register_operand" "")
13520 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13522 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13524 (define_expand "slt"
13525 [(set (match_operand:QI 0 "register_operand" "")
13526 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13528 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13530 (define_expand "sltu"
13531 [(set (match_operand:QI 0 "register_operand" "")
13532 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13534 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13536 (define_expand "sge"
13537 [(set (match_operand:QI 0 "register_operand" "")
13538 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13540 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13542 (define_expand "sgeu"
13543 [(set (match_operand:QI 0 "register_operand" "")
13544 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13546 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13548 (define_expand "sle"
13549 [(set (match_operand:QI 0 "register_operand" "")
13550 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13552 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13554 (define_expand "sleu"
13555 [(set (match_operand:QI 0 "register_operand" "")
13556 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13558 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13560 (define_expand "sunordered"
13561 [(set (match_operand:QI 0 "register_operand" "")
13562 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13563 "TARGET_80387 || TARGET_SSE"
13564 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13566 (define_expand "sordered"
13567 [(set (match_operand:QI 0 "register_operand" "")
13568 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13570 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13572 (define_expand "suneq"
13573 [(set (match_operand:QI 0 "register_operand" "")
13574 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13575 "TARGET_80387 || TARGET_SSE"
13576 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13578 (define_expand "sunge"
13579 [(set (match_operand:QI 0 "register_operand" "")
13580 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13581 "TARGET_80387 || TARGET_SSE"
13582 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13584 (define_expand "sungt"
13585 [(set (match_operand:QI 0 "register_operand" "")
13586 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13587 "TARGET_80387 || TARGET_SSE"
13588 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13590 (define_expand "sunle"
13591 [(set (match_operand:QI 0 "register_operand" "")
13592 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13593 "TARGET_80387 || TARGET_SSE"
13594 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13596 (define_expand "sunlt"
13597 [(set (match_operand:QI 0 "register_operand" "")
13598 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13599 "TARGET_80387 || TARGET_SSE"
13600 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13602 (define_expand "sltgt"
13603 [(set (match_operand:QI 0 "register_operand" "")
13604 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13605 "TARGET_80387 || TARGET_SSE"
13606 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13608 (define_insn "*setcc_1"
13609 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13610 (match_operator:QI 1 "ix86_comparison_operator"
13611 [(reg FLAGS_REG) (const_int 0)]))]
13614 [(set_attr "type" "setcc")
13615 (set_attr "mode" "QI")])
13617 (define_insn "*setcc_2"
13618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13619 (match_operator:QI 1 "ix86_comparison_operator"
13620 [(reg FLAGS_REG) (const_int 0)]))]
13623 [(set_attr "type" "setcc")
13624 (set_attr "mode" "QI")])
13626 ;; In general it is not safe to assume too much about CCmode registers,
13627 ;; so simplify-rtx stops when it sees a second one. Under certain
13628 ;; conditions this is safe on x86, so help combine not create
13635 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13636 (ne:QI (match_operator 1 "ix86_comparison_operator"
13637 [(reg FLAGS_REG) (const_int 0)])
13640 [(set (match_dup 0) (match_dup 1))]
13642 PUT_MODE (operands[1], QImode);
13646 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13647 (ne:QI (match_operator 1 "ix86_comparison_operator"
13648 [(reg FLAGS_REG) (const_int 0)])
13651 [(set (match_dup 0) (match_dup 1))]
13653 PUT_MODE (operands[1], QImode);
13657 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13658 (eq:QI (match_operator 1 "ix86_comparison_operator"
13659 [(reg FLAGS_REG) (const_int 0)])
13662 [(set (match_dup 0) (match_dup 1))]
13664 rtx new_op1 = copy_rtx (operands[1]);
13665 operands[1] = new_op1;
13666 PUT_MODE (new_op1, QImode);
13667 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13668 GET_MODE (XEXP (new_op1, 0))));
13670 /* Make sure that (a) the CCmode we have for the flags is strong
13671 enough for the reversed compare or (b) we have a valid FP compare. */
13672 if (! ix86_comparison_operator (new_op1, VOIDmode))
13677 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13678 (eq:QI (match_operator 1 "ix86_comparison_operator"
13679 [(reg FLAGS_REG) (const_int 0)])
13682 [(set (match_dup 0) (match_dup 1))]
13684 rtx new_op1 = copy_rtx (operands[1]);
13685 operands[1] = new_op1;
13686 PUT_MODE (new_op1, QImode);
13687 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13688 GET_MODE (XEXP (new_op1, 0))));
13690 /* Make sure that (a) the CCmode we have for the flags is strong
13691 enough for the reversed compare or (b) we have a valid FP compare. */
13692 if (! ix86_comparison_operator (new_op1, VOIDmode))
13696 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13697 ;; subsequent logical operations are used to imitate conditional moves.
13698 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13701 (define_insn "*sse_setccsf"
13702 [(set (match_operand:SF 0 "register_operand" "=x")
13703 (match_operator:SF 1 "sse_comparison_operator"
13704 [(match_operand:SF 2 "register_operand" "0")
13705 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13707 "cmp%D1ss\t{%3, %0|%0, %3}"
13708 [(set_attr "type" "ssecmp")
13709 (set_attr "mode" "SF")])
13711 (define_insn "*sse_setccdf"
13712 [(set (match_operand:DF 0 "register_operand" "=x")
13713 (match_operator:DF 1 "sse_comparison_operator"
13714 [(match_operand:DF 2 "register_operand" "0")
13715 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13717 "cmp%D1sd\t{%3, %0|%0, %3}"
13718 [(set_attr "type" "ssecmp")
13719 (set_attr "mode" "DF")])
13721 ;; Basic conditional jump instructions.
13722 ;; We ignore the overflow flag for signed branch instructions.
13724 ;; For all bCOND expanders, also expand the compare or test insn that
13725 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13727 (define_expand "beq"
13729 (if_then_else (match_dup 1)
13730 (label_ref (match_operand 0 "" ""))
13733 "ix86_expand_branch (EQ, operands[0]); DONE;")
13735 (define_expand "bne"
13737 (if_then_else (match_dup 1)
13738 (label_ref (match_operand 0 "" ""))
13741 "ix86_expand_branch (NE, operands[0]); DONE;")
13743 (define_expand "bgt"
13745 (if_then_else (match_dup 1)
13746 (label_ref (match_operand 0 "" ""))
13749 "ix86_expand_branch (GT, operands[0]); DONE;")
13751 (define_expand "bgtu"
13753 (if_then_else (match_dup 1)
13754 (label_ref (match_operand 0 "" ""))
13757 "ix86_expand_branch (GTU, operands[0]); DONE;")
13759 (define_expand "blt"
13761 (if_then_else (match_dup 1)
13762 (label_ref (match_operand 0 "" ""))
13765 "ix86_expand_branch (LT, operands[0]); DONE;")
13767 (define_expand "bltu"
13769 (if_then_else (match_dup 1)
13770 (label_ref (match_operand 0 "" ""))
13773 "ix86_expand_branch (LTU, operands[0]); DONE;")
13775 (define_expand "bge"
13777 (if_then_else (match_dup 1)
13778 (label_ref (match_operand 0 "" ""))
13781 "ix86_expand_branch (GE, operands[0]); DONE;")
13783 (define_expand "bgeu"
13785 (if_then_else (match_dup 1)
13786 (label_ref (match_operand 0 "" ""))
13789 "ix86_expand_branch (GEU, operands[0]); DONE;")
13791 (define_expand "ble"
13793 (if_then_else (match_dup 1)
13794 (label_ref (match_operand 0 "" ""))
13797 "ix86_expand_branch (LE, operands[0]); DONE;")
13799 (define_expand "bleu"
13801 (if_then_else (match_dup 1)
13802 (label_ref (match_operand 0 "" ""))
13805 "ix86_expand_branch (LEU, operands[0]); DONE;")
13807 (define_expand "bunordered"
13809 (if_then_else (match_dup 1)
13810 (label_ref (match_operand 0 "" ""))
13812 "TARGET_80387 || TARGET_SSE_MATH"
13813 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13815 (define_expand "bordered"
13817 (if_then_else (match_dup 1)
13818 (label_ref (match_operand 0 "" ""))
13820 "TARGET_80387 || TARGET_SSE_MATH"
13821 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13823 (define_expand "buneq"
13825 (if_then_else (match_dup 1)
13826 (label_ref (match_operand 0 "" ""))
13828 "TARGET_80387 || TARGET_SSE_MATH"
13829 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13831 (define_expand "bunge"
13833 (if_then_else (match_dup 1)
13834 (label_ref (match_operand 0 "" ""))
13836 "TARGET_80387 || TARGET_SSE_MATH"
13837 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13839 (define_expand "bungt"
13841 (if_then_else (match_dup 1)
13842 (label_ref (match_operand 0 "" ""))
13844 "TARGET_80387 || TARGET_SSE_MATH"
13845 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13847 (define_expand "bunle"
13849 (if_then_else (match_dup 1)
13850 (label_ref (match_operand 0 "" ""))
13852 "TARGET_80387 || TARGET_SSE_MATH"
13853 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13855 (define_expand "bunlt"
13857 (if_then_else (match_dup 1)
13858 (label_ref (match_operand 0 "" ""))
13860 "TARGET_80387 || TARGET_SSE_MATH"
13861 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13863 (define_expand "bltgt"
13865 (if_then_else (match_dup 1)
13866 (label_ref (match_operand 0 "" ""))
13868 "TARGET_80387 || TARGET_SSE_MATH"
13869 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13871 (define_insn "*jcc_1"
13873 (if_then_else (match_operator 1 "ix86_comparison_operator"
13874 [(reg FLAGS_REG) (const_int 0)])
13875 (label_ref (match_operand 0 "" ""))
13879 [(set_attr "type" "ibr")
13880 (set_attr "modrm" "0")
13881 (set (attr "length")
13882 (if_then_else (and (ge (minus (match_dup 0) (pc))
13884 (lt (minus (match_dup 0) (pc))
13889 (define_insn "*jcc_2"
13891 (if_then_else (match_operator 1 "ix86_comparison_operator"
13892 [(reg FLAGS_REG) (const_int 0)])
13894 (label_ref (match_operand 0 "" ""))))]
13897 [(set_attr "type" "ibr")
13898 (set_attr "modrm" "0")
13899 (set (attr "length")
13900 (if_then_else (and (ge (minus (match_dup 0) (pc))
13902 (lt (minus (match_dup 0) (pc))
13907 ;; In general it is not safe to assume too much about CCmode registers,
13908 ;; so simplify-rtx stops when it sees a second one. Under certain
13909 ;; conditions this is safe on x86, so help combine not create
13917 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13918 [(reg FLAGS_REG) (const_int 0)])
13920 (label_ref (match_operand 1 "" ""))
13924 (if_then_else (match_dup 0)
13925 (label_ref (match_dup 1))
13928 PUT_MODE (operands[0], VOIDmode);
13933 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13934 [(reg FLAGS_REG) (const_int 0)])
13936 (label_ref (match_operand 1 "" ""))
13940 (if_then_else (match_dup 0)
13941 (label_ref (match_dup 1))
13944 rtx new_op0 = copy_rtx (operands[0]);
13945 operands[0] = new_op0;
13946 PUT_MODE (new_op0, VOIDmode);
13947 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13948 GET_MODE (XEXP (new_op0, 0))));
13950 /* Make sure that (a) the CCmode we have for the flags is strong
13951 enough for the reversed compare or (b) we have a valid FP compare. */
13952 if (! ix86_comparison_operator (new_op0, VOIDmode))
13956 ;; Define combination compare-and-branch fp compare instructions to use
13957 ;; during early optimization. Splitting the operation apart early makes
13958 ;; for bad code when we want to reverse the operation.
13960 (define_insn "*fp_jcc_1_mixed"
13962 (if_then_else (match_operator 0 "comparison_operator"
13963 [(match_operand 1 "register_operand" "f,x")
13964 (match_operand 2 "nonimmediate_operand" "f,xm")])
13965 (label_ref (match_operand 3 "" ""))
13967 (clobber (reg:CCFP FPSR_REG))
13968 (clobber (reg:CCFP FLAGS_REG))]
13969 "TARGET_MIX_SSE_I387
13970 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13971 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13972 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13975 (define_insn "*fp_jcc_1_sse"
13977 (if_then_else (match_operator 0 "comparison_operator"
13978 [(match_operand 1 "register_operand" "x")
13979 (match_operand 2 "nonimmediate_operand" "xm")])
13980 (label_ref (match_operand 3 "" ""))
13982 (clobber (reg:CCFP FPSR_REG))
13983 (clobber (reg:CCFP FLAGS_REG))]
13985 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13986 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13987 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13990 (define_insn "*fp_jcc_1_387"
13992 (if_then_else (match_operator 0 "comparison_operator"
13993 [(match_operand 1 "register_operand" "f")
13994 (match_operand 2 "register_operand" "f")])
13995 (label_ref (match_operand 3 "" ""))
13997 (clobber (reg:CCFP FPSR_REG))
13998 (clobber (reg:CCFP FLAGS_REG))]
13999 "TARGET_CMOVE && TARGET_80387
14000 && 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_2_mixed"
14007 (if_then_else (match_operator 0 "comparison_operator"
14008 [(match_operand 1 "register_operand" "f,x")
14009 (match_operand 2 "nonimmediate_operand" "f,xm")])
14011 (label_ref (match_operand 3 "" ""))))
14012 (clobber (reg:CCFP FPSR_REG))
14013 (clobber (reg:CCFP FLAGS_REG))]
14014 "TARGET_MIX_SSE_I387
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_2_sse"
14022 (if_then_else (match_operator 0 "comparison_operator"
14023 [(match_operand 1 "register_operand" "x")
14024 (match_operand 2 "nonimmediate_operand" "xm")])
14026 (label_ref (match_operand 3 "" ""))))
14027 (clobber (reg:CCFP FPSR_REG))
14028 (clobber (reg:CCFP FLAGS_REG))]
14030 && SSE_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_387"
14037 (if_then_else (match_operator 0 "comparison_operator"
14038 [(match_operand 1 "register_operand" "f")
14039 (match_operand 2 "register_operand" "f")])
14041 (label_ref (match_operand 3 "" ""))))
14042 (clobber (reg:CCFP FPSR_REG))
14043 (clobber (reg:CCFP FLAGS_REG))]
14044 "TARGET_CMOVE && TARGET_80387
14045 && 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_3_387"
14052 (if_then_else (match_operator 0 "comparison_operator"
14053 [(match_operand 1 "register_operand" "f")
14054 (match_operand 2 "nonimmediate_operand" "fm")])
14055 (label_ref (match_operand 3 "" ""))
14057 (clobber (reg:CCFP FPSR_REG))
14058 (clobber (reg:CCFP FLAGS_REG))
14059 (clobber (match_scratch:HI 4 "=a"))]
14061 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14062 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14063 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14064 && SELECT_CC_MODE (GET_CODE (operands[0]),
14065 operands[1], operands[2]) == CCFPmode
14066 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14069 (define_insn "*fp_jcc_4_387"
14071 (if_then_else (match_operator 0 "comparison_operator"
14072 [(match_operand 1 "register_operand" "f")
14073 (match_operand 2 "nonimmediate_operand" "fm")])
14075 (label_ref (match_operand 3 "" ""))))
14076 (clobber (reg:CCFP FPSR_REG))
14077 (clobber (reg:CCFP FLAGS_REG))
14078 (clobber (match_scratch:HI 4 "=a"))]
14080 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14081 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14082 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14083 && SELECT_CC_MODE (GET_CODE (operands[0]),
14084 operands[1], operands[2]) == CCFPmode
14085 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14088 (define_insn "*fp_jcc_5_387"
14090 (if_then_else (match_operator 0 "comparison_operator"
14091 [(match_operand 1 "register_operand" "f")
14092 (match_operand 2 "register_operand" "f")])
14093 (label_ref (match_operand 3 "" ""))
14095 (clobber (reg:CCFP FPSR_REG))
14096 (clobber (reg:CCFP FLAGS_REG))
14097 (clobber (match_scratch:HI 4 "=a"))]
14099 && FLOAT_MODE_P (GET_MODE (operands[1]))
14100 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14101 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14104 (define_insn "*fp_jcc_6_387"
14106 (if_then_else (match_operator 0 "comparison_operator"
14107 [(match_operand 1 "register_operand" "f")
14108 (match_operand 2 "register_operand" "f")])
14110 (label_ref (match_operand 3 "" ""))))
14111 (clobber (reg:CCFP FPSR_REG))
14112 (clobber (reg:CCFP FLAGS_REG))
14113 (clobber (match_scratch:HI 4 "=a"))]
14115 && FLOAT_MODE_P (GET_MODE (operands[1]))
14116 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14117 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14120 (define_insn "*fp_jcc_7_387"
14122 (if_then_else (match_operator 0 "comparison_operator"
14123 [(match_operand 1 "register_operand" "f")
14124 (match_operand 2 "const0_operand" "X")])
14125 (label_ref (match_operand 3 "" ""))
14127 (clobber (reg:CCFP FPSR_REG))
14128 (clobber (reg:CCFP FLAGS_REG))
14129 (clobber (match_scratch:HI 4 "=a"))]
14131 && FLOAT_MODE_P (GET_MODE (operands[1]))
14132 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14133 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14134 && SELECT_CC_MODE (GET_CODE (operands[0]),
14135 operands[1], operands[2]) == CCFPmode
14136 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14139 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14140 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14141 ;; with a precedence over other operators and is always put in the first
14142 ;; place. Swap condition and operands to match ficom instruction.
14144 (define_insn "*fp_jcc_8<mode>_387"
14146 (if_then_else (match_operator 0 "comparison_operator"
14147 [(match_operator 1 "float_operator"
14148 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14149 (match_operand 3 "register_operand" "f,f")])
14150 (label_ref (match_operand 4 "" ""))
14152 (clobber (reg:CCFP FPSR_REG))
14153 (clobber (reg:CCFP FLAGS_REG))
14154 (clobber (match_scratch:HI 5 "=a,a"))]
14155 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14156 && FLOAT_MODE_P (GET_MODE (operands[3]))
14157 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14158 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14159 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14160 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14165 (if_then_else (match_operator 0 "comparison_operator"
14166 [(match_operand 1 "register_operand" "")
14167 (match_operand 2 "nonimmediate_operand" "")])
14168 (match_operand 3 "" "")
14169 (match_operand 4 "" "")))
14170 (clobber (reg:CCFP FPSR_REG))
14171 (clobber (reg:CCFP FLAGS_REG))]
14175 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14176 operands[3], operands[4], NULL_RTX, NULL_RTX);
14182 (if_then_else (match_operator 0 "comparison_operator"
14183 [(match_operand 1 "register_operand" "")
14184 (match_operand 2 "general_operand" "")])
14185 (match_operand 3 "" "")
14186 (match_operand 4 "" "")))
14187 (clobber (reg:CCFP FPSR_REG))
14188 (clobber (reg:CCFP FLAGS_REG))
14189 (clobber (match_scratch:HI 5 "=a"))]
14193 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14194 operands[3], operands[4], operands[5], NULL_RTX);
14200 (if_then_else (match_operator 0 "comparison_operator"
14201 [(match_operator 1 "float_operator"
14202 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14203 (match_operand 3 "register_operand" "")])
14204 (match_operand 4 "" "")
14205 (match_operand 5 "" "")))
14206 (clobber (reg:CCFP FPSR_REG))
14207 (clobber (reg:CCFP FLAGS_REG))
14208 (clobber (match_scratch:HI 6 "=a"))]
14212 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14213 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14214 operands[3], operands[7],
14215 operands[4], operands[5], operands[6], NULL_RTX);
14219 ;; %%% Kill this when reload knows how to do it.
14222 (if_then_else (match_operator 0 "comparison_operator"
14223 [(match_operator 1 "float_operator"
14224 [(match_operand:X87MODEI12 2 "register_operand" "")])
14225 (match_operand 3 "register_operand" "")])
14226 (match_operand 4 "" "")
14227 (match_operand 5 "" "")))
14228 (clobber (reg:CCFP FPSR_REG))
14229 (clobber (reg:CCFP FLAGS_REG))
14230 (clobber (match_scratch:HI 6 "=a"))]
14234 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14235 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14236 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14237 operands[3], operands[7],
14238 operands[4], operands[5], operands[6], operands[2]);
14242 ;; Unconditional and other jump instructions
14244 (define_insn "jump"
14246 (label_ref (match_operand 0 "" "")))]
14249 [(set_attr "type" "ibr")
14250 (set (attr "length")
14251 (if_then_else (and (ge (minus (match_dup 0) (pc))
14253 (lt (minus (match_dup 0) (pc))
14257 (set_attr "modrm" "0")])
14259 (define_expand "indirect_jump"
14260 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14264 (define_insn "*indirect_jump"
14265 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14268 [(set_attr "type" "ibr")
14269 (set_attr "length_immediate" "0")])
14271 (define_insn "*indirect_jump_rtx64"
14272 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14275 [(set_attr "type" "ibr")
14276 (set_attr "length_immediate" "0")])
14278 (define_expand "tablejump"
14279 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14280 (use (label_ref (match_operand 1 "" "")))])]
14283 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14284 relative. Convert the relative address to an absolute address. */
14288 enum rtx_code code;
14294 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14296 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14300 op1 = pic_offset_table_rtx;
14305 op0 = pic_offset_table_rtx;
14309 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14314 (define_insn "*tablejump_1"
14315 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14316 (use (label_ref (match_operand 1 "" "")))]
14319 [(set_attr "type" "ibr")
14320 (set_attr "length_immediate" "0")])
14322 (define_insn "*tablejump_1_rtx64"
14323 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14324 (use (label_ref (match_operand 1 "" "")))]
14327 [(set_attr "type" "ibr")
14328 (set_attr "length_immediate" "0")])
14330 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14333 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14334 (set (match_operand:QI 1 "register_operand" "")
14335 (match_operator:QI 2 "ix86_comparison_operator"
14336 [(reg FLAGS_REG) (const_int 0)]))
14337 (set (match_operand 3 "q_regs_operand" "")
14338 (zero_extend (match_dup 1)))]
14339 "(peep2_reg_dead_p (3, operands[1])
14340 || operands_match_p (operands[1], operands[3]))
14341 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14342 [(set (match_dup 4) (match_dup 0))
14343 (set (strict_low_part (match_dup 5))
14346 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14347 operands[5] = gen_lowpart (QImode, operands[3]);
14348 ix86_expand_clear (operands[3]);
14351 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14354 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14355 (set (match_operand:QI 1 "register_operand" "")
14356 (match_operator:QI 2 "ix86_comparison_operator"
14357 [(reg FLAGS_REG) (const_int 0)]))
14358 (parallel [(set (match_operand 3 "q_regs_operand" "")
14359 (zero_extend (match_dup 1)))
14360 (clobber (reg:CC FLAGS_REG))])]
14361 "(peep2_reg_dead_p (3, operands[1])
14362 || operands_match_p (operands[1], operands[3]))
14363 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14364 [(set (match_dup 4) (match_dup 0))
14365 (set (strict_low_part (match_dup 5))
14368 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14369 operands[5] = gen_lowpart (QImode, operands[3]);
14370 ix86_expand_clear (operands[3]);
14373 ;; Call instructions.
14375 ;; The predicates normally associated with named expanders are not properly
14376 ;; checked for calls. This is a bug in the generic code, but it isn't that
14377 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14379 ;; Call subroutine returning no value.
14381 (define_expand "call_pop"
14382 [(parallel [(call (match_operand:QI 0 "" "")
14383 (match_operand:SI 1 "" ""))
14384 (set (reg:SI SP_REG)
14385 (plus:SI (reg:SI SP_REG)
14386 (match_operand:SI 3 "" "")))])]
14389 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14393 (define_insn "*call_pop_0"
14394 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14395 (match_operand:SI 1 "" ""))
14396 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14397 (match_operand:SI 2 "immediate_operand" "")))]
14400 if (SIBLING_CALL_P (insn))
14403 return "call\t%P0";
14405 [(set_attr "type" "call")])
14407 (define_insn "*call_pop_1"
14408 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14409 (match_operand:SI 1 "" ""))
14410 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14411 (match_operand:SI 2 "immediate_operand" "i")))]
14414 if (constant_call_address_operand (operands[0], Pmode))
14416 if (SIBLING_CALL_P (insn))
14419 return "call\t%P0";
14421 if (SIBLING_CALL_P (insn))
14424 return "call\t%A0";
14426 [(set_attr "type" "call")])
14428 (define_expand "call"
14429 [(call (match_operand:QI 0 "" "")
14430 (match_operand 1 "" ""))
14431 (use (match_operand 2 "" ""))]
14434 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14438 (define_expand "sibcall"
14439 [(call (match_operand:QI 0 "" "")
14440 (match_operand 1 "" ""))
14441 (use (match_operand 2 "" ""))]
14444 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14448 (define_insn "*call_0"
14449 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14450 (match_operand 1 "" ""))]
14453 if (SIBLING_CALL_P (insn))
14456 return "call\t%P0";
14458 [(set_attr "type" "call")])
14460 (define_insn "*call_1"
14461 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14462 (match_operand 1 "" ""))]
14463 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14465 if (constant_call_address_operand (operands[0], Pmode))
14466 return "call\t%P0";
14467 return "call\t%A0";
14469 [(set_attr "type" "call")])
14471 (define_insn "*sibcall_1"
14472 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14473 (match_operand 1 "" ""))]
14474 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14476 if (constant_call_address_operand (operands[0], Pmode))
14480 [(set_attr "type" "call")])
14482 (define_insn "*call_1_rex64"
14483 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14484 (match_operand 1 "" ""))]
14485 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14487 if (constant_call_address_operand (operands[0], Pmode))
14488 return "call\t%P0";
14489 return "call\t%A0";
14491 [(set_attr "type" "call")])
14493 (define_insn "*sibcall_1_rex64"
14494 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14495 (match_operand 1 "" ""))]
14496 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14498 [(set_attr "type" "call")])
14500 (define_insn "*sibcall_1_rex64_v"
14501 [(call (mem:QI (reg:DI R11_REG))
14502 (match_operand 0 "" ""))]
14503 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14505 [(set_attr "type" "call")])
14508 ;; Call subroutine, returning value in operand 0
14510 (define_expand "call_value_pop"
14511 [(parallel [(set (match_operand 0 "" "")
14512 (call (match_operand:QI 1 "" "")
14513 (match_operand:SI 2 "" "")))
14514 (set (reg:SI SP_REG)
14515 (plus:SI (reg:SI SP_REG)
14516 (match_operand:SI 4 "" "")))])]
14519 ix86_expand_call (operands[0], operands[1], operands[2],
14520 operands[3], operands[4], 0);
14524 (define_expand "call_value"
14525 [(set (match_operand 0 "" "")
14526 (call (match_operand:QI 1 "" "")
14527 (match_operand:SI 2 "" "")))
14528 (use (match_operand:SI 3 "" ""))]
14529 ;; Operand 2 not used on the i386.
14532 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14536 (define_expand "sibcall_value"
14537 [(set (match_operand 0 "" "")
14538 (call (match_operand:QI 1 "" "")
14539 (match_operand:SI 2 "" "")))
14540 (use (match_operand:SI 3 "" ""))]
14541 ;; Operand 2 not used on the i386.
14544 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14548 ;; Call subroutine returning any type.
14550 (define_expand "untyped_call"
14551 [(parallel [(call (match_operand 0 "" "")
14553 (match_operand 1 "" "")
14554 (match_operand 2 "" "")])]
14559 /* In order to give reg-stack an easier job in validating two
14560 coprocessor registers as containing a possible return value,
14561 simply pretend the untyped call returns a complex long double
14564 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14565 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14566 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14569 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14571 rtx set = XVECEXP (operands[2], 0, i);
14572 emit_move_insn (SET_DEST (set), SET_SRC (set));
14575 /* The optimizer does not know that the call sets the function value
14576 registers we stored in the result block. We avoid problems by
14577 claiming that all hard registers are used and clobbered at this
14579 emit_insn (gen_blockage (const0_rtx));
14584 ;; Prologue and epilogue instructions
14586 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14587 ;; all of memory. This blocks insns from being moved across this point.
14589 (define_insn "blockage"
14590 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14593 [(set_attr "length" "0")])
14595 ;; Insn emitted into the body of a function to return from a function.
14596 ;; This is only done if the function's epilogue is known to be simple.
14597 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14599 (define_expand "return"
14601 "ix86_can_use_return_insn_p ()"
14603 if (current_function_pops_args)
14605 rtx popc = GEN_INT (current_function_pops_args);
14606 emit_jump_insn (gen_return_pop_internal (popc));
14611 (define_insn "return_internal"
14615 [(set_attr "length" "1")
14616 (set_attr "length_immediate" "0")
14617 (set_attr "modrm" "0")])
14619 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14620 ;; instruction Athlon and K8 have.
14622 (define_insn "return_internal_long"
14624 (unspec [(const_int 0)] UNSPEC_REP)]
14627 [(set_attr "length" "1")
14628 (set_attr "length_immediate" "0")
14629 (set_attr "prefix_rep" "1")
14630 (set_attr "modrm" "0")])
14632 (define_insn "return_pop_internal"
14634 (use (match_operand:SI 0 "const_int_operand" ""))]
14637 [(set_attr "length" "3")
14638 (set_attr "length_immediate" "2")
14639 (set_attr "modrm" "0")])
14641 (define_insn "return_indirect_internal"
14643 (use (match_operand:SI 0 "register_operand" "r"))]
14646 [(set_attr "type" "ibr")
14647 (set_attr "length_immediate" "0")])
14653 [(set_attr "length" "1")
14654 (set_attr "length_immediate" "0")
14655 (set_attr "modrm" "0")])
14657 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14658 ;; branch prediction penalty for the third jump in a 16-byte
14661 (define_insn "align"
14662 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14665 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14666 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14668 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14669 The align insn is used to avoid 3 jump instructions in the row to improve
14670 branch prediction and the benefits hardly outweigh the cost of extra 8
14671 nops on the average inserted by full alignment pseudo operation. */
14675 [(set_attr "length" "16")])
14677 (define_expand "prologue"
14680 "ix86_expand_prologue (); DONE;")
14682 (define_insn "set_got"
14683 [(set (match_operand:SI 0 "register_operand" "=r")
14684 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14685 (clobber (reg:CC FLAGS_REG))]
14687 { return output_set_got (operands[0], NULL_RTX); }
14688 [(set_attr "type" "multi")
14689 (set_attr "length" "12")])
14691 (define_insn "set_got_labelled"
14692 [(set (match_operand:SI 0 "register_operand" "=r")
14693 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14695 (clobber (reg:CC FLAGS_REG))]
14697 { return output_set_got (operands[0], operands[1]); }
14698 [(set_attr "type" "multi")
14699 (set_attr "length" "12")])
14701 (define_insn "set_got_rex64"
14702 [(set (match_operand:DI 0 "register_operand" "=r")
14703 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14705 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14706 [(set_attr "type" "lea")
14707 (set_attr "length" "6")])
14709 (define_expand "epilogue"
14712 "ix86_expand_epilogue (1); DONE;")
14714 (define_expand "sibcall_epilogue"
14717 "ix86_expand_epilogue (0); DONE;")
14719 (define_expand "eh_return"
14720 [(use (match_operand 0 "register_operand" ""))]
14723 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14725 /* Tricky bit: we write the address of the handler to which we will
14726 be returning into someone else's stack frame, one word below the
14727 stack address we wish to restore. */
14728 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14729 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14730 tmp = gen_rtx_MEM (Pmode, tmp);
14731 emit_move_insn (tmp, ra);
14733 if (Pmode == SImode)
14734 emit_jump_insn (gen_eh_return_si (sa));
14736 emit_jump_insn (gen_eh_return_di (sa));
14741 (define_insn_and_split "eh_return_si"
14743 (unspec [(match_operand:SI 0 "register_operand" "c")]
14744 UNSPEC_EH_RETURN))]
14749 "ix86_expand_epilogue (2); DONE;")
14751 (define_insn_and_split "eh_return_di"
14753 (unspec [(match_operand:DI 0 "register_operand" "c")]
14754 UNSPEC_EH_RETURN))]
14759 "ix86_expand_epilogue (2); DONE;")
14761 (define_insn "leave"
14762 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14763 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14764 (clobber (mem:BLK (scratch)))]
14767 [(set_attr "type" "leave")])
14769 (define_insn "leave_rex64"
14770 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14771 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14772 (clobber (mem:BLK (scratch)))]
14775 [(set_attr "type" "leave")])
14777 (define_expand "ffssi2"
14779 [(set (match_operand:SI 0 "register_operand" "")
14780 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14781 (clobber (match_scratch:SI 2 ""))
14782 (clobber (reg:CC FLAGS_REG))])]
14786 (define_insn_and_split "*ffs_cmove"
14787 [(set (match_operand:SI 0 "register_operand" "=r")
14788 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14789 (clobber (match_scratch:SI 2 "=&r"))
14790 (clobber (reg:CC FLAGS_REG))]
14793 "&& reload_completed"
14794 [(set (match_dup 2) (const_int -1))
14795 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14796 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14797 (set (match_dup 0) (if_then_else:SI
14798 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14801 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14802 (clobber (reg:CC FLAGS_REG))])]
14805 (define_insn_and_split "*ffs_no_cmove"
14806 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14807 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14808 (clobber (match_scratch:SI 2 "=&q"))
14809 (clobber (reg:CC FLAGS_REG))]
14813 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14814 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14815 (set (strict_low_part (match_dup 3))
14816 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14817 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14818 (clobber (reg:CC FLAGS_REG))])
14819 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14820 (clobber (reg:CC FLAGS_REG))])
14821 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14822 (clobber (reg:CC FLAGS_REG))])]
14824 operands[3] = gen_lowpart (QImode, operands[2]);
14825 ix86_expand_clear (operands[2]);
14828 (define_insn "*ffssi_1"
14829 [(set (reg:CCZ FLAGS_REG)
14830 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14832 (set (match_operand:SI 0 "register_operand" "=r")
14833 (ctz:SI (match_dup 1)))]
14835 "bsf{l}\t{%1, %0|%0, %1}"
14836 [(set_attr "prefix_0f" "1")])
14838 (define_expand "ffsdi2"
14840 [(set (match_operand:DI 0 "register_operand" "")
14841 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14842 (clobber (match_scratch:DI 2 ""))
14843 (clobber (reg:CC FLAGS_REG))])]
14844 "TARGET_64BIT && TARGET_CMOVE"
14847 (define_insn_and_split "*ffs_rex64"
14848 [(set (match_operand:DI 0 "register_operand" "=r")
14849 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14850 (clobber (match_scratch:DI 2 "=&r"))
14851 (clobber (reg:CC FLAGS_REG))]
14852 "TARGET_64BIT && TARGET_CMOVE"
14854 "&& reload_completed"
14855 [(set (match_dup 2) (const_int -1))
14856 (parallel [(set (reg:CCZ FLAGS_REG)
14857 (compare:CCZ (match_dup 1) (const_int 0)))
14858 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14859 (set (match_dup 0) (if_then_else:DI
14860 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14863 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14864 (clobber (reg:CC FLAGS_REG))])]
14867 (define_insn "*ffsdi_1"
14868 [(set (reg:CCZ FLAGS_REG)
14869 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14871 (set (match_operand:DI 0 "register_operand" "=r")
14872 (ctz:DI (match_dup 1)))]
14874 "bsf{q}\t{%1, %0|%0, %1}"
14875 [(set_attr "prefix_0f" "1")])
14877 (define_insn "ctzsi2"
14878 [(set (match_operand:SI 0 "register_operand" "=r")
14879 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14880 (clobber (reg:CC FLAGS_REG))]
14882 "bsf{l}\t{%1, %0|%0, %1}"
14883 [(set_attr "prefix_0f" "1")])
14885 (define_insn "ctzdi2"
14886 [(set (match_operand:DI 0 "register_operand" "=r")
14887 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14888 (clobber (reg:CC FLAGS_REG))]
14890 "bsf{q}\t{%1, %0|%0, %1}"
14891 [(set_attr "prefix_0f" "1")])
14893 (define_expand "clzsi2"
14895 [(set (match_operand:SI 0 "register_operand" "")
14896 (minus:SI (const_int 31)
14897 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14898 (clobber (reg:CC FLAGS_REG))])
14900 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14901 (clobber (reg:CC FLAGS_REG))])]
14906 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14911 (define_insn "clzsi2_abm"
14912 [(set (match_operand:SI 0 "register_operand" "=r")
14913 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14914 (clobber (reg:CC FLAGS_REG))]
14916 "lzcnt{l}\t{%1, %0|%0, %1}"
14917 [(set_attr "prefix_rep" "1")
14918 (set_attr "type" "bitmanip")
14919 (set_attr "mode" "SI")])
14921 (define_insn "*bsr"
14922 [(set (match_operand:SI 0 "register_operand" "=r")
14923 (minus:SI (const_int 31)
14924 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14925 (clobber (reg:CC FLAGS_REG))]
14927 "bsr{l}\t{%1, %0|%0, %1}"
14928 [(set_attr "prefix_0f" "1")
14929 (set_attr "mode" "SI")])
14931 (define_insn "popcountsi2"
14932 [(set (match_operand:SI 0 "register_operand" "=r")
14933 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14934 (clobber (reg:CC FLAGS_REG))]
14936 "popcnt{l}\t{%1, %0|%0, %1}"
14937 [(set_attr "prefix_rep" "1")
14938 (set_attr "type" "bitmanip")
14939 (set_attr "mode" "SI")])
14941 (define_insn "*popcountsi2_cmp"
14942 [(set (reg FLAGS_REG)
14944 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14946 (set (match_operand:SI 0 "register_operand" "=r")
14947 (popcount:SI (match_dup 1)))]
14948 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14949 "popcnt{l}\t{%1, %0|%0, %1}"
14950 [(set_attr "prefix_rep" "1")
14951 (set_attr "type" "bitmanip")
14952 (set_attr "mode" "SI")])
14954 (define_insn "*popcountsi2_cmp_zext"
14955 [(set (reg FLAGS_REG)
14957 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14959 (set (match_operand:DI 0 "register_operand" "=r")
14960 (zero_extend:DI(popcount:SI (match_dup 1))))]
14961 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14962 "popcnt{l}\t{%1, %0|%0, %1}"
14963 [(set_attr "prefix_rep" "1")
14964 (set_attr "type" "bitmanip")
14965 (set_attr "mode" "SI")])
14967 (define_insn "bswapsi2"
14968 [(set (match_operand:SI 0 "register_operand" "=r")
14969 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14970 (clobber (reg:CC FLAGS_REG))]
14973 [(set_attr "prefix_0f" "1")
14974 (set_attr "length" "2")])
14976 (define_insn "bswapdi2"
14977 [(set (match_operand:DI 0 "register_operand" "=r")
14978 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14979 (clobber (reg:CC FLAGS_REG))]
14980 "TARGET_64BIT && TARGET_BSWAP"
14982 [(set_attr "prefix_0f" "1")
14983 (set_attr "length" "3")])
14985 (define_expand "clzdi2"
14987 [(set (match_operand:DI 0 "register_operand" "")
14988 (minus:DI (const_int 63)
14989 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14990 (clobber (reg:CC FLAGS_REG))])
14992 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14993 (clobber (reg:CC FLAGS_REG))])]
14998 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15003 (define_insn "clzdi2_abm"
15004 [(set (match_operand:DI 0 "register_operand" "=r")
15005 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15006 (clobber (reg:CC FLAGS_REG))]
15007 "TARGET_64BIT && TARGET_ABM"
15008 "lzcnt{q}\t{%1, %0|%0, %1}"
15009 [(set_attr "prefix_rep" "1")
15010 (set_attr "type" "bitmanip")
15011 (set_attr "mode" "DI")])
15013 (define_insn "*bsr_rex64"
15014 [(set (match_operand:DI 0 "register_operand" "=r")
15015 (minus:DI (const_int 63)
15016 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15017 (clobber (reg:CC FLAGS_REG))]
15019 "bsr{q}\t{%1, %0|%0, %1}"
15020 [(set_attr "prefix_0f" "1")
15021 (set_attr "mode" "DI")])
15023 (define_insn "popcountdi2"
15024 [(set (match_operand:DI 0 "register_operand" "=r")
15025 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15026 (clobber (reg:CC FLAGS_REG))]
15027 "TARGET_64BIT && TARGET_POPCNT"
15028 "popcnt{q}\t{%1, %0|%0, %1}"
15029 [(set_attr "prefix_rep" "1")
15030 (set_attr "type" "bitmanip")
15031 (set_attr "mode" "DI")])
15033 (define_insn "*popcountdi2_cmp"
15034 [(set (reg FLAGS_REG)
15036 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15038 (set (match_operand:DI 0 "register_operand" "=r")
15039 (popcount:DI (match_dup 1)))]
15040 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15041 "popcnt{q}\t{%1, %0|%0, %1}"
15042 [(set_attr "prefix_rep" "1")
15043 (set_attr "type" "bitmanip")
15044 (set_attr "mode" "DI")])
15046 (define_expand "clzhi2"
15048 [(set (match_operand:HI 0 "register_operand" "")
15049 (minus:HI (const_int 15)
15050 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15051 (clobber (reg:CC FLAGS_REG))])
15053 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15054 (clobber (reg:CC FLAGS_REG))])]
15059 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15064 (define_insn "clzhi2_abm"
15065 [(set (match_operand:HI 0 "register_operand" "=r")
15066 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15067 (clobber (reg:CC FLAGS_REG))]
15069 "lzcnt{w}\t{%1, %0|%0, %1}"
15070 [(set_attr "prefix_rep" "1")
15071 (set_attr "type" "bitmanip")
15072 (set_attr "mode" "HI")])
15074 (define_insn "*bsrhi"
15075 [(set (match_operand:HI 0 "register_operand" "=r")
15076 (minus:HI (const_int 15)
15077 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15078 (clobber (reg:CC FLAGS_REG))]
15080 "bsr{w}\t{%1, %0|%0, %1}"
15081 [(set_attr "prefix_0f" "1")
15082 (set_attr "mode" "HI")])
15084 (define_insn "popcounthi2"
15085 [(set (match_operand:HI 0 "register_operand" "=r")
15086 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15087 (clobber (reg:CC FLAGS_REG))]
15089 "popcnt{w}\t{%1, %0|%0, %1}"
15090 [(set_attr "prefix_rep" "1")
15091 (set_attr "type" "bitmanip")
15092 (set_attr "mode" "HI")])
15094 (define_insn "*popcounthi2_cmp"
15095 [(set (reg FLAGS_REG)
15097 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15099 (set (match_operand:HI 0 "register_operand" "=r")
15100 (popcount:HI (match_dup 1)))]
15101 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15102 "popcnt{w}\t{%1, %0|%0, %1}"
15103 [(set_attr "prefix_rep" "1")
15104 (set_attr "type" "bitmanip")
15105 (set_attr "mode" "HI")])
15107 ;; Thread-local storage patterns for ELF.
15109 ;; Note that these code sequences must appear exactly as shown
15110 ;; in order to allow linker relaxation.
15112 (define_insn "*tls_global_dynamic_32_gnu"
15113 [(set (match_operand:SI 0 "register_operand" "=a")
15114 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15115 (match_operand:SI 2 "tls_symbolic_operand" "")
15116 (match_operand:SI 3 "call_insn_operand" "")]
15118 (clobber (match_scratch:SI 4 "=d"))
15119 (clobber (match_scratch:SI 5 "=c"))
15120 (clobber (reg:CC FLAGS_REG))]
15121 "!TARGET_64BIT && TARGET_GNU_TLS"
15122 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15123 [(set_attr "type" "multi")
15124 (set_attr "length" "12")])
15126 (define_insn "*tls_global_dynamic_32_sun"
15127 [(set (match_operand:SI 0 "register_operand" "=a")
15128 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15129 (match_operand:SI 2 "tls_symbolic_operand" "")
15130 (match_operand:SI 3 "call_insn_operand" "")]
15132 (clobber (match_scratch:SI 4 "=d"))
15133 (clobber (match_scratch:SI 5 "=c"))
15134 (clobber (reg:CC FLAGS_REG))]
15135 "!TARGET_64BIT && TARGET_SUN_TLS"
15136 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15137 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15138 [(set_attr "type" "multi")
15139 (set_attr "length" "14")])
15141 (define_expand "tls_global_dynamic_32"
15142 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15145 (match_operand:SI 1 "tls_symbolic_operand" "")
15148 (clobber (match_scratch:SI 4 ""))
15149 (clobber (match_scratch:SI 5 ""))
15150 (clobber (reg:CC FLAGS_REG))])]
15154 operands[2] = pic_offset_table_rtx;
15157 operands[2] = gen_reg_rtx (Pmode);
15158 emit_insn (gen_set_got (operands[2]));
15160 if (TARGET_GNU2_TLS)
15162 emit_insn (gen_tls_dynamic_gnu2_32
15163 (operands[0], operands[1], operands[2]));
15166 operands[3] = ix86_tls_get_addr ();
15169 (define_insn "*tls_global_dynamic_64"
15170 [(set (match_operand:DI 0 "register_operand" "=a")
15171 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15172 (match_operand:DI 3 "" "")))
15173 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15176 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15177 [(set_attr "type" "multi")
15178 (set_attr "length" "16")])
15180 (define_expand "tls_global_dynamic_64"
15181 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15182 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15183 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15187 if (TARGET_GNU2_TLS)
15189 emit_insn (gen_tls_dynamic_gnu2_64
15190 (operands[0], operands[1]));
15193 operands[2] = ix86_tls_get_addr ();
15196 (define_insn "*tls_local_dynamic_base_32_gnu"
15197 [(set (match_operand:SI 0 "register_operand" "=a")
15198 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15199 (match_operand:SI 2 "call_insn_operand" "")]
15200 UNSPEC_TLS_LD_BASE))
15201 (clobber (match_scratch:SI 3 "=d"))
15202 (clobber (match_scratch:SI 4 "=c"))
15203 (clobber (reg:CC FLAGS_REG))]
15204 "!TARGET_64BIT && TARGET_GNU_TLS"
15205 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15206 [(set_attr "type" "multi")
15207 (set_attr "length" "11")])
15209 (define_insn "*tls_local_dynamic_base_32_sun"
15210 [(set (match_operand:SI 0 "register_operand" "=a")
15211 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15212 (match_operand:SI 2 "call_insn_operand" "")]
15213 UNSPEC_TLS_LD_BASE))
15214 (clobber (match_scratch:SI 3 "=d"))
15215 (clobber (match_scratch:SI 4 "=c"))
15216 (clobber (reg:CC FLAGS_REG))]
15217 "!TARGET_64BIT && TARGET_SUN_TLS"
15218 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15219 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15220 [(set_attr "type" "multi")
15221 (set_attr "length" "13")])
15223 (define_expand "tls_local_dynamic_base_32"
15224 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15225 (unspec:SI [(match_dup 1) (match_dup 2)]
15226 UNSPEC_TLS_LD_BASE))
15227 (clobber (match_scratch:SI 3 ""))
15228 (clobber (match_scratch:SI 4 ""))
15229 (clobber (reg:CC FLAGS_REG))])]
15233 operands[1] = pic_offset_table_rtx;
15236 operands[1] = gen_reg_rtx (Pmode);
15237 emit_insn (gen_set_got (operands[1]));
15239 if (TARGET_GNU2_TLS)
15241 emit_insn (gen_tls_dynamic_gnu2_32
15242 (operands[0], ix86_tls_module_base (), operands[1]));
15245 operands[2] = ix86_tls_get_addr ();
15248 (define_insn "*tls_local_dynamic_base_64"
15249 [(set (match_operand:DI 0 "register_operand" "=a")
15250 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15251 (match_operand:DI 2 "" "")))
15252 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15254 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15255 [(set_attr "type" "multi")
15256 (set_attr "length" "12")])
15258 (define_expand "tls_local_dynamic_base_64"
15259 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15260 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15261 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15264 if (TARGET_GNU2_TLS)
15266 emit_insn (gen_tls_dynamic_gnu2_64
15267 (operands[0], ix86_tls_module_base ()));
15270 operands[1] = ix86_tls_get_addr ();
15273 ;; Local dynamic of a single variable is a lose. Show combine how
15274 ;; to convert that back to global dynamic.
15276 (define_insn_and_split "*tls_local_dynamic_32_once"
15277 [(set (match_operand:SI 0 "register_operand" "=a")
15278 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15279 (match_operand:SI 2 "call_insn_operand" "")]
15280 UNSPEC_TLS_LD_BASE)
15281 (const:SI (unspec:SI
15282 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15284 (clobber (match_scratch:SI 4 "=d"))
15285 (clobber (match_scratch:SI 5 "=c"))
15286 (clobber (reg:CC FLAGS_REG))]
15290 [(parallel [(set (match_dup 0)
15291 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15293 (clobber (match_dup 4))
15294 (clobber (match_dup 5))
15295 (clobber (reg:CC FLAGS_REG))])]
15298 ;; Load and add the thread base pointer from %gs:0.
15300 (define_insn "*load_tp_si"
15301 [(set (match_operand:SI 0 "register_operand" "=r")
15302 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15304 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15305 [(set_attr "type" "imov")
15306 (set_attr "modrm" "0")
15307 (set_attr "length" "7")
15308 (set_attr "memory" "load")
15309 (set_attr "imm_disp" "false")])
15311 (define_insn "*add_tp_si"
15312 [(set (match_operand:SI 0 "register_operand" "=r")
15313 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15314 (match_operand:SI 1 "register_operand" "0")))
15315 (clobber (reg:CC FLAGS_REG))]
15317 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15318 [(set_attr "type" "alu")
15319 (set_attr "modrm" "0")
15320 (set_attr "length" "7")
15321 (set_attr "memory" "load")
15322 (set_attr "imm_disp" "false")])
15324 (define_insn "*load_tp_di"
15325 [(set (match_operand:DI 0 "register_operand" "=r")
15326 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15328 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15329 [(set_attr "type" "imov")
15330 (set_attr "modrm" "0")
15331 (set_attr "length" "7")
15332 (set_attr "memory" "load")
15333 (set_attr "imm_disp" "false")])
15335 (define_insn "*add_tp_di"
15336 [(set (match_operand:DI 0 "register_operand" "=r")
15337 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15338 (match_operand:DI 1 "register_operand" "0")))
15339 (clobber (reg:CC FLAGS_REG))]
15341 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15342 [(set_attr "type" "alu")
15343 (set_attr "modrm" "0")
15344 (set_attr "length" "7")
15345 (set_attr "memory" "load")
15346 (set_attr "imm_disp" "false")])
15348 ;; GNU2 TLS patterns can be split.
15350 (define_expand "tls_dynamic_gnu2_32"
15351 [(set (match_dup 3)
15352 (plus:SI (match_operand:SI 2 "register_operand" "")
15354 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15357 [(set (match_operand:SI 0 "register_operand" "")
15358 (unspec:SI [(match_dup 1) (match_dup 3)
15359 (match_dup 2) (reg:SI SP_REG)]
15361 (clobber (reg:CC FLAGS_REG))])]
15362 "!TARGET_64BIT && TARGET_GNU2_TLS"
15364 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15365 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15368 (define_insn "*tls_dynamic_lea_32"
15369 [(set (match_operand:SI 0 "register_operand" "=r")
15370 (plus:SI (match_operand:SI 1 "register_operand" "b")
15372 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15373 UNSPEC_TLSDESC))))]
15374 "!TARGET_64BIT && TARGET_GNU2_TLS"
15375 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15376 [(set_attr "type" "lea")
15377 (set_attr "mode" "SI")
15378 (set_attr "length" "6")
15379 (set_attr "length_address" "4")])
15381 (define_insn "*tls_dynamic_call_32"
15382 [(set (match_operand:SI 0 "register_operand" "=a")
15383 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15384 (match_operand:SI 2 "register_operand" "0")
15385 ;; we have to make sure %ebx still points to the GOT
15386 (match_operand:SI 3 "register_operand" "b")
15389 (clobber (reg:CC FLAGS_REG))]
15390 "!TARGET_64BIT && TARGET_GNU2_TLS"
15391 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15392 [(set_attr "type" "call")
15393 (set_attr "length" "2")
15394 (set_attr "length_address" "0")])
15396 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15397 [(set (match_operand:SI 0 "register_operand" "=&a")
15399 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15400 (match_operand:SI 4 "" "")
15401 (match_operand:SI 2 "register_operand" "b")
15404 (const:SI (unspec:SI
15405 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15407 (clobber (reg:CC FLAGS_REG))]
15408 "!TARGET_64BIT && TARGET_GNU2_TLS"
15411 [(set (match_dup 0) (match_dup 5))]
15413 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15414 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15417 (define_expand "tls_dynamic_gnu2_64"
15418 [(set (match_dup 2)
15419 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15422 [(set (match_operand:DI 0 "register_operand" "")
15423 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15425 (clobber (reg:CC FLAGS_REG))])]
15426 "TARGET_64BIT && TARGET_GNU2_TLS"
15428 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15429 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15432 (define_insn "*tls_dynamic_lea_64"
15433 [(set (match_operand:DI 0 "register_operand" "=r")
15434 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15436 "TARGET_64BIT && TARGET_GNU2_TLS"
15437 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15438 [(set_attr "type" "lea")
15439 (set_attr "mode" "DI")
15440 (set_attr "length" "7")
15441 (set_attr "length_address" "4")])
15443 (define_insn "*tls_dynamic_call_64"
15444 [(set (match_operand:DI 0 "register_operand" "=a")
15445 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15446 (match_operand:DI 2 "register_operand" "0")
15449 (clobber (reg:CC FLAGS_REG))]
15450 "TARGET_64BIT && TARGET_GNU2_TLS"
15451 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15452 [(set_attr "type" "call")
15453 (set_attr "length" "2")
15454 (set_attr "length_address" "0")])
15456 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15457 [(set (match_operand:DI 0 "register_operand" "=&a")
15459 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15460 (match_operand:DI 3 "" "")
15463 (const:DI (unspec:DI
15464 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15466 (clobber (reg:CC FLAGS_REG))]
15467 "TARGET_64BIT && TARGET_GNU2_TLS"
15470 [(set (match_dup 0) (match_dup 4))]
15472 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15473 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15478 ;; These patterns match the binary 387 instructions for addM3, subM3,
15479 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15480 ;; SFmode. The first is the normal insn, the second the same insn but
15481 ;; with one operand a conversion, and the third the same insn but with
15482 ;; the other operand a conversion. The conversion may be SFmode or
15483 ;; SImode if the target mode DFmode, but only SImode if the target mode
15486 ;; Gcc is slightly more smart about handling normal two address instructions
15487 ;; so use special patterns for add and mull.
15489 (define_insn "*fop_sf_comm_mixed"
15490 [(set (match_operand:SF 0 "register_operand" "=f,x")
15491 (match_operator:SF 3 "binary_fp_operator"
15492 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15493 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15494 "TARGET_MIX_SSE_I387
15495 && COMMUTATIVE_ARITH_P (operands[3])
15496 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15497 "* return output_387_binary_op (insn, operands);"
15498 [(set (attr "type")
15499 (if_then_else (eq_attr "alternative" "1")
15500 (if_then_else (match_operand:SF 3 "mult_operator" "")
15501 (const_string "ssemul")
15502 (const_string "sseadd"))
15503 (if_then_else (match_operand:SF 3 "mult_operator" "")
15504 (const_string "fmul")
15505 (const_string "fop"))))
15506 (set_attr "mode" "SF")])
15508 (define_insn "*fop_sf_comm_sse"
15509 [(set (match_operand:SF 0 "register_operand" "=x")
15510 (match_operator:SF 3 "binary_fp_operator"
15511 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15512 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15514 && COMMUTATIVE_ARITH_P (operands[3])
15515 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15516 "* return output_387_binary_op (insn, operands);"
15517 [(set (attr "type")
15518 (if_then_else (match_operand:SF 3 "mult_operator" "")
15519 (const_string "ssemul")
15520 (const_string "sseadd")))
15521 (set_attr "mode" "SF")])
15523 (define_insn "*fop_sf_comm_i387"
15524 [(set (match_operand:SF 0 "register_operand" "=f")
15525 (match_operator:SF 3 "binary_fp_operator"
15526 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15527 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15529 && COMMUTATIVE_ARITH_P (operands[3])
15530 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15531 "* return output_387_binary_op (insn, operands);"
15532 [(set (attr "type")
15533 (if_then_else (match_operand:SF 3 "mult_operator" "")
15534 (const_string "fmul")
15535 (const_string "fop")))
15536 (set_attr "mode" "SF")])
15538 (define_insn "*fop_sf_1_mixed"
15539 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15540 (match_operator:SF 3 "binary_fp_operator"
15541 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15542 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15543 "TARGET_MIX_SSE_I387
15544 && !COMMUTATIVE_ARITH_P (operands[3])
15545 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15546 "* return output_387_binary_op (insn, operands);"
15547 [(set (attr "type")
15548 (cond [(and (eq_attr "alternative" "2")
15549 (match_operand:SF 3 "mult_operator" ""))
15550 (const_string "ssemul")
15551 (and (eq_attr "alternative" "2")
15552 (match_operand:SF 3 "div_operator" ""))
15553 (const_string "ssediv")
15554 (eq_attr "alternative" "2")
15555 (const_string "sseadd")
15556 (match_operand:SF 3 "mult_operator" "")
15557 (const_string "fmul")
15558 (match_operand:SF 3 "div_operator" "")
15559 (const_string "fdiv")
15561 (const_string "fop")))
15562 (set_attr "mode" "SF")])
15564 (define_insn "*fop_sf_1_sse"
15565 [(set (match_operand:SF 0 "register_operand" "=x")
15566 (match_operator:SF 3 "binary_fp_operator"
15567 [(match_operand:SF 1 "register_operand" "0")
15568 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15570 && !COMMUTATIVE_ARITH_P (operands[3])"
15571 "* return output_387_binary_op (insn, operands);"
15572 [(set (attr "type")
15573 (cond [(match_operand:SF 3 "mult_operator" "")
15574 (const_string "ssemul")
15575 (match_operand:SF 3 "div_operator" "")
15576 (const_string "ssediv")
15578 (const_string "sseadd")))
15579 (set_attr "mode" "SF")])
15581 ;; This pattern is not fully shadowed by the pattern above.
15582 (define_insn "*fop_sf_1_i387"
15583 [(set (match_operand:SF 0 "register_operand" "=f,f")
15584 (match_operator:SF 3 "binary_fp_operator"
15585 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15586 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15587 "TARGET_80387 && !TARGET_SSE_MATH
15588 && !COMMUTATIVE_ARITH_P (operands[3])
15589 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15590 "* return output_387_binary_op (insn, operands);"
15591 [(set (attr "type")
15592 (cond [(match_operand:SF 3 "mult_operator" "")
15593 (const_string "fmul")
15594 (match_operand:SF 3 "div_operator" "")
15595 (const_string "fdiv")
15597 (const_string "fop")))
15598 (set_attr "mode" "SF")])
15600 ;; ??? Add SSE splitters for these!
15601 (define_insn "*fop_sf_2<mode>_i387"
15602 [(set (match_operand:SF 0 "register_operand" "=f,f")
15603 (match_operator:SF 3 "binary_fp_operator"
15604 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15605 (match_operand:SF 2 "register_operand" "0,0")]))]
15606 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15607 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15608 [(set (attr "type")
15609 (cond [(match_operand:SF 3 "mult_operator" "")
15610 (const_string "fmul")
15611 (match_operand:SF 3 "div_operator" "")
15612 (const_string "fdiv")
15614 (const_string "fop")))
15615 (set_attr "fp_int_src" "true")
15616 (set_attr "mode" "<MODE>")])
15618 (define_insn "*fop_sf_3<mode>_i387"
15619 [(set (match_operand:SF 0 "register_operand" "=f,f")
15620 (match_operator:SF 3 "binary_fp_operator"
15621 [(match_operand:SF 1 "register_operand" "0,0")
15622 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15623 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15624 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15625 [(set (attr "type")
15626 (cond [(match_operand:SF 3 "mult_operator" "")
15627 (const_string "fmul")
15628 (match_operand:SF 3 "div_operator" "")
15629 (const_string "fdiv")
15631 (const_string "fop")))
15632 (set_attr "fp_int_src" "true")
15633 (set_attr "mode" "<MODE>")])
15635 (define_insn "*fop_df_comm_mixed"
15636 [(set (match_operand:DF 0 "register_operand" "=f,x")
15637 (match_operator:DF 3 "binary_fp_operator"
15638 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15639 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15640 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15641 && COMMUTATIVE_ARITH_P (operands[3])
15642 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15643 "* return output_387_binary_op (insn, operands);"
15644 [(set (attr "type")
15645 (if_then_else (eq_attr "alternative" "1")
15646 (if_then_else (match_operand:DF 3 "mult_operator" "")
15647 (const_string "ssemul")
15648 (const_string "sseadd"))
15649 (if_then_else (match_operand:DF 3 "mult_operator" "")
15650 (const_string "fmul")
15651 (const_string "fop"))))
15652 (set_attr "mode" "DF")])
15654 (define_insn "*fop_df_comm_sse"
15655 [(set (match_operand:DF 0 "register_operand" "=x")
15656 (match_operator:DF 3 "binary_fp_operator"
15657 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15658 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15659 "TARGET_SSE2 && TARGET_SSE_MATH
15660 && COMMUTATIVE_ARITH_P (operands[3])
15661 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15662 "* return output_387_binary_op (insn, operands);"
15663 [(set (attr "type")
15664 (if_then_else (match_operand:DF 3 "mult_operator" "")
15665 (const_string "ssemul")
15666 (const_string "sseadd")))
15667 (set_attr "mode" "DF")])
15669 (define_insn "*fop_df_comm_i387"
15670 [(set (match_operand:DF 0 "register_operand" "=f")
15671 (match_operator:DF 3 "binary_fp_operator"
15672 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15673 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15675 && COMMUTATIVE_ARITH_P (operands[3])
15676 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15677 "* return output_387_binary_op (insn, operands);"
15678 [(set (attr "type")
15679 (if_then_else (match_operand:DF 3 "mult_operator" "")
15680 (const_string "fmul")
15681 (const_string "fop")))
15682 (set_attr "mode" "DF")])
15684 (define_insn "*fop_df_1_mixed"
15685 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15686 (match_operator:DF 3 "binary_fp_operator"
15687 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15688 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15689 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15690 && !COMMUTATIVE_ARITH_P (operands[3])
15691 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15692 "* return output_387_binary_op (insn, operands);"
15693 [(set (attr "type")
15694 (cond [(and (eq_attr "alternative" "2")
15695 (match_operand:DF 3 "mult_operator" ""))
15696 (const_string "ssemul")
15697 (and (eq_attr "alternative" "2")
15698 (match_operand:DF 3 "div_operator" ""))
15699 (const_string "ssediv")
15700 (eq_attr "alternative" "2")
15701 (const_string "sseadd")
15702 (match_operand:DF 3 "mult_operator" "")
15703 (const_string "fmul")
15704 (match_operand:DF 3 "div_operator" "")
15705 (const_string "fdiv")
15707 (const_string "fop")))
15708 (set_attr "mode" "DF")])
15710 (define_insn "*fop_df_1_sse"
15711 [(set (match_operand:DF 0 "register_operand" "=x")
15712 (match_operator:DF 3 "binary_fp_operator"
15713 [(match_operand:DF 1 "register_operand" "0")
15714 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15715 "TARGET_SSE2 && TARGET_SSE_MATH
15716 && !COMMUTATIVE_ARITH_P (operands[3])"
15717 "* return output_387_binary_op (insn, operands);"
15718 [(set_attr "mode" "DF")
15720 (cond [(match_operand:DF 3 "mult_operator" "")
15721 (const_string "ssemul")
15722 (match_operand:DF 3 "div_operator" "")
15723 (const_string "ssediv")
15725 (const_string "sseadd")))])
15727 ;; This pattern is not fully shadowed by the pattern above.
15728 (define_insn "*fop_df_1_i387"
15729 [(set (match_operand:DF 0 "register_operand" "=f,f")
15730 (match_operator:DF 3 "binary_fp_operator"
15731 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15732 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15733 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15734 && !COMMUTATIVE_ARITH_P (operands[3])
15735 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15736 "* return output_387_binary_op (insn, operands);"
15737 [(set (attr "type")
15738 (cond [(match_operand:DF 3 "mult_operator" "")
15739 (const_string "fmul")
15740 (match_operand:DF 3 "div_operator" "")
15741 (const_string "fdiv")
15743 (const_string "fop")))
15744 (set_attr "mode" "DF")])
15746 ;; ??? Add SSE splitters for these!
15747 (define_insn "*fop_df_2<mode>_i387"
15748 [(set (match_operand:DF 0 "register_operand" "=f,f")
15749 (match_operator:DF 3 "binary_fp_operator"
15750 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15751 (match_operand:DF 2 "register_operand" "0,0")]))]
15752 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15753 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15754 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15755 [(set (attr "type")
15756 (cond [(match_operand:DF 3 "mult_operator" "")
15757 (const_string "fmul")
15758 (match_operand:DF 3 "div_operator" "")
15759 (const_string "fdiv")
15761 (const_string "fop")))
15762 (set_attr "fp_int_src" "true")
15763 (set_attr "mode" "<MODE>")])
15765 (define_insn "*fop_df_3<mode>_i387"
15766 [(set (match_operand:DF 0 "register_operand" "=f,f")
15767 (match_operator:DF 3 "binary_fp_operator"
15768 [(match_operand:DF 1 "register_operand" "0,0")
15769 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15770 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15771 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15772 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15773 [(set (attr "type")
15774 (cond [(match_operand:DF 3 "mult_operator" "")
15775 (const_string "fmul")
15776 (match_operand:DF 3 "div_operator" "")
15777 (const_string "fdiv")
15779 (const_string "fop")))
15780 (set_attr "fp_int_src" "true")
15781 (set_attr "mode" "<MODE>")])
15783 (define_insn "*fop_df_4_i387"
15784 [(set (match_operand:DF 0 "register_operand" "=f,f")
15785 (match_operator:DF 3 "binary_fp_operator"
15786 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15787 (match_operand:DF 2 "register_operand" "0,f")]))]
15788 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15789 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15790 "* return output_387_binary_op (insn, operands);"
15791 [(set (attr "type")
15792 (cond [(match_operand:DF 3 "mult_operator" "")
15793 (const_string "fmul")
15794 (match_operand:DF 3 "div_operator" "")
15795 (const_string "fdiv")
15797 (const_string "fop")))
15798 (set_attr "mode" "SF")])
15800 (define_insn "*fop_df_5_i387"
15801 [(set (match_operand:DF 0 "register_operand" "=f,f")
15802 (match_operator:DF 3 "binary_fp_operator"
15803 [(match_operand:DF 1 "register_operand" "0,f")
15805 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15806 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15807 "* return output_387_binary_op (insn, operands);"
15808 [(set (attr "type")
15809 (cond [(match_operand:DF 3 "mult_operator" "")
15810 (const_string "fmul")
15811 (match_operand:DF 3 "div_operator" "")
15812 (const_string "fdiv")
15814 (const_string "fop")))
15815 (set_attr "mode" "SF")])
15817 (define_insn "*fop_df_6_i387"
15818 [(set (match_operand:DF 0 "register_operand" "=f,f")
15819 (match_operator:DF 3 "binary_fp_operator"
15821 (match_operand:SF 1 "register_operand" "0,f"))
15823 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15824 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15825 "* return output_387_binary_op (insn, operands);"
15826 [(set (attr "type")
15827 (cond [(match_operand:DF 3 "mult_operator" "")
15828 (const_string "fmul")
15829 (match_operand:DF 3 "div_operator" "")
15830 (const_string "fdiv")
15832 (const_string "fop")))
15833 (set_attr "mode" "SF")])
15835 (define_insn "*fop_xf_comm_i387"
15836 [(set (match_operand:XF 0 "register_operand" "=f")
15837 (match_operator:XF 3 "binary_fp_operator"
15838 [(match_operand:XF 1 "register_operand" "%0")
15839 (match_operand:XF 2 "register_operand" "f")]))]
15841 && COMMUTATIVE_ARITH_P (operands[3])"
15842 "* return output_387_binary_op (insn, operands);"
15843 [(set (attr "type")
15844 (if_then_else (match_operand:XF 3 "mult_operator" "")
15845 (const_string "fmul")
15846 (const_string "fop")))
15847 (set_attr "mode" "XF")])
15849 (define_insn "*fop_xf_1_i387"
15850 [(set (match_operand:XF 0 "register_operand" "=f,f")
15851 (match_operator:XF 3 "binary_fp_operator"
15852 [(match_operand:XF 1 "register_operand" "0,f")
15853 (match_operand:XF 2 "register_operand" "f,0")]))]
15855 && !COMMUTATIVE_ARITH_P (operands[3])"
15856 "* return output_387_binary_op (insn, operands);"
15857 [(set (attr "type")
15858 (cond [(match_operand:XF 3 "mult_operator" "")
15859 (const_string "fmul")
15860 (match_operand:XF 3 "div_operator" "")
15861 (const_string "fdiv")
15863 (const_string "fop")))
15864 (set_attr "mode" "XF")])
15866 (define_insn "*fop_xf_2<mode>_i387"
15867 [(set (match_operand:XF 0 "register_operand" "=f,f")
15868 (match_operator:XF 3 "binary_fp_operator"
15869 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15870 (match_operand:XF 2 "register_operand" "0,0")]))]
15871 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15872 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15873 [(set (attr "type")
15874 (cond [(match_operand:XF 3 "mult_operator" "")
15875 (const_string "fmul")
15876 (match_operand:XF 3 "div_operator" "")
15877 (const_string "fdiv")
15879 (const_string "fop")))
15880 (set_attr "fp_int_src" "true")
15881 (set_attr "mode" "<MODE>")])
15883 (define_insn "*fop_xf_3<mode>_i387"
15884 [(set (match_operand:XF 0 "register_operand" "=f,f")
15885 (match_operator:XF 3 "binary_fp_operator"
15886 [(match_operand:XF 1 "register_operand" "0,0")
15887 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15888 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15889 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15890 [(set (attr "type")
15891 (cond [(match_operand:XF 3 "mult_operator" "")
15892 (const_string "fmul")
15893 (match_operand:XF 3 "div_operator" "")
15894 (const_string "fdiv")
15896 (const_string "fop")))
15897 (set_attr "fp_int_src" "true")
15898 (set_attr "mode" "<MODE>")])
15900 (define_insn "*fop_xf_4_i387"
15901 [(set (match_operand:XF 0 "register_operand" "=f,f")
15902 (match_operator:XF 3 "binary_fp_operator"
15904 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15905 (match_operand:XF 2 "register_operand" "0,f")]))]
15907 "* return output_387_binary_op (insn, operands);"
15908 [(set (attr "type")
15909 (cond [(match_operand:XF 3 "mult_operator" "")
15910 (const_string "fmul")
15911 (match_operand:XF 3 "div_operator" "")
15912 (const_string "fdiv")
15914 (const_string "fop")))
15915 (set_attr "mode" "SF")])
15917 (define_insn "*fop_xf_5_i387"
15918 [(set (match_operand:XF 0 "register_operand" "=f,f")
15919 (match_operator:XF 3 "binary_fp_operator"
15920 [(match_operand:XF 1 "register_operand" "0,f")
15922 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15924 "* return output_387_binary_op (insn, operands);"
15925 [(set (attr "type")
15926 (cond [(match_operand:XF 3 "mult_operator" "")
15927 (const_string "fmul")
15928 (match_operand:XF 3 "div_operator" "")
15929 (const_string "fdiv")
15931 (const_string "fop")))
15932 (set_attr "mode" "SF")])
15934 (define_insn "*fop_xf_6_i387"
15935 [(set (match_operand:XF 0 "register_operand" "=f,f")
15936 (match_operator:XF 3 "binary_fp_operator"
15938 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15940 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15942 "* return output_387_binary_op (insn, operands);"
15943 [(set (attr "type")
15944 (cond [(match_operand:XF 3 "mult_operator" "")
15945 (const_string "fmul")
15946 (match_operand:XF 3 "div_operator" "")
15947 (const_string "fdiv")
15949 (const_string "fop")))
15950 (set_attr "mode" "SF")])
15953 [(set (match_operand 0 "register_operand" "")
15954 (match_operator 3 "binary_fp_operator"
15955 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15956 (match_operand 2 "register_operand" "")]))]
15957 "TARGET_80387 && reload_completed
15958 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15961 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15962 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15963 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15964 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15965 GET_MODE (operands[3]),
15968 ix86_free_from_memory (GET_MODE (operands[1]));
15973 [(set (match_operand 0 "register_operand" "")
15974 (match_operator 3 "binary_fp_operator"
15975 [(match_operand 1 "register_operand" "")
15976 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15977 "TARGET_80387 && reload_completed
15978 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15981 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15982 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15983 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15984 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15985 GET_MODE (operands[3]),
15988 ix86_free_from_memory (GET_MODE (operands[2]));
15992 ;; FPU special functions.
15994 ;; This pattern implements a no-op XFmode truncation for
15995 ;; all fancy i386 XFmode math functions.
15997 (define_insn "truncxf<mode>2_i387_noop_unspec"
15998 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15999 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16000 UNSPEC_TRUNC_NOOP))]
16001 "TARGET_USE_FANCY_MATH_387"
16002 "* return output_387_reg_move (insn, operands);"
16003 [(set_attr "type" "fmov")
16004 (set_attr "mode" "<MODE>")])
16006 (define_insn "sqrtxf2"
16007 [(set (match_operand:XF 0 "register_operand" "=f")
16008 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16009 "TARGET_USE_FANCY_MATH_387"
16011 [(set_attr "type" "fpspc")
16012 (set_attr "mode" "XF")
16013 (set_attr "athlon_decode" "direct")
16014 (set_attr "amdfam10_decode" "direct")])
16016 (define_insn "sqrt_extend<mode>xf2_i387"
16017 [(set (match_operand:XF 0 "register_operand" "=f")
16020 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16021 "TARGET_USE_FANCY_MATH_387"
16023 [(set_attr "type" "fpspc")
16024 (set_attr "mode" "XF")
16025 (set_attr "athlon_decode" "direct")
16026 (set_attr "amdfam10_decode" "direct")])
16028 (define_insn "*sqrt<mode>2_sse"
16029 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16031 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16032 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16033 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16034 [(set_attr "type" "sse")
16035 (set_attr "mode" "<MODE>")
16036 (set_attr "athlon_decode" "*")
16037 (set_attr "amdfam10_decode" "*")])
16039 (define_expand "sqrt<mode>2"
16040 [(set (match_operand:X87MODEF12 0 "register_operand" "")
16042 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16043 "TARGET_USE_FANCY_MATH_387
16044 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16046 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16048 rtx op0 = gen_reg_rtx (XFmode);
16049 rtx op1 = force_reg (<MODE>mode, operands[1]);
16051 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16052 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16057 (define_insn "fpremxf4_i387"
16058 [(set (match_operand:XF 0 "register_operand" "=f")
16059 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16060 (match_operand:XF 3 "register_operand" "1")]
16062 (set (match_operand:XF 1 "register_operand" "=u")
16063 (unspec:XF [(match_dup 2) (match_dup 3)]
16065 (set (reg:CCFP FPSR_REG)
16066 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16067 "TARGET_USE_FANCY_MATH_387"
16069 [(set_attr "type" "fpspc")
16070 (set_attr "mode" "XF")])
16072 (define_expand "fmodxf3"
16073 [(use (match_operand:XF 0 "register_operand" ""))
16074 (use (match_operand:XF 1 "register_operand" ""))
16075 (use (match_operand:XF 2 "register_operand" ""))]
16076 "TARGET_USE_FANCY_MATH_387"
16078 rtx label = gen_label_rtx ();
16080 emit_label (label);
16082 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16083 operands[1], operands[2]));
16084 ix86_emit_fp_unordered_jump (label);
16086 emit_move_insn (operands[0], operands[1]);
16090 (define_expand "fmod<mode>3"
16091 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16092 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16093 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16094 "TARGET_USE_FANCY_MATH_387"
16096 rtx label = gen_label_rtx ();
16098 rtx op1 = gen_reg_rtx (XFmode);
16099 rtx op2 = gen_reg_rtx (XFmode);
16101 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16102 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16104 emit_label (label);
16105 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16106 ix86_emit_fp_unordered_jump (label);
16108 /* Truncate the result properly for strict SSE math. */
16109 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16110 && !TARGET_MIX_SSE_I387)
16111 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16113 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16118 (define_insn "fprem1xf4_i387"
16119 [(set (match_operand:XF 0 "register_operand" "=f")
16120 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16121 (match_operand:XF 3 "register_operand" "1")]
16123 (set (match_operand:XF 1 "register_operand" "=u")
16124 (unspec:XF [(match_dup 2) (match_dup 3)]
16126 (set (reg:CCFP FPSR_REG)
16127 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16128 "TARGET_USE_FANCY_MATH_387"
16130 [(set_attr "type" "fpspc")
16131 (set_attr "mode" "XF")])
16133 (define_expand "remainderxf3"
16134 [(use (match_operand:XF 0 "register_operand" ""))
16135 (use (match_operand:XF 1 "register_operand" ""))
16136 (use (match_operand:XF 2 "register_operand" ""))]
16137 "TARGET_USE_FANCY_MATH_387"
16139 rtx label = gen_label_rtx ();
16141 emit_label (label);
16143 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16144 operands[1], operands[2]));
16145 ix86_emit_fp_unordered_jump (label);
16147 emit_move_insn (operands[0], operands[1]);
16151 (define_expand "remainder<mode>3"
16152 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16153 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16154 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16155 "TARGET_USE_FANCY_MATH_387"
16157 rtx label = gen_label_rtx ();
16159 rtx op1 = gen_reg_rtx (XFmode);
16160 rtx op2 = gen_reg_rtx (XFmode);
16162 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16163 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16165 emit_label (label);
16167 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16168 ix86_emit_fp_unordered_jump (label);
16170 /* Truncate the result properly for strict SSE math. */
16171 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16172 && !TARGET_MIX_SSE_I387)
16173 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16175 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16180 (define_insn "*sinxf2_i387"
16181 [(set (match_operand:XF 0 "register_operand" "=f")
16182 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16183 "TARGET_USE_FANCY_MATH_387
16184 && flag_unsafe_math_optimizations"
16186 [(set_attr "type" "fpspc")
16187 (set_attr "mode" "XF")])
16189 (define_insn "*sin_extend<mode>xf2_i387"
16190 [(set (match_operand:XF 0 "register_operand" "=f")
16191 (unspec:XF [(float_extend:XF
16192 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16194 "TARGET_USE_FANCY_MATH_387
16195 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16196 || TARGET_MIX_SSE_I387)
16197 && flag_unsafe_math_optimizations"
16199 [(set_attr "type" "fpspc")
16200 (set_attr "mode" "XF")])
16202 (define_insn "*cosxf2_i387"
16203 [(set (match_operand:XF 0 "register_operand" "=f")
16204 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16205 "TARGET_USE_FANCY_MATH_387
16206 && flag_unsafe_math_optimizations"
16208 [(set_attr "type" "fpspc")
16209 (set_attr "mode" "XF")])
16211 (define_insn "*cos_extend<mode>xf2_i387"
16212 [(set (match_operand:XF 0 "register_operand" "=f")
16213 (unspec:XF [(float_extend:XF
16214 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16216 "TARGET_USE_FANCY_MATH_387
16217 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16218 || TARGET_MIX_SSE_I387)
16219 && flag_unsafe_math_optimizations"
16221 [(set_attr "type" "fpspc")
16222 (set_attr "mode" "XF")])
16224 ;; When sincos pattern is defined, sin and cos builtin functions will be
16225 ;; expanded to sincos pattern with one of its outputs left unused.
16226 ;; CSE pass will figure out if two sincos patterns can be combined,
16227 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16228 ;; depending on the unused output.
16230 (define_insn "sincosxf3"
16231 [(set (match_operand:XF 0 "register_operand" "=f")
16232 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16233 UNSPEC_SINCOS_COS))
16234 (set (match_operand:XF 1 "register_operand" "=u")
16235 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16236 "TARGET_USE_FANCY_MATH_387
16237 && flag_unsafe_math_optimizations"
16239 [(set_attr "type" "fpspc")
16240 (set_attr "mode" "XF")])
16243 [(set (match_operand:XF 0 "register_operand" "")
16244 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16245 UNSPEC_SINCOS_COS))
16246 (set (match_operand:XF 1 "register_operand" "")
16247 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16248 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16249 && !reload_completed && !reload_in_progress"
16250 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16254 [(set (match_operand:XF 0 "register_operand" "")
16255 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16256 UNSPEC_SINCOS_COS))
16257 (set (match_operand:XF 1 "register_operand" "")
16258 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16259 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16260 && !reload_completed && !reload_in_progress"
16261 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16264 (define_insn "sincos_extend<mode>xf3_i387"
16265 [(set (match_operand:XF 0 "register_operand" "=f")
16266 (unspec:XF [(float_extend:XF
16267 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16268 UNSPEC_SINCOS_COS))
16269 (set (match_operand:XF 1 "register_operand" "=u")
16270 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16271 "TARGET_USE_FANCY_MATH_387
16272 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16273 || TARGET_MIX_SSE_I387)
16274 && flag_unsafe_math_optimizations"
16276 [(set_attr "type" "fpspc")
16277 (set_attr "mode" "XF")])
16280 [(set (match_operand:XF 0 "register_operand" "")
16281 (unspec:XF [(float_extend:XF
16282 (match_operand:X87MODEF12 2 "register_operand" ""))]
16283 UNSPEC_SINCOS_COS))
16284 (set (match_operand:XF 1 "register_operand" "")
16285 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16286 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16287 && !reload_completed && !reload_in_progress"
16288 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16292 [(set (match_operand:XF 0 "register_operand" "")
16293 (unspec:XF [(float_extend:XF
16294 (match_operand:X87MODEF12 2 "register_operand" ""))]
16295 UNSPEC_SINCOS_COS))
16296 (set (match_operand:XF 1 "register_operand" "")
16297 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16298 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16299 && !reload_completed && !reload_in_progress"
16300 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16303 (define_expand "sincos<mode>3"
16304 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16305 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16306 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16307 "TARGET_USE_FANCY_MATH_387
16308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16309 || TARGET_MIX_SSE_I387)
16310 && flag_unsafe_math_optimizations"
16312 rtx op0 = gen_reg_rtx (XFmode);
16313 rtx op1 = gen_reg_rtx (XFmode);
16315 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16316 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16321 (define_insn "fptanxf4_i387"
16322 [(set (match_operand:XF 0 "register_operand" "=f")
16323 (match_operand:XF 3 "const_double_operand" "F"))
16324 (set (match_operand:XF 1 "register_operand" "=u")
16325 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16327 "TARGET_USE_FANCY_MATH_387
16328 && flag_unsafe_math_optimizations
16329 && standard_80387_constant_p (operands[3]) == 2"
16331 [(set_attr "type" "fpspc")
16332 (set_attr "mode" "XF")])
16334 (define_insn "fptan_extend<mode>xf4_i387"
16335 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16336 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16337 (set (match_operand:XF 1 "register_operand" "=u")
16338 (unspec:XF [(float_extend:XF
16339 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16341 "TARGET_USE_FANCY_MATH_387
16342 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16343 || TARGET_MIX_SSE_I387)
16344 && flag_unsafe_math_optimizations
16345 && standard_80387_constant_p (operands[3]) == 2"
16347 [(set_attr "type" "fpspc")
16348 (set_attr "mode" "XF")])
16350 (define_expand "tanxf2"
16351 [(use (match_operand:XF 0 "register_operand" ""))
16352 (use (match_operand:XF 1 "register_operand" ""))]
16353 "TARGET_USE_FANCY_MATH_387
16354 && flag_unsafe_math_optimizations"
16356 rtx one = gen_reg_rtx (XFmode);
16357 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16359 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16363 (define_expand "tan<mode>2"
16364 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16365 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16366 "TARGET_USE_FANCY_MATH_387
16367 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16368 || TARGET_MIX_SSE_I387)
16369 && flag_unsafe_math_optimizations"
16371 rtx op0 = gen_reg_rtx (XFmode);
16373 rtx one = gen_reg_rtx (<MODE>mode);
16374 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16376 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16377 operands[1], op2));
16378 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16382 (define_insn "*fpatanxf3_i387"
16383 [(set (match_operand:XF 0 "register_operand" "=f")
16384 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16385 (match_operand:XF 2 "register_operand" "u")]
16387 (clobber (match_scratch:XF 3 "=2"))]
16388 "TARGET_USE_FANCY_MATH_387
16389 && flag_unsafe_math_optimizations"
16391 [(set_attr "type" "fpspc")
16392 (set_attr "mode" "XF")])
16394 (define_insn "fpatan_extend<mode>xf3_i387"
16395 [(set (match_operand:XF 0 "register_operand" "=f")
16396 (unspec:XF [(float_extend:XF
16397 (match_operand:X87MODEF12 1 "register_operand" "0"))
16399 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16401 (clobber (match_scratch:XF 3 "=2"))]
16402 "TARGET_USE_FANCY_MATH_387
16403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16404 || TARGET_MIX_SSE_I387)
16405 && flag_unsafe_math_optimizations"
16407 [(set_attr "type" "fpspc")
16408 (set_attr "mode" "XF")])
16410 (define_expand "atan2xf3"
16411 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16412 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16413 (match_operand:XF 1 "register_operand" "")]
16415 (clobber (match_scratch:XF 3 ""))])]
16416 "TARGET_USE_FANCY_MATH_387
16417 && flag_unsafe_math_optimizations"
16420 (define_expand "atan2<mode>3"
16421 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16422 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16423 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16424 "TARGET_USE_FANCY_MATH_387
16425 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16426 || TARGET_MIX_SSE_I387)
16427 && flag_unsafe_math_optimizations"
16429 rtx op0 = gen_reg_rtx (XFmode);
16431 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16432 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16436 (define_expand "atanxf2"
16437 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16438 (unspec:XF [(match_dup 2)
16439 (match_operand:XF 1 "register_operand" "")]
16441 (clobber (match_scratch:XF 3 ""))])]
16442 "TARGET_USE_FANCY_MATH_387
16443 && flag_unsafe_math_optimizations"
16445 operands[2] = gen_reg_rtx (XFmode);
16446 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16449 (define_expand "atan<mode>2"
16450 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16451 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16452 "TARGET_USE_FANCY_MATH_387
16453 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16454 || TARGET_MIX_SSE_I387)
16455 && flag_unsafe_math_optimizations"
16457 rtx op0 = gen_reg_rtx (XFmode);
16459 rtx op2 = gen_reg_rtx (<MODE>mode);
16460 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16462 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16463 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16467 (define_expand "asinxf2"
16468 [(set (match_dup 2)
16469 (mult:XF (match_operand:XF 1 "register_operand" "")
16471 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16472 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16473 (parallel [(set (match_operand:XF 0 "register_operand" "")
16474 (unspec:XF [(match_dup 5) (match_dup 1)]
16476 (clobber (match_scratch:XF 6 ""))])]
16477 "TARGET_USE_FANCY_MATH_387
16478 && flag_unsafe_math_optimizations && !optimize_size"
16482 for (i = 2; i < 6; i++)
16483 operands[i] = gen_reg_rtx (XFmode);
16485 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16488 (define_expand "asin<mode>2"
16489 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16490 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16491 "TARGET_USE_FANCY_MATH_387
16492 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16493 || TARGET_MIX_SSE_I387)
16494 && flag_unsafe_math_optimizations && !optimize_size"
16496 rtx op0 = gen_reg_rtx (XFmode);
16497 rtx op1 = gen_reg_rtx (XFmode);
16499 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16500 emit_insn (gen_asinxf2 (op0, op1));
16501 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16505 (define_expand "acosxf2"
16506 [(set (match_dup 2)
16507 (mult:XF (match_operand:XF 1 "register_operand" "")
16509 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16510 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16511 (parallel [(set (match_operand:XF 0 "register_operand" "")
16512 (unspec:XF [(match_dup 1) (match_dup 5)]
16514 (clobber (match_scratch:XF 6 ""))])]
16515 "TARGET_USE_FANCY_MATH_387
16516 && flag_unsafe_math_optimizations && !optimize_size"
16520 for (i = 2; i < 6; i++)
16521 operands[i] = gen_reg_rtx (XFmode);
16523 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16526 (define_expand "acos<mode>2"
16527 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16528 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16529 "TARGET_USE_FANCY_MATH_387
16530 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16531 || TARGET_MIX_SSE_I387)
16532 && flag_unsafe_math_optimizations && !optimize_size"
16534 rtx op0 = gen_reg_rtx (XFmode);
16535 rtx op1 = gen_reg_rtx (XFmode);
16537 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16538 emit_insn (gen_acosxf2 (op0, op1));
16539 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16543 (define_insn "fyl2xxf3_i387"
16544 [(set (match_operand:XF 0 "register_operand" "=f")
16545 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16546 (match_operand:XF 2 "register_operand" "u")]
16548 (clobber (match_scratch:XF 3 "=2"))]
16549 "TARGET_USE_FANCY_MATH_387
16550 && flag_unsafe_math_optimizations"
16552 [(set_attr "type" "fpspc")
16553 (set_attr "mode" "XF")])
16555 (define_insn "fyl2x_extend<mode>xf3_i387"
16556 [(set (match_operand:XF 0 "register_operand" "=f")
16557 (unspec:XF [(float_extend:XF
16558 (match_operand:X87MODEF12 1 "register_operand" "0"))
16559 (match_operand:XF 2 "register_operand" "u")]
16561 (clobber (match_scratch:XF 3 "=2"))]
16562 "TARGET_USE_FANCY_MATH_387
16563 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16564 || TARGET_MIX_SSE_I387)
16565 && flag_unsafe_math_optimizations"
16567 [(set_attr "type" "fpspc")
16568 (set_attr "mode" "XF")])
16570 (define_expand "logxf2"
16571 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16572 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16573 (match_dup 2)] UNSPEC_FYL2X))
16574 (clobber (match_scratch:XF 3 ""))])]
16575 "TARGET_USE_FANCY_MATH_387
16576 && flag_unsafe_math_optimizations"
16578 operands[2] = gen_reg_rtx (XFmode);
16579 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16582 (define_expand "log<mode>2"
16583 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16584 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16585 "TARGET_USE_FANCY_MATH_387
16586 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16587 || TARGET_MIX_SSE_I387)
16588 && flag_unsafe_math_optimizations"
16590 rtx op0 = gen_reg_rtx (XFmode);
16592 rtx op2 = gen_reg_rtx (XFmode);
16593 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16595 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16596 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16600 (define_expand "log10xf2"
16601 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16602 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16603 (match_dup 2)] UNSPEC_FYL2X))
16604 (clobber (match_scratch:XF 3 ""))])]
16605 "TARGET_USE_FANCY_MATH_387
16606 && flag_unsafe_math_optimizations"
16608 operands[2] = gen_reg_rtx (XFmode);
16609 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16612 (define_expand "log10<mode>2"
16613 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16614 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16615 "TARGET_USE_FANCY_MATH_387
16616 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16617 || TARGET_MIX_SSE_I387)
16618 && flag_unsafe_math_optimizations"
16620 rtx op0 = gen_reg_rtx (XFmode);
16622 rtx op2 = gen_reg_rtx (XFmode);
16623 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16625 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16626 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16630 (define_expand "log2xf2"
16631 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16632 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16633 (match_dup 2)] UNSPEC_FYL2X))
16634 (clobber (match_scratch:XF 3 ""))])]
16635 "TARGET_USE_FANCY_MATH_387
16636 && flag_unsafe_math_optimizations"
16638 operands[2] = gen_reg_rtx (XFmode);
16639 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16642 (define_expand "log2<mode>2"
16643 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16644 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16645 "TARGET_USE_FANCY_MATH_387
16646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16647 || TARGET_MIX_SSE_I387)
16648 && flag_unsafe_math_optimizations"
16650 rtx op0 = gen_reg_rtx (XFmode);
16652 rtx op2 = gen_reg_rtx (XFmode);
16653 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16655 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16656 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16660 (define_insn "fyl2xp1xf3_i387"
16661 [(set (match_operand:XF 0 "register_operand" "=f")
16662 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16663 (match_operand:XF 2 "register_operand" "u")]
16665 (clobber (match_scratch:XF 3 "=2"))]
16666 "TARGET_USE_FANCY_MATH_387
16667 && flag_unsafe_math_optimizations"
16669 [(set_attr "type" "fpspc")
16670 (set_attr "mode" "XF")])
16672 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16673 [(set (match_operand:XF 0 "register_operand" "=f")
16674 (unspec:XF [(float_extend:XF
16675 (match_operand:X87MODEF12 1 "register_operand" "0"))
16676 (match_operand:XF 2 "register_operand" "u")]
16678 (clobber (match_scratch:XF 3 "=2"))]
16679 "TARGET_USE_FANCY_MATH_387
16680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16681 || TARGET_MIX_SSE_I387)
16682 && flag_unsafe_math_optimizations"
16684 [(set_attr "type" "fpspc")
16685 (set_attr "mode" "XF")])
16687 (define_expand "log1pxf2"
16688 [(use (match_operand:XF 0 "register_operand" ""))
16689 (use (match_operand:XF 1 "register_operand" ""))]
16690 "TARGET_USE_FANCY_MATH_387
16691 && flag_unsafe_math_optimizations && !optimize_size"
16693 ix86_emit_i387_log1p (operands[0], operands[1]);
16697 (define_expand "log1p<mode>2"
16698 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16699 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16700 "TARGET_USE_FANCY_MATH_387
16701 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16702 || TARGET_MIX_SSE_I387)
16703 && flag_unsafe_math_optimizations && !optimize_size"
16705 rtx op0 = gen_reg_rtx (XFmode);
16707 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16709 ix86_emit_i387_log1p (op0, operands[1]);
16710 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16714 (define_insn "fxtractxf3_i387"
16715 [(set (match_operand:XF 0 "register_operand" "=f")
16716 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16717 UNSPEC_XTRACT_FRACT))
16718 (set (match_operand:XF 1 "register_operand" "=u")
16719 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16720 "TARGET_USE_FANCY_MATH_387
16721 && flag_unsafe_math_optimizations"
16723 [(set_attr "type" "fpspc")
16724 (set_attr "mode" "XF")])
16726 (define_insn "fxtract_extend<mode>xf3_i387"
16727 [(set (match_operand:XF 0 "register_operand" "=f")
16728 (unspec:XF [(float_extend:XF
16729 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16730 UNSPEC_XTRACT_FRACT))
16731 (set (match_operand:XF 1 "register_operand" "=u")
16732 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16733 "TARGET_USE_FANCY_MATH_387
16734 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16735 || TARGET_MIX_SSE_I387)
16736 && flag_unsafe_math_optimizations"
16738 [(set_attr "type" "fpspc")
16739 (set_attr "mode" "XF")])
16741 (define_expand "logbxf2"
16742 [(parallel [(set (match_dup 2)
16743 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16744 UNSPEC_XTRACT_FRACT))
16745 (set (match_operand:XF 0 "register_operand" "")
16746 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16747 "TARGET_USE_FANCY_MATH_387
16748 && flag_unsafe_math_optimizations"
16750 operands[2] = gen_reg_rtx (XFmode);
16753 (define_expand "logb<mode>2"
16754 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16755 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16756 "TARGET_USE_FANCY_MATH_387
16757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16758 || TARGET_MIX_SSE_I387)
16759 && flag_unsafe_math_optimizations"
16761 rtx op0 = gen_reg_rtx (XFmode);
16762 rtx op1 = gen_reg_rtx (XFmode);
16764 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16765 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16769 (define_expand "ilogbxf2"
16770 [(use (match_operand:SI 0 "register_operand" ""))
16771 (use (match_operand:XF 1 "register_operand" ""))]
16772 "TARGET_USE_FANCY_MATH_387
16773 && flag_unsafe_math_optimizations && !optimize_size"
16775 rtx op0 = gen_reg_rtx (XFmode);
16776 rtx op1 = gen_reg_rtx (XFmode);
16778 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16779 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16783 (define_expand "ilogb<mode>2"
16784 [(use (match_operand:SI 0 "register_operand" ""))
16785 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16786 "TARGET_USE_FANCY_MATH_387
16787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16788 || TARGET_MIX_SSE_I387)
16789 && flag_unsafe_math_optimizations && !optimize_size"
16791 rtx op0 = gen_reg_rtx (XFmode);
16792 rtx op1 = gen_reg_rtx (XFmode);
16794 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16795 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16799 (define_insn "*f2xm1xf2_i387"
16800 [(set (match_operand:XF 0 "register_operand" "=f")
16801 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16803 "TARGET_USE_FANCY_MATH_387
16804 && flag_unsafe_math_optimizations"
16806 [(set_attr "type" "fpspc")
16807 (set_attr "mode" "XF")])
16809 (define_insn "*fscalexf4_i387"
16810 [(set (match_operand:XF 0 "register_operand" "=f")
16811 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16812 (match_operand:XF 3 "register_operand" "1")]
16813 UNSPEC_FSCALE_FRACT))
16814 (set (match_operand:XF 1 "register_operand" "=u")
16815 (unspec:XF [(match_dup 2) (match_dup 3)]
16816 UNSPEC_FSCALE_EXP))]
16817 "TARGET_USE_FANCY_MATH_387
16818 && flag_unsafe_math_optimizations"
16820 [(set_attr "type" "fpspc")
16821 (set_attr "mode" "XF")])
16823 (define_expand "expNcorexf3"
16824 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16825 (match_operand:XF 2 "register_operand" "")))
16826 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16827 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16828 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16829 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16830 (parallel [(set (match_operand:XF 0 "register_operand" "")
16831 (unspec:XF [(match_dup 8) (match_dup 4)]
16832 UNSPEC_FSCALE_FRACT))
16834 (unspec:XF [(match_dup 8) (match_dup 4)]
16835 UNSPEC_FSCALE_EXP))])]
16836 "TARGET_USE_FANCY_MATH_387
16837 && flag_unsafe_math_optimizations && !optimize_size"
16841 for (i = 3; i < 10; i++)
16842 operands[i] = gen_reg_rtx (XFmode);
16844 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16847 (define_expand "expxf2"
16848 [(use (match_operand:XF 0 "register_operand" ""))
16849 (use (match_operand:XF 1 "register_operand" ""))]
16850 "TARGET_USE_FANCY_MATH_387
16851 && flag_unsafe_math_optimizations && !optimize_size"
16853 rtx op2 = gen_reg_rtx (XFmode);
16854 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16856 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16860 (define_expand "exp<mode>2"
16861 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16862 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16863 "TARGET_USE_FANCY_MATH_387
16864 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16865 || TARGET_MIX_SSE_I387)
16866 && flag_unsafe_math_optimizations && !optimize_size"
16868 rtx op0 = gen_reg_rtx (XFmode);
16869 rtx op1 = gen_reg_rtx (XFmode);
16871 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16872 emit_insn (gen_expxf2 (op0, op1));
16873 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16877 (define_expand "exp10xf2"
16878 [(use (match_operand:XF 0 "register_operand" ""))
16879 (use (match_operand:XF 1 "register_operand" ""))]
16880 "TARGET_USE_FANCY_MATH_387
16881 && flag_unsafe_math_optimizations && !optimize_size"
16883 rtx op2 = gen_reg_rtx (XFmode);
16884 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16886 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16890 (define_expand "exp10<mode>2"
16891 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16892 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16893 "TARGET_USE_FANCY_MATH_387
16894 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16895 || TARGET_MIX_SSE_I387)
16896 && flag_unsafe_math_optimizations && !optimize_size"
16898 rtx op0 = gen_reg_rtx (XFmode);
16899 rtx op1 = gen_reg_rtx (XFmode);
16901 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16902 emit_insn (gen_exp10xf2 (op0, op1));
16903 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16907 (define_expand "exp2xf2"
16908 [(use (match_operand:XF 0 "register_operand" ""))
16909 (use (match_operand:XF 1 "register_operand" ""))]
16910 "TARGET_USE_FANCY_MATH_387
16911 && flag_unsafe_math_optimizations && !optimize_size"
16913 rtx op2 = gen_reg_rtx (XFmode);
16914 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16916 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16920 (define_expand "exp2<mode>2"
16921 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16922 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16923 "TARGET_USE_FANCY_MATH_387
16924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16925 || TARGET_MIX_SSE_I387)
16926 && flag_unsafe_math_optimizations && !optimize_size"
16928 rtx op0 = gen_reg_rtx (XFmode);
16929 rtx op1 = gen_reg_rtx (XFmode);
16931 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16932 emit_insn (gen_exp2xf2 (op0, op1));
16933 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16937 (define_expand "expm1xf2"
16938 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16940 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16941 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16942 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16943 (parallel [(set (match_dup 7)
16944 (unspec:XF [(match_dup 6) (match_dup 4)]
16945 UNSPEC_FSCALE_FRACT))
16947 (unspec:XF [(match_dup 6) (match_dup 4)]
16948 UNSPEC_FSCALE_EXP))])
16949 (parallel [(set (match_dup 10)
16950 (unspec:XF [(match_dup 9) (match_dup 8)]
16951 UNSPEC_FSCALE_FRACT))
16952 (set (match_dup 11)
16953 (unspec:XF [(match_dup 9) (match_dup 8)]
16954 UNSPEC_FSCALE_EXP))])
16955 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16956 (set (match_operand:XF 0 "register_operand" "")
16957 (plus:XF (match_dup 12) (match_dup 7)))]
16958 "TARGET_USE_FANCY_MATH_387
16959 && flag_unsafe_math_optimizations && !optimize_size"
16963 for (i = 2; i < 13; i++)
16964 operands[i] = gen_reg_rtx (XFmode);
16966 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16967 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16970 (define_expand "expm1<mode>2"
16971 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16972 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16973 "TARGET_USE_FANCY_MATH_387
16974 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16975 || TARGET_MIX_SSE_I387)
16976 && flag_unsafe_math_optimizations && !optimize_size"
16978 rtx op0 = gen_reg_rtx (XFmode);
16979 rtx op1 = gen_reg_rtx (XFmode);
16981 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16982 emit_insn (gen_expm1xf2 (op0, op1));
16983 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16987 (define_expand "ldexpxf3"
16988 [(set (match_dup 3)
16989 (float:XF (match_operand:SI 2 "register_operand" "")))
16990 (parallel [(set (match_operand:XF 0 " register_operand" "")
16991 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16993 UNSPEC_FSCALE_FRACT))
16995 (unspec:XF [(match_dup 1) (match_dup 3)]
16996 UNSPEC_FSCALE_EXP))])]
16997 "TARGET_USE_FANCY_MATH_387
16998 && flag_unsafe_math_optimizations && !optimize_size"
17000 operands[3] = gen_reg_rtx (XFmode);
17001 operands[4] = gen_reg_rtx (XFmode);
17004 (define_expand "ldexp<mode>3"
17005 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17006 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17007 (use (match_operand:SI 2 "register_operand" ""))]
17008 "TARGET_USE_FANCY_MATH_387
17009 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17010 || TARGET_MIX_SSE_I387)
17011 && flag_unsafe_math_optimizations && !optimize_size"
17013 rtx op0 = gen_reg_rtx (XFmode);
17014 rtx op1 = gen_reg_rtx (XFmode);
17016 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17017 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17018 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17023 (define_insn "frndintxf2"
17024 [(set (match_operand:XF 0 "register_operand" "=f")
17025 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17027 "TARGET_USE_FANCY_MATH_387
17028 && flag_unsafe_math_optimizations"
17030 [(set_attr "type" "fpspc")
17031 (set_attr "mode" "XF")])
17033 (define_expand "rintdf2"
17034 [(use (match_operand:DF 0 "register_operand" ""))
17035 (use (match_operand:DF 1 "register_operand" ""))]
17036 "(TARGET_USE_FANCY_MATH_387
17037 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17038 && flag_unsafe_math_optimizations)
17039 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17040 && !flag_trapping_math
17041 && !optimize_size)"
17043 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17044 && !flag_trapping_math
17046 ix86_expand_rint (operand0, operand1);
17049 rtx op0 = gen_reg_rtx (XFmode);
17050 rtx op1 = gen_reg_rtx (XFmode);
17052 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17053 emit_insn (gen_frndintxf2 (op0, op1));
17055 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17060 (define_expand "rintsf2"
17061 [(use (match_operand:SF 0 "register_operand" ""))
17062 (use (match_operand:SF 1 "register_operand" ""))]
17063 "(TARGET_USE_FANCY_MATH_387
17064 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17065 && flag_unsafe_math_optimizations)
17066 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17067 && !flag_trapping_math
17068 && !optimize_size)"
17070 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17071 && !flag_trapping_math
17073 ix86_expand_rint (operand0, operand1);
17076 rtx op0 = gen_reg_rtx (XFmode);
17077 rtx op1 = gen_reg_rtx (XFmode);
17079 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17080 emit_insn (gen_frndintxf2 (op0, op1));
17082 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17087 (define_expand "rintxf2"
17088 [(use (match_operand:XF 0 "register_operand" ""))
17089 (use (match_operand:XF 1 "register_operand" ""))]
17090 "TARGET_USE_FANCY_MATH_387
17091 && flag_unsafe_math_optimizations && !optimize_size"
17093 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17097 (define_expand "roundsf2"
17098 [(match_operand:SF 0 "register_operand" "")
17099 (match_operand:SF 1 "nonimmediate_operand" "")]
17100 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17101 && !flag_trapping_math && !flag_rounding_math
17104 ix86_expand_round (operand0, operand1);
17108 (define_expand "rounddf2"
17109 [(match_operand:DF 0 "register_operand" "")
17110 (match_operand:DF 1 "nonimmediate_operand" "")]
17111 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17112 && !flag_trapping_math && !flag_rounding_math
17116 ix86_expand_round (operand0, operand1);
17118 ix86_expand_rounddf_32 (operand0, operand1);
17122 (define_insn_and_split "*fistdi2_1"
17123 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17124 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17126 "TARGET_USE_FANCY_MATH_387
17127 && !(reload_completed || reload_in_progress)"
17132 if (memory_operand (operands[0], VOIDmode))
17133 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17136 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17137 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17142 [(set_attr "type" "fpspc")
17143 (set_attr "mode" "DI")])
17145 (define_insn "fistdi2"
17146 [(set (match_operand:DI 0 "memory_operand" "=m")
17147 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17149 (clobber (match_scratch:XF 2 "=&1f"))]
17150 "TARGET_USE_FANCY_MATH_387"
17151 "* return output_fix_trunc (insn, operands, 0);"
17152 [(set_attr "type" "fpspc")
17153 (set_attr "mode" "DI")])
17155 (define_insn "fistdi2_with_temp"
17156 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17157 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17159 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17160 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17161 "TARGET_USE_FANCY_MATH_387"
17163 [(set_attr "type" "fpspc")
17164 (set_attr "mode" "DI")])
17167 [(set (match_operand:DI 0 "register_operand" "")
17168 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17170 (clobber (match_operand:DI 2 "memory_operand" ""))
17171 (clobber (match_scratch 3 ""))]
17173 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17174 (clobber (match_dup 3))])
17175 (set (match_dup 0) (match_dup 2))]
17179 [(set (match_operand:DI 0 "memory_operand" "")
17180 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17182 (clobber (match_operand:DI 2 "memory_operand" ""))
17183 (clobber (match_scratch 3 ""))]
17185 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17186 (clobber (match_dup 3))])]
17189 (define_insn_and_split "*fist<mode>2_1"
17190 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17191 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17193 "TARGET_USE_FANCY_MATH_387
17194 && !(reload_completed || reload_in_progress)"
17199 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17200 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17204 [(set_attr "type" "fpspc")
17205 (set_attr "mode" "<MODE>")])
17207 (define_insn "fist<mode>2"
17208 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17209 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17211 "TARGET_USE_FANCY_MATH_387"
17212 "* return output_fix_trunc (insn, operands, 0);"
17213 [(set_attr "type" "fpspc")
17214 (set_attr "mode" "<MODE>")])
17216 (define_insn "fist<mode>2_with_temp"
17217 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17218 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17220 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17221 "TARGET_USE_FANCY_MATH_387"
17223 [(set_attr "type" "fpspc")
17224 (set_attr "mode" "<MODE>")])
17227 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17228 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17230 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17232 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17234 (set (match_dup 0) (match_dup 2))]
17238 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17239 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17241 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17243 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17247 (define_expand "lrintxf<mode>2"
17248 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17249 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17251 "TARGET_USE_FANCY_MATH_387"
17254 (define_expand "lrint<mode>di2"
17255 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17256 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17257 UNSPEC_FIX_NOTRUNC))]
17258 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17261 (define_expand "lrint<mode>si2"
17262 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17263 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17264 UNSPEC_FIX_NOTRUNC))]
17265 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17268 (define_expand "lround<mode>di2"
17269 [(match_operand:DI 0 "nonimmediate_operand" "")
17270 (match_operand:SSEMODEF 1 "register_operand" "")]
17271 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17272 && !flag_trapping_math && !flag_rounding_math
17275 ix86_expand_lround (operand0, operand1);
17279 (define_expand "lround<mode>si2"
17280 [(match_operand:SI 0 "nonimmediate_operand" "")
17281 (match_operand:SSEMODEF 1 "register_operand" "")]
17282 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17283 && !flag_trapping_math && !flag_rounding_math
17286 ix86_expand_lround (operand0, operand1);
17290 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17291 (define_insn_and_split "frndintxf2_floor"
17292 [(set (match_operand:XF 0 "register_operand" "=f")
17293 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17294 UNSPEC_FRNDINT_FLOOR))
17295 (clobber (reg:CC FLAGS_REG))]
17296 "TARGET_USE_FANCY_MATH_387
17297 && flag_unsafe_math_optimizations
17298 && !(reload_completed || reload_in_progress)"
17303 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17305 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17306 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17308 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17309 operands[2], operands[3]));
17312 [(set_attr "type" "frndint")
17313 (set_attr "i387_cw" "floor")
17314 (set_attr "mode" "XF")])
17316 (define_insn "frndintxf2_floor_i387"
17317 [(set (match_operand:XF 0 "register_operand" "=f")
17318 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17319 UNSPEC_FRNDINT_FLOOR))
17320 (use (match_operand:HI 2 "memory_operand" "m"))
17321 (use (match_operand:HI 3 "memory_operand" "m"))]
17322 "TARGET_USE_FANCY_MATH_387
17323 && flag_unsafe_math_optimizations"
17324 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17325 [(set_attr "type" "frndint")
17326 (set_attr "i387_cw" "floor")
17327 (set_attr "mode" "XF")])
17329 (define_expand "floorxf2"
17330 [(use (match_operand:XF 0 "register_operand" ""))
17331 (use (match_operand:XF 1 "register_operand" ""))]
17332 "TARGET_USE_FANCY_MATH_387
17333 && flag_unsafe_math_optimizations && !optimize_size"
17335 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17339 (define_expand "floordf2"
17340 [(use (match_operand:DF 0 "register_operand" ""))
17341 (use (match_operand:DF 1 "register_operand" ""))]
17342 "((TARGET_USE_FANCY_MATH_387
17343 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17344 && flag_unsafe_math_optimizations)
17345 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17346 && !flag_trapping_math))
17349 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17350 && !flag_trapping_math)
17353 ix86_expand_floorceil (operand0, operand1, true);
17355 ix86_expand_floorceildf_32 (operand0, operand1, true);
17359 rtx op0 = gen_reg_rtx (XFmode);
17360 rtx op1 = gen_reg_rtx (XFmode);
17362 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17363 emit_insn (gen_frndintxf2_floor (op0, op1));
17365 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17370 (define_expand "floorsf2"
17371 [(use (match_operand:SF 0 "register_operand" ""))
17372 (use (match_operand:SF 1 "register_operand" ""))]
17373 "((TARGET_USE_FANCY_MATH_387
17374 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17375 && flag_unsafe_math_optimizations)
17376 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17377 && !flag_trapping_math))
17380 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17381 && !flag_trapping_math)
17382 ix86_expand_floorceil (operand0, operand1, true);
17385 rtx op0 = gen_reg_rtx (XFmode);
17386 rtx op1 = gen_reg_rtx (XFmode);
17388 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17389 emit_insn (gen_frndintxf2_floor (op0, op1));
17391 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17396 (define_insn_and_split "*fist<mode>2_floor_1"
17397 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17398 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17399 UNSPEC_FIST_FLOOR))
17400 (clobber (reg:CC FLAGS_REG))]
17401 "TARGET_USE_FANCY_MATH_387
17402 && flag_unsafe_math_optimizations
17403 && !(reload_completed || reload_in_progress)"
17408 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17410 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17411 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17412 if (memory_operand (operands[0], VOIDmode))
17413 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17414 operands[2], operands[3]));
17417 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17418 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17419 operands[2], operands[3],
17424 [(set_attr "type" "fistp")
17425 (set_attr "i387_cw" "floor")
17426 (set_attr "mode" "<MODE>")])
17428 (define_insn "fistdi2_floor"
17429 [(set (match_operand:DI 0 "memory_operand" "=m")
17430 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17431 UNSPEC_FIST_FLOOR))
17432 (use (match_operand:HI 2 "memory_operand" "m"))
17433 (use (match_operand:HI 3 "memory_operand" "m"))
17434 (clobber (match_scratch:XF 4 "=&1f"))]
17435 "TARGET_USE_FANCY_MATH_387
17436 && flag_unsafe_math_optimizations"
17437 "* return output_fix_trunc (insn, operands, 0);"
17438 [(set_attr "type" "fistp")
17439 (set_attr "i387_cw" "floor")
17440 (set_attr "mode" "DI")])
17442 (define_insn "fistdi2_floor_with_temp"
17443 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17444 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17445 UNSPEC_FIST_FLOOR))
17446 (use (match_operand:HI 2 "memory_operand" "m,m"))
17447 (use (match_operand:HI 3 "memory_operand" "m,m"))
17448 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17449 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17450 "TARGET_USE_FANCY_MATH_387
17451 && flag_unsafe_math_optimizations"
17453 [(set_attr "type" "fistp")
17454 (set_attr "i387_cw" "floor")
17455 (set_attr "mode" "DI")])
17458 [(set (match_operand:DI 0 "register_operand" "")
17459 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17460 UNSPEC_FIST_FLOOR))
17461 (use (match_operand:HI 2 "memory_operand" ""))
17462 (use (match_operand:HI 3 "memory_operand" ""))
17463 (clobber (match_operand:DI 4 "memory_operand" ""))
17464 (clobber (match_scratch 5 ""))]
17466 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17467 (use (match_dup 2))
17468 (use (match_dup 3))
17469 (clobber (match_dup 5))])
17470 (set (match_dup 0) (match_dup 4))]
17474 [(set (match_operand:DI 0 "memory_operand" "")
17475 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17476 UNSPEC_FIST_FLOOR))
17477 (use (match_operand:HI 2 "memory_operand" ""))
17478 (use (match_operand:HI 3 "memory_operand" ""))
17479 (clobber (match_operand:DI 4 "memory_operand" ""))
17480 (clobber (match_scratch 5 ""))]
17482 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17483 (use (match_dup 2))
17484 (use (match_dup 3))
17485 (clobber (match_dup 5))])]
17488 (define_insn "fist<mode>2_floor"
17489 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17490 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17491 UNSPEC_FIST_FLOOR))
17492 (use (match_operand:HI 2 "memory_operand" "m"))
17493 (use (match_operand:HI 3 "memory_operand" "m"))]
17494 "TARGET_USE_FANCY_MATH_387
17495 && flag_unsafe_math_optimizations"
17496 "* return output_fix_trunc (insn, operands, 0);"
17497 [(set_attr "type" "fistp")
17498 (set_attr "i387_cw" "floor")
17499 (set_attr "mode" "<MODE>")])
17501 (define_insn "fist<mode>2_floor_with_temp"
17502 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17503 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17504 UNSPEC_FIST_FLOOR))
17505 (use (match_operand:HI 2 "memory_operand" "m,m"))
17506 (use (match_operand:HI 3 "memory_operand" "m,m"))
17507 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17508 "TARGET_USE_FANCY_MATH_387
17509 && flag_unsafe_math_optimizations"
17511 [(set_attr "type" "fistp")
17512 (set_attr "i387_cw" "floor")
17513 (set_attr "mode" "<MODE>")])
17516 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17517 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17518 UNSPEC_FIST_FLOOR))
17519 (use (match_operand:HI 2 "memory_operand" ""))
17520 (use (match_operand:HI 3 "memory_operand" ""))
17521 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17523 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17524 UNSPEC_FIST_FLOOR))
17525 (use (match_dup 2))
17526 (use (match_dup 3))])
17527 (set (match_dup 0) (match_dup 4))]
17531 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17532 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17533 UNSPEC_FIST_FLOOR))
17534 (use (match_operand:HI 2 "memory_operand" ""))
17535 (use (match_operand:HI 3 "memory_operand" ""))
17536 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17538 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17539 UNSPEC_FIST_FLOOR))
17540 (use (match_dup 2))
17541 (use (match_dup 3))])]
17544 (define_expand "lfloorxf<mode>2"
17545 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17546 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17547 UNSPEC_FIST_FLOOR))
17548 (clobber (reg:CC FLAGS_REG))])]
17549 "TARGET_USE_FANCY_MATH_387
17550 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17551 && flag_unsafe_math_optimizations"
17554 (define_expand "lfloor<mode>di2"
17555 [(match_operand:DI 0 "nonimmediate_operand" "")
17556 (match_operand:SSEMODEF 1 "register_operand" "")]
17557 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17558 && !flag_trapping_math
17561 ix86_expand_lfloorceil (operand0, operand1, true);
17565 (define_expand "lfloor<mode>si2"
17566 [(match_operand:SI 0 "nonimmediate_operand" "")
17567 (match_operand:SSEMODEF 1 "register_operand" "")]
17568 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17569 && !flag_trapping_math
17570 && (!optimize_size || !TARGET_64BIT)"
17572 ix86_expand_lfloorceil (operand0, operand1, true);
17576 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17577 (define_insn_and_split "frndintxf2_ceil"
17578 [(set (match_operand:XF 0 "register_operand" "=f")
17579 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17580 UNSPEC_FRNDINT_CEIL))
17581 (clobber (reg:CC FLAGS_REG))]
17582 "TARGET_USE_FANCY_MATH_387
17583 && flag_unsafe_math_optimizations
17584 && !(reload_completed || reload_in_progress)"
17589 ix86_optimize_mode_switching[I387_CEIL] = 1;
17591 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17592 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17594 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17595 operands[2], operands[3]));
17598 [(set_attr "type" "frndint")
17599 (set_attr "i387_cw" "ceil")
17600 (set_attr "mode" "XF")])
17602 (define_insn "frndintxf2_ceil_i387"
17603 [(set (match_operand:XF 0 "register_operand" "=f")
17604 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17605 UNSPEC_FRNDINT_CEIL))
17606 (use (match_operand:HI 2 "memory_operand" "m"))
17607 (use (match_operand:HI 3 "memory_operand" "m"))]
17608 "TARGET_USE_FANCY_MATH_387
17609 && flag_unsafe_math_optimizations"
17610 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17611 [(set_attr "type" "frndint")
17612 (set_attr "i387_cw" "ceil")
17613 (set_attr "mode" "XF")])
17615 (define_expand "ceilxf2"
17616 [(use (match_operand:XF 0 "register_operand" ""))
17617 (use (match_operand:XF 1 "register_operand" ""))]
17618 "TARGET_USE_FANCY_MATH_387
17619 && flag_unsafe_math_optimizations && !optimize_size"
17621 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17625 (define_expand "ceildf2"
17626 [(use (match_operand:DF 0 "register_operand" ""))
17627 (use (match_operand:DF 1 "register_operand" ""))]
17628 "((TARGET_USE_FANCY_MATH_387
17629 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17630 && flag_unsafe_math_optimizations)
17631 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17632 && !flag_trapping_math))
17635 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17636 && !flag_trapping_math)
17639 ix86_expand_floorceil (operand0, operand1, false);
17641 ix86_expand_floorceildf_32 (operand0, operand1, false);
17645 rtx op0 = gen_reg_rtx (XFmode);
17646 rtx op1 = gen_reg_rtx (XFmode);
17648 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17649 emit_insn (gen_frndintxf2_ceil (op0, op1));
17651 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17656 (define_expand "ceilsf2"
17657 [(use (match_operand:SF 0 "register_operand" ""))
17658 (use (match_operand:SF 1 "register_operand" ""))]
17659 "((TARGET_USE_FANCY_MATH_387
17660 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17661 && flag_unsafe_math_optimizations)
17662 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17663 && !flag_trapping_math))
17666 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17667 && !flag_trapping_math)
17668 ix86_expand_floorceil (operand0, operand1, false);
17671 rtx op0 = gen_reg_rtx (XFmode);
17672 rtx op1 = gen_reg_rtx (XFmode);
17674 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17675 emit_insn (gen_frndintxf2_ceil (op0, op1));
17677 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17682 (define_insn_and_split "*fist<mode>2_ceil_1"
17683 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17684 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17686 (clobber (reg:CC FLAGS_REG))]
17687 "TARGET_USE_FANCY_MATH_387
17688 && flag_unsafe_math_optimizations
17689 && !(reload_completed || reload_in_progress)"
17694 ix86_optimize_mode_switching[I387_CEIL] = 1;
17696 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17697 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17698 if (memory_operand (operands[0], VOIDmode))
17699 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17700 operands[2], operands[3]));
17703 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17704 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17705 operands[2], operands[3],
17710 [(set_attr "type" "fistp")
17711 (set_attr "i387_cw" "ceil")
17712 (set_attr "mode" "<MODE>")])
17714 (define_insn "fistdi2_ceil"
17715 [(set (match_operand:DI 0 "memory_operand" "=m")
17716 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17718 (use (match_operand:HI 2 "memory_operand" "m"))
17719 (use (match_operand:HI 3 "memory_operand" "m"))
17720 (clobber (match_scratch:XF 4 "=&1f"))]
17721 "TARGET_USE_FANCY_MATH_387
17722 && flag_unsafe_math_optimizations"
17723 "* return output_fix_trunc (insn, operands, 0);"
17724 [(set_attr "type" "fistp")
17725 (set_attr "i387_cw" "ceil")
17726 (set_attr "mode" "DI")])
17728 (define_insn "fistdi2_ceil_with_temp"
17729 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17730 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17732 (use (match_operand:HI 2 "memory_operand" "m,m"))
17733 (use (match_operand:HI 3 "memory_operand" "m,m"))
17734 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17735 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17736 "TARGET_USE_FANCY_MATH_387
17737 && flag_unsafe_math_optimizations"
17739 [(set_attr "type" "fistp")
17740 (set_attr "i387_cw" "ceil")
17741 (set_attr "mode" "DI")])
17744 [(set (match_operand:DI 0 "register_operand" "")
17745 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17747 (use (match_operand:HI 2 "memory_operand" ""))
17748 (use (match_operand:HI 3 "memory_operand" ""))
17749 (clobber (match_operand:DI 4 "memory_operand" ""))
17750 (clobber (match_scratch 5 ""))]
17752 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17753 (use (match_dup 2))
17754 (use (match_dup 3))
17755 (clobber (match_dup 5))])
17756 (set (match_dup 0) (match_dup 4))]
17760 [(set (match_operand:DI 0 "memory_operand" "")
17761 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17763 (use (match_operand:HI 2 "memory_operand" ""))
17764 (use (match_operand:HI 3 "memory_operand" ""))
17765 (clobber (match_operand:DI 4 "memory_operand" ""))
17766 (clobber (match_scratch 5 ""))]
17768 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17769 (use (match_dup 2))
17770 (use (match_dup 3))
17771 (clobber (match_dup 5))])]
17774 (define_insn "fist<mode>2_ceil"
17775 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17776 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17778 (use (match_operand:HI 2 "memory_operand" "m"))
17779 (use (match_operand:HI 3 "memory_operand" "m"))]
17780 "TARGET_USE_FANCY_MATH_387
17781 && flag_unsafe_math_optimizations"
17782 "* return output_fix_trunc (insn, operands, 0);"
17783 [(set_attr "type" "fistp")
17784 (set_attr "i387_cw" "ceil")
17785 (set_attr "mode" "<MODE>")])
17787 (define_insn "fist<mode>2_ceil_with_temp"
17788 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17789 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17791 (use (match_operand:HI 2 "memory_operand" "m,m"))
17792 (use (match_operand:HI 3 "memory_operand" "m,m"))
17793 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17794 "TARGET_USE_FANCY_MATH_387
17795 && flag_unsafe_math_optimizations"
17797 [(set_attr "type" "fistp")
17798 (set_attr "i387_cw" "ceil")
17799 (set_attr "mode" "<MODE>")])
17802 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17803 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17805 (use (match_operand:HI 2 "memory_operand" ""))
17806 (use (match_operand:HI 3 "memory_operand" ""))
17807 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17809 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17811 (use (match_dup 2))
17812 (use (match_dup 3))])
17813 (set (match_dup 0) (match_dup 4))]
17817 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17818 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17820 (use (match_operand:HI 2 "memory_operand" ""))
17821 (use (match_operand:HI 3 "memory_operand" ""))
17822 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17824 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17826 (use (match_dup 2))
17827 (use (match_dup 3))])]
17830 (define_expand "lceilxf<mode>2"
17831 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17832 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17834 (clobber (reg:CC FLAGS_REG))])]
17835 "TARGET_USE_FANCY_MATH_387
17836 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17837 && flag_unsafe_math_optimizations"
17840 (define_expand "lceil<mode>di2"
17841 [(match_operand:DI 0 "nonimmediate_operand" "")
17842 (match_operand:SSEMODEF 1 "register_operand" "")]
17843 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17844 && !flag_trapping_math"
17846 ix86_expand_lfloorceil (operand0, operand1, false);
17850 (define_expand "lceil<mode>si2"
17851 [(match_operand:SI 0 "nonimmediate_operand" "")
17852 (match_operand:SSEMODEF 1 "register_operand" "")]
17853 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17854 && !flag_trapping_math"
17856 ix86_expand_lfloorceil (operand0, operand1, false);
17860 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17861 (define_insn_and_split "frndintxf2_trunc"
17862 [(set (match_operand:XF 0 "register_operand" "=f")
17863 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17864 UNSPEC_FRNDINT_TRUNC))
17865 (clobber (reg:CC FLAGS_REG))]
17866 "TARGET_USE_FANCY_MATH_387
17867 && flag_unsafe_math_optimizations
17868 && !(reload_completed || reload_in_progress)"
17873 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17875 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17876 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17878 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17879 operands[2], operands[3]));
17882 [(set_attr "type" "frndint")
17883 (set_attr "i387_cw" "trunc")
17884 (set_attr "mode" "XF")])
17886 (define_insn "frndintxf2_trunc_i387"
17887 [(set (match_operand:XF 0 "register_operand" "=f")
17888 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17889 UNSPEC_FRNDINT_TRUNC))
17890 (use (match_operand:HI 2 "memory_operand" "m"))
17891 (use (match_operand:HI 3 "memory_operand" "m"))]
17892 "TARGET_USE_FANCY_MATH_387
17893 && flag_unsafe_math_optimizations"
17894 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17895 [(set_attr "type" "frndint")
17896 (set_attr "i387_cw" "trunc")
17897 (set_attr "mode" "XF")])
17899 (define_expand "btruncxf2"
17900 [(use (match_operand:XF 0 "register_operand" ""))
17901 (use (match_operand:XF 1 "register_operand" ""))]
17902 "TARGET_USE_FANCY_MATH_387
17903 && flag_unsafe_math_optimizations && !optimize_size"
17905 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17909 (define_expand "btruncdf2"
17910 [(use (match_operand:DF 0 "register_operand" ""))
17911 (use (match_operand:DF 1 "register_operand" ""))]
17912 "((TARGET_USE_FANCY_MATH_387
17913 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17914 && flag_unsafe_math_optimizations)
17915 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17916 && !flag_trapping_math))
17919 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17920 && !flag_trapping_math)
17923 ix86_expand_trunc (operand0, operand1);
17925 ix86_expand_truncdf_32 (operand0, operand1);
17929 rtx op0 = gen_reg_rtx (XFmode);
17930 rtx op1 = gen_reg_rtx (XFmode);
17932 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17933 emit_insn (gen_frndintxf2_trunc (op0, op1));
17935 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17940 (define_expand "btruncsf2"
17941 [(use (match_operand:SF 0 "register_operand" ""))
17942 (use (match_operand:SF 1 "register_operand" ""))]
17943 "((TARGET_USE_FANCY_MATH_387
17944 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17945 && flag_unsafe_math_optimizations)
17946 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17947 && !flag_trapping_math))
17950 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17951 && !flag_trapping_math)
17952 ix86_expand_trunc (operand0, operand1);
17955 rtx op0 = gen_reg_rtx (XFmode);
17956 rtx op1 = gen_reg_rtx (XFmode);
17958 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17959 emit_insn (gen_frndintxf2_trunc (op0, op1));
17961 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17966 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17967 (define_insn_and_split "frndintxf2_mask_pm"
17968 [(set (match_operand:XF 0 "register_operand" "=f")
17969 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17970 UNSPEC_FRNDINT_MASK_PM))
17971 (clobber (reg:CC FLAGS_REG))]
17972 "TARGET_USE_FANCY_MATH_387
17973 && flag_unsafe_math_optimizations
17974 && !(reload_completed || reload_in_progress)"
17979 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17981 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17982 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17984 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17985 operands[2], operands[3]));
17988 [(set_attr "type" "frndint")
17989 (set_attr "i387_cw" "mask_pm")
17990 (set_attr "mode" "XF")])
17992 (define_insn "frndintxf2_mask_pm_i387"
17993 [(set (match_operand:XF 0 "register_operand" "=f")
17994 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17995 UNSPEC_FRNDINT_MASK_PM))
17996 (use (match_operand:HI 2 "memory_operand" "m"))
17997 (use (match_operand:HI 3 "memory_operand" "m"))]
17998 "TARGET_USE_FANCY_MATH_387
17999 && flag_unsafe_math_optimizations"
18000 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18001 [(set_attr "type" "frndint")
18002 (set_attr "i387_cw" "mask_pm")
18003 (set_attr "mode" "XF")])
18005 (define_expand "nearbyintxf2"
18006 [(use (match_operand:XF 0 "register_operand" ""))
18007 (use (match_operand:XF 1 "register_operand" ""))]
18008 "TARGET_USE_FANCY_MATH_387
18009 && flag_unsafe_math_optimizations"
18011 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18016 (define_expand "nearbyintdf2"
18017 [(use (match_operand:DF 0 "register_operand" ""))
18018 (use (match_operand:DF 1 "register_operand" ""))]
18019 "TARGET_USE_FANCY_MATH_387
18020 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18021 && flag_unsafe_math_optimizations"
18023 rtx op0 = gen_reg_rtx (XFmode);
18024 rtx op1 = gen_reg_rtx (XFmode);
18026 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18027 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18029 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18033 (define_expand "nearbyintsf2"
18034 [(use (match_operand:SF 0 "register_operand" ""))
18035 (use (match_operand:SF 1 "register_operand" ""))]
18036 "TARGET_USE_FANCY_MATH_387
18037 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18038 && flag_unsafe_math_optimizations"
18040 rtx op0 = gen_reg_rtx (XFmode);
18041 rtx op1 = gen_reg_rtx (XFmode);
18043 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18044 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18046 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18050 (define_insn "fxam<mode>2_i387"
18051 [(set (match_operand:HI 0 "register_operand" "=a")
18053 [(match_operand:X87MODEF 1 "register_operand" "f")]
18055 "TARGET_USE_FANCY_MATH_387"
18056 "fxam\n\tfnstsw\t%0"
18057 [(set_attr "type" "multi")
18058 (set_attr "unit" "i387")
18059 (set_attr "mode" "<MODE>")])
18061 (define_expand "isinf<mode>2"
18062 [(use (match_operand:SI 0 "register_operand" ""))
18063 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18064 "TARGET_USE_FANCY_MATH_387
18065 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18066 || TARGET_MIX_SSE_I387)"
18068 rtx mask = GEN_INT (0x45);
18069 rtx val = GEN_INT (0x05);
18073 rtx scratch = gen_reg_rtx (HImode);
18074 rtx res = gen_reg_rtx (QImode);
18076 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18077 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18078 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18079 cond = gen_rtx_fmt_ee (EQ, QImode,
18080 gen_rtx_REG (CCmode, FLAGS_REG),
18082 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18083 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18088 ;; Block operation instructions
18090 (define_expand "movmemsi"
18091 [(use (match_operand:BLK 0 "memory_operand" ""))
18092 (use (match_operand:BLK 1 "memory_operand" ""))
18093 (use (match_operand:SI 2 "nonmemory_operand" ""))
18094 (use (match_operand:SI 3 "const_int_operand" ""))
18095 (use (match_operand:SI 4 "const_int_operand" ""))
18096 (use (match_operand:SI 5 "const_int_operand" ""))]
18099 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18100 operands[4], operands[5]))
18106 (define_expand "movmemdi"
18107 [(use (match_operand:BLK 0 "memory_operand" ""))
18108 (use (match_operand:BLK 1 "memory_operand" ""))
18109 (use (match_operand:DI 2 "nonmemory_operand" ""))
18110 (use (match_operand:DI 3 "const_int_operand" ""))
18111 (use (match_operand:SI 4 "const_int_operand" ""))
18112 (use (match_operand:SI 5 "const_int_operand" ""))]
18115 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18116 operands[4], operands[5]))
18122 ;; Most CPUs don't like single string operations
18123 ;; Handle this case here to simplify previous expander.
18125 (define_expand "strmov"
18126 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18127 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18128 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18129 (clobber (reg:CC FLAGS_REG))])
18130 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18131 (clobber (reg:CC FLAGS_REG))])]
18134 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18136 /* If .md ever supports :P for Pmode, these can be directly
18137 in the pattern above. */
18138 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18139 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18141 if (TARGET_SINGLE_STRINGOP || optimize_size)
18143 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18144 operands[2], operands[3],
18145 operands[5], operands[6]));
18149 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18152 (define_expand "strmov_singleop"
18153 [(parallel [(set (match_operand 1 "memory_operand" "")
18154 (match_operand 3 "memory_operand" ""))
18155 (set (match_operand 0 "register_operand" "")
18156 (match_operand 4 "" ""))
18157 (set (match_operand 2 "register_operand" "")
18158 (match_operand 5 "" ""))])]
18159 "TARGET_SINGLE_STRINGOP || optimize_size"
18162 (define_insn "*strmovdi_rex_1"
18163 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18164 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18165 (set (match_operand:DI 0 "register_operand" "=D")
18166 (plus:DI (match_dup 2)
18168 (set (match_operand:DI 1 "register_operand" "=S")
18169 (plus:DI (match_dup 3)
18171 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18173 [(set_attr "type" "str")
18174 (set_attr "mode" "DI")
18175 (set_attr "memory" "both")])
18177 (define_insn "*strmovsi_1"
18178 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18179 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18180 (set (match_operand:SI 0 "register_operand" "=D")
18181 (plus:SI (match_dup 2)
18183 (set (match_operand:SI 1 "register_operand" "=S")
18184 (plus:SI (match_dup 3)
18186 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18188 [(set_attr "type" "str")
18189 (set_attr "mode" "SI")
18190 (set_attr "memory" "both")])
18192 (define_insn "*strmovsi_rex_1"
18193 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18194 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18195 (set (match_operand:DI 0 "register_operand" "=D")
18196 (plus:DI (match_dup 2)
18198 (set (match_operand:DI 1 "register_operand" "=S")
18199 (plus:DI (match_dup 3)
18201 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18203 [(set_attr "type" "str")
18204 (set_attr "mode" "SI")
18205 (set_attr "memory" "both")])
18207 (define_insn "*strmovhi_1"
18208 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18209 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18210 (set (match_operand:SI 0 "register_operand" "=D")
18211 (plus:SI (match_dup 2)
18213 (set (match_operand:SI 1 "register_operand" "=S")
18214 (plus:SI (match_dup 3)
18216 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18218 [(set_attr "type" "str")
18219 (set_attr "memory" "both")
18220 (set_attr "mode" "HI")])
18222 (define_insn "*strmovhi_rex_1"
18223 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18224 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18225 (set (match_operand:DI 0 "register_operand" "=D")
18226 (plus:DI (match_dup 2)
18228 (set (match_operand:DI 1 "register_operand" "=S")
18229 (plus:DI (match_dup 3)
18231 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18233 [(set_attr "type" "str")
18234 (set_attr "memory" "both")
18235 (set_attr "mode" "HI")])
18237 (define_insn "*strmovqi_1"
18238 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18239 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18240 (set (match_operand:SI 0 "register_operand" "=D")
18241 (plus:SI (match_dup 2)
18243 (set (match_operand:SI 1 "register_operand" "=S")
18244 (plus:SI (match_dup 3)
18246 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18248 [(set_attr "type" "str")
18249 (set_attr "memory" "both")
18250 (set_attr "mode" "QI")])
18252 (define_insn "*strmovqi_rex_1"
18253 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18254 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18255 (set (match_operand:DI 0 "register_operand" "=D")
18256 (plus:DI (match_dup 2)
18258 (set (match_operand:DI 1 "register_operand" "=S")
18259 (plus:DI (match_dup 3)
18261 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18263 [(set_attr "type" "str")
18264 (set_attr "memory" "both")
18265 (set_attr "mode" "QI")])
18267 (define_expand "rep_mov"
18268 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18269 (set (match_operand 0 "register_operand" "")
18270 (match_operand 5 "" ""))
18271 (set (match_operand 2 "register_operand" "")
18272 (match_operand 6 "" ""))
18273 (set (match_operand 1 "memory_operand" "")
18274 (match_operand 3 "memory_operand" ""))
18275 (use (match_dup 4))])]
18279 (define_insn "*rep_movdi_rex64"
18280 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18281 (set (match_operand:DI 0 "register_operand" "=D")
18282 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18284 (match_operand:DI 3 "register_operand" "0")))
18285 (set (match_operand:DI 1 "register_operand" "=S")
18286 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18287 (match_operand:DI 4 "register_operand" "1")))
18288 (set (mem:BLK (match_dup 3))
18289 (mem:BLK (match_dup 4)))
18290 (use (match_dup 5))]
18292 "{rep\;movsq|rep movsq}"
18293 [(set_attr "type" "str")
18294 (set_attr "prefix_rep" "1")
18295 (set_attr "memory" "both")
18296 (set_attr "mode" "DI")])
18298 (define_insn "*rep_movsi"
18299 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18300 (set (match_operand:SI 0 "register_operand" "=D")
18301 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18303 (match_operand:SI 3 "register_operand" "0")))
18304 (set (match_operand:SI 1 "register_operand" "=S")
18305 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18306 (match_operand:SI 4 "register_operand" "1")))
18307 (set (mem:BLK (match_dup 3))
18308 (mem:BLK (match_dup 4)))
18309 (use (match_dup 5))]
18311 "{rep\;movsl|rep movsd}"
18312 [(set_attr "type" "str")
18313 (set_attr "prefix_rep" "1")
18314 (set_attr "memory" "both")
18315 (set_attr "mode" "SI")])
18317 (define_insn "*rep_movsi_rex64"
18318 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18319 (set (match_operand:DI 0 "register_operand" "=D")
18320 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18322 (match_operand:DI 3 "register_operand" "0")))
18323 (set (match_operand:DI 1 "register_operand" "=S")
18324 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18325 (match_operand:DI 4 "register_operand" "1")))
18326 (set (mem:BLK (match_dup 3))
18327 (mem:BLK (match_dup 4)))
18328 (use (match_dup 5))]
18330 "{rep\;movsl|rep movsd}"
18331 [(set_attr "type" "str")
18332 (set_attr "prefix_rep" "1")
18333 (set_attr "memory" "both")
18334 (set_attr "mode" "SI")])
18336 (define_insn "*rep_movqi"
18337 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18338 (set (match_operand:SI 0 "register_operand" "=D")
18339 (plus:SI (match_operand:SI 3 "register_operand" "0")
18340 (match_operand:SI 5 "register_operand" "2")))
18341 (set (match_operand:SI 1 "register_operand" "=S")
18342 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18343 (set (mem:BLK (match_dup 3))
18344 (mem:BLK (match_dup 4)))
18345 (use (match_dup 5))]
18347 "{rep\;movsb|rep movsb}"
18348 [(set_attr "type" "str")
18349 (set_attr "prefix_rep" "1")
18350 (set_attr "memory" "both")
18351 (set_attr "mode" "SI")])
18353 (define_insn "*rep_movqi_rex64"
18354 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18355 (set (match_operand:DI 0 "register_operand" "=D")
18356 (plus:DI (match_operand:DI 3 "register_operand" "0")
18357 (match_operand:DI 5 "register_operand" "2")))
18358 (set (match_operand:DI 1 "register_operand" "=S")
18359 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18360 (set (mem:BLK (match_dup 3))
18361 (mem:BLK (match_dup 4)))
18362 (use (match_dup 5))]
18364 "{rep\;movsb|rep movsb}"
18365 [(set_attr "type" "str")
18366 (set_attr "prefix_rep" "1")
18367 (set_attr "memory" "both")
18368 (set_attr "mode" "SI")])
18370 (define_expand "setmemsi"
18371 [(use (match_operand:BLK 0 "memory_operand" ""))
18372 (use (match_operand:SI 1 "nonmemory_operand" ""))
18373 (use (match_operand 2 "const_int_operand" ""))
18374 (use (match_operand 3 "const_int_operand" ""))
18375 (use (match_operand:SI 4 "const_int_operand" ""))
18376 (use (match_operand:SI 5 "const_int_operand" ""))]
18379 if (ix86_expand_setmem (operands[0], operands[1],
18380 operands[2], operands[3],
18381 operands[4], operands[5]))
18387 (define_expand "setmemdi"
18388 [(use (match_operand:BLK 0 "memory_operand" ""))
18389 (use (match_operand:DI 1 "nonmemory_operand" ""))
18390 (use (match_operand 2 "const_int_operand" ""))
18391 (use (match_operand 3 "const_int_operand" ""))
18392 (use (match_operand 4 "const_int_operand" ""))
18393 (use (match_operand 5 "const_int_operand" ""))]
18396 if (ix86_expand_setmem (operands[0], operands[1],
18397 operands[2], operands[3],
18398 operands[4], operands[5]))
18404 ;; Most CPUs don't like single string operations
18405 ;; Handle this case here to simplify previous expander.
18407 (define_expand "strset"
18408 [(set (match_operand 1 "memory_operand" "")
18409 (match_operand 2 "register_operand" ""))
18410 (parallel [(set (match_operand 0 "register_operand" "")
18412 (clobber (reg:CC FLAGS_REG))])]
18415 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18416 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18418 /* If .md ever supports :P for Pmode, this can be directly
18419 in the pattern above. */
18420 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18421 GEN_INT (GET_MODE_SIZE (GET_MODE
18423 if (TARGET_SINGLE_STRINGOP || optimize_size)
18425 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18431 (define_expand "strset_singleop"
18432 [(parallel [(set (match_operand 1 "memory_operand" "")
18433 (match_operand 2 "register_operand" ""))
18434 (set (match_operand 0 "register_operand" "")
18435 (match_operand 3 "" ""))])]
18436 "TARGET_SINGLE_STRINGOP || optimize_size"
18439 (define_insn "*strsetdi_rex_1"
18440 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18441 (match_operand:DI 2 "register_operand" "a"))
18442 (set (match_operand:DI 0 "register_operand" "=D")
18443 (plus:DI (match_dup 1)
18445 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18447 [(set_attr "type" "str")
18448 (set_attr "memory" "store")
18449 (set_attr "mode" "DI")])
18451 (define_insn "*strsetsi_1"
18452 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18453 (match_operand:SI 2 "register_operand" "a"))
18454 (set (match_operand:SI 0 "register_operand" "=D")
18455 (plus:SI (match_dup 1)
18457 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18459 [(set_attr "type" "str")
18460 (set_attr "memory" "store")
18461 (set_attr "mode" "SI")])
18463 (define_insn "*strsetsi_rex_1"
18464 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18465 (match_operand:SI 2 "register_operand" "a"))
18466 (set (match_operand:DI 0 "register_operand" "=D")
18467 (plus:DI (match_dup 1)
18469 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18471 [(set_attr "type" "str")
18472 (set_attr "memory" "store")
18473 (set_attr "mode" "SI")])
18475 (define_insn "*strsethi_1"
18476 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18477 (match_operand:HI 2 "register_operand" "a"))
18478 (set (match_operand:SI 0 "register_operand" "=D")
18479 (plus:SI (match_dup 1)
18481 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18483 [(set_attr "type" "str")
18484 (set_attr "memory" "store")
18485 (set_attr "mode" "HI")])
18487 (define_insn "*strsethi_rex_1"
18488 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18489 (match_operand:HI 2 "register_operand" "a"))
18490 (set (match_operand:DI 0 "register_operand" "=D")
18491 (plus:DI (match_dup 1)
18493 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18495 [(set_attr "type" "str")
18496 (set_attr "memory" "store")
18497 (set_attr "mode" "HI")])
18499 (define_insn "*strsetqi_1"
18500 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18501 (match_operand:QI 2 "register_operand" "a"))
18502 (set (match_operand:SI 0 "register_operand" "=D")
18503 (plus:SI (match_dup 1)
18505 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18507 [(set_attr "type" "str")
18508 (set_attr "memory" "store")
18509 (set_attr "mode" "QI")])
18511 (define_insn "*strsetqi_rex_1"
18512 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18513 (match_operand:QI 2 "register_operand" "a"))
18514 (set (match_operand:DI 0 "register_operand" "=D")
18515 (plus:DI (match_dup 1)
18517 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18519 [(set_attr "type" "str")
18520 (set_attr "memory" "store")
18521 (set_attr "mode" "QI")])
18523 (define_expand "rep_stos"
18524 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18525 (set (match_operand 0 "register_operand" "")
18526 (match_operand 4 "" ""))
18527 (set (match_operand 2 "memory_operand" "") (const_int 0))
18528 (use (match_operand 3 "register_operand" ""))
18529 (use (match_dup 1))])]
18533 (define_insn "*rep_stosdi_rex64"
18534 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18535 (set (match_operand:DI 0 "register_operand" "=D")
18536 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18538 (match_operand:DI 3 "register_operand" "0")))
18539 (set (mem:BLK (match_dup 3))
18541 (use (match_operand:DI 2 "register_operand" "a"))
18542 (use (match_dup 4))]
18544 "{rep\;stosq|rep stosq}"
18545 [(set_attr "type" "str")
18546 (set_attr "prefix_rep" "1")
18547 (set_attr "memory" "store")
18548 (set_attr "mode" "DI")])
18550 (define_insn "*rep_stossi"
18551 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18552 (set (match_operand:SI 0 "register_operand" "=D")
18553 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18555 (match_operand:SI 3 "register_operand" "0")))
18556 (set (mem:BLK (match_dup 3))
18558 (use (match_operand:SI 2 "register_operand" "a"))
18559 (use (match_dup 4))]
18561 "{rep\;stosl|rep stosd}"
18562 [(set_attr "type" "str")
18563 (set_attr "prefix_rep" "1")
18564 (set_attr "memory" "store")
18565 (set_attr "mode" "SI")])
18567 (define_insn "*rep_stossi_rex64"
18568 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18569 (set (match_operand:DI 0 "register_operand" "=D")
18570 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18572 (match_operand:DI 3 "register_operand" "0")))
18573 (set (mem:BLK (match_dup 3))
18575 (use (match_operand:SI 2 "register_operand" "a"))
18576 (use (match_dup 4))]
18578 "{rep\;stosl|rep stosd}"
18579 [(set_attr "type" "str")
18580 (set_attr "prefix_rep" "1")
18581 (set_attr "memory" "store")
18582 (set_attr "mode" "SI")])
18584 (define_insn "*rep_stosqi"
18585 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18586 (set (match_operand:SI 0 "register_operand" "=D")
18587 (plus:SI (match_operand:SI 3 "register_operand" "0")
18588 (match_operand:SI 4 "register_operand" "1")))
18589 (set (mem:BLK (match_dup 3))
18591 (use (match_operand:QI 2 "register_operand" "a"))
18592 (use (match_dup 4))]
18594 "{rep\;stosb|rep stosb}"
18595 [(set_attr "type" "str")
18596 (set_attr "prefix_rep" "1")
18597 (set_attr "memory" "store")
18598 (set_attr "mode" "QI")])
18600 (define_insn "*rep_stosqi_rex64"
18601 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18602 (set (match_operand:DI 0 "register_operand" "=D")
18603 (plus:DI (match_operand:DI 3 "register_operand" "0")
18604 (match_operand:DI 4 "register_operand" "1")))
18605 (set (mem:BLK (match_dup 3))
18607 (use (match_operand:QI 2 "register_operand" "a"))
18608 (use (match_dup 4))]
18610 "{rep\;stosb|rep stosb}"
18611 [(set_attr "type" "str")
18612 (set_attr "prefix_rep" "1")
18613 (set_attr "memory" "store")
18614 (set_attr "mode" "QI")])
18616 (define_expand "cmpstrnsi"
18617 [(set (match_operand:SI 0 "register_operand" "")
18618 (compare:SI (match_operand:BLK 1 "general_operand" "")
18619 (match_operand:BLK 2 "general_operand" "")))
18620 (use (match_operand 3 "general_operand" ""))
18621 (use (match_operand 4 "immediate_operand" ""))]
18622 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18624 rtx addr1, addr2, out, outlow, count, countreg, align;
18626 /* Can't use this if the user has appropriated esi or edi. */
18627 if (global_regs[4] || global_regs[5])
18632 out = gen_reg_rtx (SImode);
18634 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18635 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18636 if (addr1 != XEXP (operands[1], 0))
18637 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18638 if (addr2 != XEXP (operands[2], 0))
18639 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18641 count = operands[3];
18642 countreg = ix86_zero_extend_to_Pmode (count);
18644 /* %%% Iff we are testing strict equality, we can use known alignment
18645 to good advantage. This may be possible with combine, particularly
18646 once cc0 is dead. */
18647 align = operands[4];
18649 if (CONST_INT_P (count))
18651 if (INTVAL (count) == 0)
18653 emit_move_insn (operands[0], const0_rtx);
18656 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18657 operands[1], operands[2]));
18662 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18664 emit_insn (gen_cmpsi_1 (countreg, countreg));
18665 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18666 operands[1], operands[2]));
18669 outlow = gen_lowpart (QImode, out);
18670 emit_insn (gen_cmpintqi (outlow));
18671 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18673 if (operands[0] != out)
18674 emit_move_insn (operands[0], out);
18679 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18681 (define_expand "cmpintqi"
18682 [(set (match_dup 1)
18683 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18685 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18686 (parallel [(set (match_operand:QI 0 "register_operand" "")
18687 (minus:QI (match_dup 1)
18689 (clobber (reg:CC FLAGS_REG))])]
18691 "operands[1] = gen_reg_rtx (QImode);
18692 operands[2] = gen_reg_rtx (QImode);")
18694 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18695 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18697 (define_expand "cmpstrnqi_nz_1"
18698 [(parallel [(set (reg:CC FLAGS_REG)
18699 (compare:CC (match_operand 4 "memory_operand" "")
18700 (match_operand 5 "memory_operand" "")))
18701 (use (match_operand 2 "register_operand" ""))
18702 (use (match_operand:SI 3 "immediate_operand" ""))
18703 (clobber (match_operand 0 "register_operand" ""))
18704 (clobber (match_operand 1 "register_operand" ""))
18705 (clobber (match_dup 2))])]
18709 (define_insn "*cmpstrnqi_nz_1"
18710 [(set (reg:CC FLAGS_REG)
18711 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18712 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18713 (use (match_operand:SI 6 "register_operand" "2"))
18714 (use (match_operand:SI 3 "immediate_operand" "i"))
18715 (clobber (match_operand:SI 0 "register_operand" "=S"))
18716 (clobber (match_operand:SI 1 "register_operand" "=D"))
18717 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18720 [(set_attr "type" "str")
18721 (set_attr "mode" "QI")
18722 (set_attr "prefix_rep" "1")])
18724 (define_insn "*cmpstrnqi_nz_rex_1"
18725 [(set (reg:CC FLAGS_REG)
18726 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18727 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18728 (use (match_operand:DI 6 "register_operand" "2"))
18729 (use (match_operand:SI 3 "immediate_operand" "i"))
18730 (clobber (match_operand:DI 0 "register_operand" "=S"))
18731 (clobber (match_operand:DI 1 "register_operand" "=D"))
18732 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18735 [(set_attr "type" "str")
18736 (set_attr "mode" "QI")
18737 (set_attr "prefix_rep" "1")])
18739 ;; The same, but the count is not known to not be zero.
18741 (define_expand "cmpstrnqi_1"
18742 [(parallel [(set (reg:CC FLAGS_REG)
18743 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18745 (compare:CC (match_operand 4 "memory_operand" "")
18746 (match_operand 5 "memory_operand" ""))
18748 (use (match_operand:SI 3 "immediate_operand" ""))
18749 (use (reg:CC FLAGS_REG))
18750 (clobber (match_operand 0 "register_operand" ""))
18751 (clobber (match_operand 1 "register_operand" ""))
18752 (clobber (match_dup 2))])]
18756 (define_insn "*cmpstrnqi_1"
18757 [(set (reg:CC FLAGS_REG)
18758 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18760 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18761 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18763 (use (match_operand:SI 3 "immediate_operand" "i"))
18764 (use (reg:CC FLAGS_REG))
18765 (clobber (match_operand:SI 0 "register_operand" "=S"))
18766 (clobber (match_operand:SI 1 "register_operand" "=D"))
18767 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18770 [(set_attr "type" "str")
18771 (set_attr "mode" "QI")
18772 (set_attr "prefix_rep" "1")])
18774 (define_insn "*cmpstrnqi_rex_1"
18775 [(set (reg:CC FLAGS_REG)
18776 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18778 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18779 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18781 (use (match_operand:SI 3 "immediate_operand" "i"))
18782 (use (reg:CC FLAGS_REG))
18783 (clobber (match_operand:DI 0 "register_operand" "=S"))
18784 (clobber (match_operand:DI 1 "register_operand" "=D"))
18785 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18788 [(set_attr "type" "str")
18789 (set_attr "mode" "QI")
18790 (set_attr "prefix_rep" "1")])
18792 (define_expand "strlensi"
18793 [(set (match_operand:SI 0 "register_operand" "")
18794 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18795 (match_operand:QI 2 "immediate_operand" "")
18796 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18799 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18805 (define_expand "strlendi"
18806 [(set (match_operand:DI 0 "register_operand" "")
18807 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18808 (match_operand:QI 2 "immediate_operand" "")
18809 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18812 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18818 (define_expand "strlenqi_1"
18819 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18820 (clobber (match_operand 1 "register_operand" ""))
18821 (clobber (reg:CC FLAGS_REG))])]
18825 (define_insn "*strlenqi_1"
18826 [(set (match_operand:SI 0 "register_operand" "=&c")
18827 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18828 (match_operand:QI 2 "register_operand" "a")
18829 (match_operand:SI 3 "immediate_operand" "i")
18830 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18831 (clobber (match_operand:SI 1 "register_operand" "=D"))
18832 (clobber (reg:CC FLAGS_REG))]
18835 [(set_attr "type" "str")
18836 (set_attr "mode" "QI")
18837 (set_attr "prefix_rep" "1")])
18839 (define_insn "*strlenqi_rex_1"
18840 [(set (match_operand:DI 0 "register_operand" "=&c")
18841 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18842 (match_operand:QI 2 "register_operand" "a")
18843 (match_operand:DI 3 "immediate_operand" "i")
18844 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18845 (clobber (match_operand:DI 1 "register_operand" "=D"))
18846 (clobber (reg:CC FLAGS_REG))]
18849 [(set_attr "type" "str")
18850 (set_attr "mode" "QI")
18851 (set_attr "prefix_rep" "1")])
18853 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18854 ;; handled in combine, but it is not currently up to the task.
18855 ;; When used for their truth value, the cmpstrn* expanders generate
18864 ;; The intermediate three instructions are unnecessary.
18866 ;; This one handles cmpstrn*_nz_1...
18869 (set (reg:CC FLAGS_REG)
18870 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18871 (mem:BLK (match_operand 5 "register_operand" ""))))
18872 (use (match_operand 6 "register_operand" ""))
18873 (use (match_operand:SI 3 "immediate_operand" ""))
18874 (clobber (match_operand 0 "register_operand" ""))
18875 (clobber (match_operand 1 "register_operand" ""))
18876 (clobber (match_operand 2 "register_operand" ""))])
18877 (set (match_operand:QI 7 "register_operand" "")
18878 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18879 (set (match_operand:QI 8 "register_operand" "")
18880 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18881 (set (reg FLAGS_REG)
18882 (compare (match_dup 7) (match_dup 8)))
18884 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18886 (set (reg:CC FLAGS_REG)
18887 (compare:CC (mem:BLK (match_dup 4))
18888 (mem:BLK (match_dup 5))))
18889 (use (match_dup 6))
18890 (use (match_dup 3))
18891 (clobber (match_dup 0))
18892 (clobber (match_dup 1))
18893 (clobber (match_dup 2))])]
18896 ;; ...and this one handles cmpstrn*_1.
18899 (set (reg:CC FLAGS_REG)
18900 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18902 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18903 (mem:BLK (match_operand 5 "register_operand" "")))
18905 (use (match_operand:SI 3 "immediate_operand" ""))
18906 (use (reg:CC FLAGS_REG))
18907 (clobber (match_operand 0 "register_operand" ""))
18908 (clobber (match_operand 1 "register_operand" ""))
18909 (clobber (match_operand 2 "register_operand" ""))])
18910 (set (match_operand:QI 7 "register_operand" "")
18911 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18912 (set (match_operand:QI 8 "register_operand" "")
18913 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18914 (set (reg FLAGS_REG)
18915 (compare (match_dup 7) (match_dup 8)))
18917 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18919 (set (reg:CC FLAGS_REG)
18920 (if_then_else:CC (ne (match_dup 6)
18922 (compare:CC (mem:BLK (match_dup 4))
18923 (mem:BLK (match_dup 5)))
18925 (use (match_dup 3))
18926 (use (reg:CC FLAGS_REG))
18927 (clobber (match_dup 0))
18928 (clobber (match_dup 1))
18929 (clobber (match_dup 2))])]
18934 ;; Conditional move instructions.
18936 (define_expand "movdicc"
18937 [(set (match_operand:DI 0 "register_operand" "")
18938 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18939 (match_operand:DI 2 "general_operand" "")
18940 (match_operand:DI 3 "general_operand" "")))]
18942 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18944 (define_insn "x86_movdicc_0_m1_rex64"
18945 [(set (match_operand:DI 0 "register_operand" "=r")
18946 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18949 (clobber (reg:CC FLAGS_REG))]
18952 ; Since we don't have the proper number of operands for an alu insn,
18953 ; fill in all the blanks.
18954 [(set_attr "type" "alu")
18955 (set_attr "pent_pair" "pu")
18956 (set_attr "memory" "none")
18957 (set_attr "imm_disp" "false")
18958 (set_attr "mode" "DI")
18959 (set_attr "length_immediate" "0")])
18961 (define_insn "*movdicc_c_rex64"
18962 [(set (match_operand:DI 0 "register_operand" "=r,r")
18963 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18964 [(reg FLAGS_REG) (const_int 0)])
18965 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18966 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18967 "TARGET_64BIT && TARGET_CMOVE
18968 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18970 cmov%O2%C1\t{%2, %0|%0, %2}
18971 cmov%O2%c1\t{%3, %0|%0, %3}"
18972 [(set_attr "type" "icmov")
18973 (set_attr "mode" "DI")])
18975 (define_expand "movsicc"
18976 [(set (match_operand:SI 0 "register_operand" "")
18977 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18978 (match_operand:SI 2 "general_operand" "")
18979 (match_operand:SI 3 "general_operand" "")))]
18981 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18983 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18984 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18985 ;; So just document what we're doing explicitly.
18987 (define_insn "x86_movsicc_0_m1"
18988 [(set (match_operand:SI 0 "register_operand" "=r")
18989 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18992 (clobber (reg:CC FLAGS_REG))]
18995 ; Since we don't have the proper number of operands for an alu insn,
18996 ; fill in all the blanks.
18997 [(set_attr "type" "alu")
18998 (set_attr "pent_pair" "pu")
18999 (set_attr "memory" "none")
19000 (set_attr "imm_disp" "false")
19001 (set_attr "mode" "SI")
19002 (set_attr "length_immediate" "0")])
19004 (define_insn "*movsicc_noc"
19005 [(set (match_operand:SI 0 "register_operand" "=r,r")
19006 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19007 [(reg FLAGS_REG) (const_int 0)])
19008 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19009 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19011 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19013 cmov%O2%C1\t{%2, %0|%0, %2}
19014 cmov%O2%c1\t{%3, %0|%0, %3}"
19015 [(set_attr "type" "icmov")
19016 (set_attr "mode" "SI")])
19018 (define_expand "movhicc"
19019 [(set (match_operand:HI 0 "register_operand" "")
19020 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19021 (match_operand:HI 2 "general_operand" "")
19022 (match_operand:HI 3 "general_operand" "")))]
19023 "TARGET_HIMODE_MATH"
19024 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19026 (define_insn "*movhicc_noc"
19027 [(set (match_operand:HI 0 "register_operand" "=r,r")
19028 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19029 [(reg FLAGS_REG) (const_int 0)])
19030 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19031 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19033 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19035 cmov%O2%C1\t{%2, %0|%0, %2}
19036 cmov%O2%c1\t{%3, %0|%0, %3}"
19037 [(set_attr "type" "icmov")
19038 (set_attr "mode" "HI")])
19040 (define_expand "movqicc"
19041 [(set (match_operand:QI 0 "register_operand" "")
19042 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19043 (match_operand:QI 2 "general_operand" "")
19044 (match_operand:QI 3 "general_operand" "")))]
19045 "TARGET_QIMODE_MATH"
19046 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19048 (define_insn_and_split "*movqicc_noc"
19049 [(set (match_operand:QI 0 "register_operand" "=r,r")
19050 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19051 [(match_operand 4 "flags_reg_operand" "")
19053 (match_operand:QI 2 "register_operand" "r,0")
19054 (match_operand:QI 3 "register_operand" "0,r")))]
19055 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19057 "&& reload_completed"
19058 [(set (match_dup 0)
19059 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19062 "operands[0] = gen_lowpart (SImode, operands[0]);
19063 operands[2] = gen_lowpart (SImode, operands[2]);
19064 operands[3] = gen_lowpart (SImode, operands[3]);"
19065 [(set_attr "type" "icmov")
19066 (set_attr "mode" "SI")])
19068 (define_expand "movsfcc"
19069 [(set (match_operand:SF 0 "register_operand" "")
19070 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19071 (match_operand:SF 2 "register_operand" "")
19072 (match_operand:SF 3 "register_operand" "")))]
19073 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19074 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19076 (define_insn "*movsfcc_1_387"
19077 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19078 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19079 [(reg FLAGS_REG) (const_int 0)])
19080 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19081 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19082 "TARGET_80387 && TARGET_CMOVE
19083 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19085 fcmov%F1\t{%2, %0|%0, %2}
19086 fcmov%f1\t{%3, %0|%0, %3}
19087 cmov%O2%C1\t{%2, %0|%0, %2}
19088 cmov%O2%c1\t{%3, %0|%0, %3}"
19089 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19090 (set_attr "mode" "SF,SF,SI,SI")])
19092 (define_expand "movdfcc"
19093 [(set (match_operand:DF 0 "register_operand" "")
19094 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19095 (match_operand:DF 2 "register_operand" "")
19096 (match_operand:DF 3 "register_operand" "")))]
19097 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19098 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19100 (define_insn "*movdfcc_1"
19101 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19102 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19103 [(reg FLAGS_REG) (const_int 0)])
19104 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19105 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19106 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19107 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19109 fcmov%F1\t{%2, %0|%0, %2}
19110 fcmov%f1\t{%3, %0|%0, %3}
19113 [(set_attr "type" "fcmov,fcmov,multi,multi")
19114 (set_attr "mode" "DF")])
19116 (define_insn "*movdfcc_1_rex64"
19117 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19118 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19119 [(reg FLAGS_REG) (const_int 0)])
19120 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19121 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19122 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19123 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19125 fcmov%F1\t{%2, %0|%0, %2}
19126 fcmov%f1\t{%3, %0|%0, %3}
19127 cmov%O2%C1\t{%2, %0|%0, %2}
19128 cmov%O2%c1\t{%3, %0|%0, %3}"
19129 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19130 (set_attr "mode" "DF")])
19133 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19134 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19135 [(match_operand 4 "flags_reg_operand" "")
19137 (match_operand:DF 2 "nonimmediate_operand" "")
19138 (match_operand:DF 3 "nonimmediate_operand" "")))]
19139 "!TARGET_64BIT && reload_completed"
19140 [(set (match_dup 2)
19141 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19145 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19148 "split_di (operands+2, 1, operands+5, operands+6);
19149 split_di (operands+3, 1, operands+7, operands+8);
19150 split_di (operands, 1, operands+2, operands+3);")
19152 (define_expand "movxfcc"
19153 [(set (match_operand:XF 0 "register_operand" "")
19154 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19155 (match_operand:XF 2 "register_operand" "")
19156 (match_operand:XF 3 "register_operand" "")))]
19157 "TARGET_80387 && TARGET_CMOVE"
19158 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19160 (define_insn "*movxfcc_1"
19161 [(set (match_operand:XF 0 "register_operand" "=f,f")
19162 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19163 [(reg FLAGS_REG) (const_int 0)])
19164 (match_operand:XF 2 "register_operand" "f,0")
19165 (match_operand:XF 3 "register_operand" "0,f")))]
19166 "TARGET_80387 && TARGET_CMOVE"
19168 fcmov%F1\t{%2, %0|%0, %2}
19169 fcmov%f1\t{%3, %0|%0, %3}"
19170 [(set_attr "type" "fcmov")
19171 (set_attr "mode" "XF")])
19173 ;; These versions of the min/max patterns are intentionally ignorant of
19174 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19175 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19176 ;; are undefined in this condition, we're certain this is correct.
19178 (define_insn "sminsf3"
19179 [(set (match_operand:SF 0 "register_operand" "=x")
19180 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19181 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19183 "minss\t{%2, %0|%0, %2}"
19184 [(set_attr "type" "sseadd")
19185 (set_attr "mode" "SF")])
19187 (define_insn "smaxsf3"
19188 [(set (match_operand:SF 0 "register_operand" "=x")
19189 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19190 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19192 "maxss\t{%2, %0|%0, %2}"
19193 [(set_attr "type" "sseadd")
19194 (set_attr "mode" "SF")])
19196 (define_insn "smindf3"
19197 [(set (match_operand:DF 0 "register_operand" "=x")
19198 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19199 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19200 "TARGET_SSE2 && TARGET_SSE_MATH"
19201 "minsd\t{%2, %0|%0, %2}"
19202 [(set_attr "type" "sseadd")
19203 (set_attr "mode" "DF")])
19205 (define_insn "smaxdf3"
19206 [(set (match_operand:DF 0 "register_operand" "=x")
19207 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19208 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19209 "TARGET_SSE2 && TARGET_SSE_MATH"
19210 "maxsd\t{%2, %0|%0, %2}"
19211 [(set_attr "type" "sseadd")
19212 (set_attr "mode" "DF")])
19214 ;; These versions of the min/max patterns implement exactly the operations
19215 ;; min = (op1 < op2 ? op1 : op2)
19216 ;; max = (!(op1 < op2) ? op1 : op2)
19217 ;; Their operands are not commutative, and thus they may be used in the
19218 ;; presence of -0.0 and NaN.
19220 (define_insn "*ieee_sminsf3"
19221 [(set (match_operand:SF 0 "register_operand" "=x")
19222 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19223 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19226 "minss\t{%2, %0|%0, %2}"
19227 [(set_attr "type" "sseadd")
19228 (set_attr "mode" "SF")])
19230 (define_insn "*ieee_smaxsf3"
19231 [(set (match_operand:SF 0 "register_operand" "=x")
19232 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19233 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19236 "maxss\t{%2, %0|%0, %2}"
19237 [(set_attr "type" "sseadd")
19238 (set_attr "mode" "SF")])
19240 (define_insn "*ieee_smindf3"
19241 [(set (match_operand:DF 0 "register_operand" "=x")
19242 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19243 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19245 "TARGET_SSE2 && TARGET_SSE_MATH"
19246 "minsd\t{%2, %0|%0, %2}"
19247 [(set_attr "type" "sseadd")
19248 (set_attr "mode" "DF")])
19250 (define_insn "*ieee_smaxdf3"
19251 [(set (match_operand:DF 0 "register_operand" "=x")
19252 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19253 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19255 "TARGET_SSE2 && TARGET_SSE_MATH"
19256 "maxsd\t{%2, %0|%0, %2}"
19257 [(set_attr "type" "sseadd")
19258 (set_attr "mode" "DF")])
19260 ;; Make two stack loads independent:
19262 ;; fld %st(0) -> fld bb
19263 ;; fmul bb fmul %st(1), %st
19265 ;; Actually we only match the last two instructions for simplicity.
19267 [(set (match_operand 0 "fp_register_operand" "")
19268 (match_operand 1 "fp_register_operand" ""))
19270 (match_operator 2 "binary_fp_operator"
19272 (match_operand 3 "memory_operand" "")]))]
19273 "REGNO (operands[0]) != REGNO (operands[1])"
19274 [(set (match_dup 0) (match_dup 3))
19275 (set (match_dup 0) (match_dup 4))]
19277 ;; The % modifier is not operational anymore in peephole2's, so we have to
19278 ;; swap the operands manually in the case of addition and multiplication.
19279 "if (COMMUTATIVE_ARITH_P (operands[2]))
19280 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19281 operands[0], operands[1]);
19283 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19284 operands[1], operands[0]);")
19286 ;; Conditional addition patterns
19287 (define_expand "addqicc"
19288 [(match_operand:QI 0 "register_operand" "")
19289 (match_operand 1 "comparison_operator" "")
19290 (match_operand:QI 2 "register_operand" "")
19291 (match_operand:QI 3 "const_int_operand" "")]
19293 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19295 (define_expand "addhicc"
19296 [(match_operand:HI 0 "register_operand" "")
19297 (match_operand 1 "comparison_operator" "")
19298 (match_operand:HI 2 "register_operand" "")
19299 (match_operand:HI 3 "const_int_operand" "")]
19301 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19303 (define_expand "addsicc"
19304 [(match_operand:SI 0 "register_operand" "")
19305 (match_operand 1 "comparison_operator" "")
19306 (match_operand:SI 2 "register_operand" "")
19307 (match_operand:SI 3 "const_int_operand" "")]
19309 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19311 (define_expand "adddicc"
19312 [(match_operand:DI 0 "register_operand" "")
19313 (match_operand 1 "comparison_operator" "")
19314 (match_operand:DI 2 "register_operand" "")
19315 (match_operand:DI 3 "const_int_operand" "")]
19317 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19320 ;; Misc patterns (?)
19322 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19323 ;; Otherwise there will be nothing to keep
19325 ;; [(set (reg ebp) (reg esp))]
19326 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19327 ;; (clobber (eflags)]
19328 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19330 ;; in proper program order.
19331 (define_insn "pro_epilogue_adjust_stack_1"
19332 [(set (match_operand:SI 0 "register_operand" "=r,r")
19333 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19334 (match_operand:SI 2 "immediate_operand" "i,i")))
19335 (clobber (reg:CC FLAGS_REG))
19336 (clobber (mem:BLK (scratch)))]
19339 switch (get_attr_type (insn))
19342 return "mov{l}\t{%1, %0|%0, %1}";
19345 if (CONST_INT_P (operands[2])
19346 && (INTVAL (operands[2]) == 128
19347 || (INTVAL (operands[2]) < 0
19348 && INTVAL (operands[2]) != -128)))
19350 operands[2] = GEN_INT (-INTVAL (operands[2]));
19351 return "sub{l}\t{%2, %0|%0, %2}";
19353 return "add{l}\t{%2, %0|%0, %2}";
19356 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19357 return "lea{l}\t{%a2, %0|%0, %a2}";
19360 gcc_unreachable ();
19363 [(set (attr "type")
19364 (cond [(eq_attr "alternative" "0")
19365 (const_string "alu")
19366 (match_operand:SI 2 "const0_operand" "")
19367 (const_string "imov")
19369 (const_string "lea")))
19370 (set_attr "mode" "SI")])
19372 (define_insn "pro_epilogue_adjust_stack_rex64"
19373 [(set (match_operand:DI 0 "register_operand" "=r,r")
19374 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19375 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19376 (clobber (reg:CC FLAGS_REG))
19377 (clobber (mem:BLK (scratch)))]
19380 switch (get_attr_type (insn))
19383 return "mov{q}\t{%1, %0|%0, %1}";
19386 if (CONST_INT_P (operands[2])
19387 /* Avoid overflows. */
19388 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19389 && (INTVAL (operands[2]) == 128
19390 || (INTVAL (operands[2]) < 0
19391 && INTVAL (operands[2]) != -128)))
19393 operands[2] = GEN_INT (-INTVAL (operands[2]));
19394 return "sub{q}\t{%2, %0|%0, %2}";
19396 return "add{q}\t{%2, %0|%0, %2}";
19399 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19400 return "lea{q}\t{%a2, %0|%0, %a2}";
19403 gcc_unreachable ();
19406 [(set (attr "type")
19407 (cond [(eq_attr "alternative" "0")
19408 (const_string "alu")
19409 (match_operand:DI 2 "const0_operand" "")
19410 (const_string "imov")
19412 (const_string "lea")))
19413 (set_attr "mode" "DI")])
19415 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19416 [(set (match_operand:DI 0 "register_operand" "=r,r")
19417 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19418 (match_operand:DI 3 "immediate_operand" "i,i")))
19419 (use (match_operand:DI 2 "register_operand" "r,r"))
19420 (clobber (reg:CC FLAGS_REG))
19421 (clobber (mem:BLK (scratch)))]
19424 switch (get_attr_type (insn))
19427 return "add{q}\t{%2, %0|%0, %2}";
19430 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19431 return "lea{q}\t{%a2, %0|%0, %a2}";
19434 gcc_unreachable ();
19437 [(set_attr "type" "alu,lea")
19438 (set_attr "mode" "DI")])
19440 (define_expand "allocate_stack_worker"
19441 [(match_operand:SI 0 "register_operand" "")]
19442 "TARGET_STACK_PROBE"
19444 if (reload_completed)
19447 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19449 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19454 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19456 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19461 (define_insn "allocate_stack_worker_1"
19462 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19463 UNSPECV_STACK_PROBE)
19464 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19465 (clobber (match_scratch:SI 1 "=0"))
19466 (clobber (reg:CC FLAGS_REG))]
19467 "!TARGET_64BIT && TARGET_STACK_PROBE"
19469 [(set_attr "type" "multi")
19470 (set_attr "length" "5")])
19472 (define_expand "allocate_stack_worker_postreload"
19473 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19474 UNSPECV_STACK_PROBE)
19475 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19476 (clobber (match_dup 0))
19477 (clobber (reg:CC FLAGS_REG))])]
19481 (define_insn "allocate_stack_worker_rex64"
19482 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19483 UNSPECV_STACK_PROBE)
19484 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19485 (clobber (match_scratch:DI 1 "=0"))
19486 (clobber (reg:CC FLAGS_REG))]
19487 "TARGET_64BIT && TARGET_STACK_PROBE"
19489 [(set_attr "type" "multi")
19490 (set_attr "length" "5")])
19492 (define_expand "allocate_stack_worker_rex64_postreload"
19493 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19494 UNSPECV_STACK_PROBE)
19495 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19496 (clobber (match_dup 0))
19497 (clobber (reg:CC FLAGS_REG))])]
19501 (define_expand "allocate_stack"
19502 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19503 (minus:SI (reg:SI SP_REG)
19504 (match_operand:SI 1 "general_operand" "")))
19505 (clobber (reg:CC FLAGS_REG))])
19506 (parallel [(set (reg:SI SP_REG)
19507 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19508 (clobber (reg:CC FLAGS_REG))])]
19509 "TARGET_STACK_PROBE"
19511 #ifdef CHECK_STACK_LIMIT
19512 if (CONST_INT_P (operands[1])
19513 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19514 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19518 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19521 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19525 (define_expand "builtin_setjmp_receiver"
19526 [(label_ref (match_operand 0 "" ""))]
19527 "!TARGET_64BIT && flag_pic"
19532 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19533 rtx label_rtx = gen_label_rtx ();
19534 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19535 xops[0] = xops[1] = picreg;
19536 xops[2] = gen_rtx_CONST (SImode,
19537 gen_rtx_MINUS (SImode,
19538 gen_rtx_LABEL_REF (SImode, label_rtx),
19539 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19540 ix86_expand_binary_operator (MINUS, SImode, xops);
19543 emit_insn (gen_set_got (pic_offset_table_rtx));
19547 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19550 [(set (match_operand 0 "register_operand" "")
19551 (match_operator 3 "promotable_binary_operator"
19552 [(match_operand 1 "register_operand" "")
19553 (match_operand 2 "aligned_operand" "")]))
19554 (clobber (reg:CC FLAGS_REG))]
19555 "! TARGET_PARTIAL_REG_STALL && reload_completed
19556 && ((GET_MODE (operands[0]) == HImode
19557 && ((!optimize_size && !TARGET_FAST_PREFIX)
19558 /* ??? next two lines just !satisfies_constraint_K (...) */
19559 || !CONST_INT_P (operands[2])
19560 || satisfies_constraint_K (operands[2])))
19561 || (GET_MODE (operands[0]) == QImode
19562 && (TARGET_PROMOTE_QImode || optimize_size)))"
19563 [(parallel [(set (match_dup 0)
19564 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19565 (clobber (reg:CC FLAGS_REG))])]
19566 "operands[0] = gen_lowpart (SImode, operands[0]);
19567 operands[1] = gen_lowpart (SImode, operands[1]);
19568 if (GET_CODE (operands[3]) != ASHIFT)
19569 operands[2] = gen_lowpart (SImode, operands[2]);
19570 PUT_MODE (operands[3], SImode);")
19572 ; Promote the QImode tests, as i386 has encoding of the AND
19573 ; instruction with 32-bit sign-extended immediate and thus the
19574 ; instruction size is unchanged, except in the %eax case for
19575 ; which it is increased by one byte, hence the ! optimize_size.
19577 [(set (match_operand 0 "flags_reg_operand" "")
19578 (match_operator 2 "compare_operator"
19579 [(and (match_operand 3 "aligned_operand" "")
19580 (match_operand 4 "const_int_operand" ""))
19582 (set (match_operand 1 "register_operand" "")
19583 (and (match_dup 3) (match_dup 4)))]
19584 "! TARGET_PARTIAL_REG_STALL && reload_completed
19585 /* Ensure that the operand will remain sign-extended immediate. */
19586 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19588 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19589 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19590 [(parallel [(set (match_dup 0)
19591 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19594 (and:SI (match_dup 3) (match_dup 4)))])]
19597 = gen_int_mode (INTVAL (operands[4])
19598 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19599 operands[1] = gen_lowpart (SImode, operands[1]);
19600 operands[3] = gen_lowpart (SImode, operands[3]);
19603 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19604 ; the TEST instruction with 32-bit sign-extended immediate and thus
19605 ; the instruction size would at least double, which is not what we
19606 ; want even with ! optimize_size.
19608 [(set (match_operand 0 "flags_reg_operand" "")
19609 (match_operator 1 "compare_operator"
19610 [(and (match_operand:HI 2 "aligned_operand" "")
19611 (match_operand:HI 3 "const_int_operand" ""))
19613 "! TARGET_PARTIAL_REG_STALL && reload_completed
19614 /* Ensure that the operand will remain sign-extended immediate. */
19615 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19616 && ! TARGET_FAST_PREFIX
19617 && ! optimize_size"
19618 [(set (match_dup 0)
19619 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19623 = gen_int_mode (INTVAL (operands[3])
19624 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19625 operands[2] = gen_lowpart (SImode, operands[2]);
19629 [(set (match_operand 0 "register_operand" "")
19630 (neg (match_operand 1 "register_operand" "")))
19631 (clobber (reg:CC FLAGS_REG))]
19632 "! TARGET_PARTIAL_REG_STALL && reload_completed
19633 && (GET_MODE (operands[0]) == HImode
19634 || (GET_MODE (operands[0]) == QImode
19635 && (TARGET_PROMOTE_QImode || optimize_size)))"
19636 [(parallel [(set (match_dup 0)
19637 (neg:SI (match_dup 1)))
19638 (clobber (reg:CC FLAGS_REG))])]
19639 "operands[0] = gen_lowpart (SImode, operands[0]);
19640 operands[1] = gen_lowpart (SImode, operands[1]);")
19643 [(set (match_operand 0 "register_operand" "")
19644 (not (match_operand 1 "register_operand" "")))]
19645 "! TARGET_PARTIAL_REG_STALL && reload_completed
19646 && (GET_MODE (operands[0]) == HImode
19647 || (GET_MODE (operands[0]) == QImode
19648 && (TARGET_PROMOTE_QImode || optimize_size)))"
19649 [(set (match_dup 0)
19650 (not:SI (match_dup 1)))]
19651 "operands[0] = gen_lowpart (SImode, operands[0]);
19652 operands[1] = gen_lowpart (SImode, operands[1]);")
19655 [(set (match_operand 0 "register_operand" "")
19656 (if_then_else (match_operator 1 "comparison_operator"
19657 [(reg FLAGS_REG) (const_int 0)])
19658 (match_operand 2 "register_operand" "")
19659 (match_operand 3 "register_operand" "")))]
19660 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19661 && (GET_MODE (operands[0]) == HImode
19662 || (GET_MODE (operands[0]) == QImode
19663 && (TARGET_PROMOTE_QImode || optimize_size)))"
19664 [(set (match_dup 0)
19665 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19666 "operands[0] = gen_lowpart (SImode, operands[0]);
19667 operands[2] = gen_lowpart (SImode, operands[2]);
19668 operands[3] = gen_lowpart (SImode, operands[3]);")
19671 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19672 ;; transform a complex memory operation into two memory to register operations.
19674 ;; Don't push memory operands
19676 [(set (match_operand:SI 0 "push_operand" "")
19677 (match_operand:SI 1 "memory_operand" ""))
19678 (match_scratch:SI 2 "r")]
19679 "!optimize_size && !TARGET_PUSH_MEMORY
19680 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19681 [(set (match_dup 2) (match_dup 1))
19682 (set (match_dup 0) (match_dup 2))]
19686 [(set (match_operand:DI 0 "push_operand" "")
19687 (match_operand:DI 1 "memory_operand" ""))
19688 (match_scratch:DI 2 "r")]
19689 "!optimize_size && !TARGET_PUSH_MEMORY
19690 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19691 [(set (match_dup 2) (match_dup 1))
19692 (set (match_dup 0) (match_dup 2))]
19695 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19698 [(set (match_operand:SF 0 "push_operand" "")
19699 (match_operand:SF 1 "memory_operand" ""))
19700 (match_scratch:SF 2 "r")]
19701 "!optimize_size && !TARGET_PUSH_MEMORY
19702 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19703 [(set (match_dup 2) (match_dup 1))
19704 (set (match_dup 0) (match_dup 2))]
19708 [(set (match_operand:HI 0 "push_operand" "")
19709 (match_operand:HI 1 "memory_operand" ""))
19710 (match_scratch:HI 2 "r")]
19711 "!optimize_size && !TARGET_PUSH_MEMORY
19712 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19713 [(set (match_dup 2) (match_dup 1))
19714 (set (match_dup 0) (match_dup 2))]
19718 [(set (match_operand:QI 0 "push_operand" "")
19719 (match_operand:QI 1 "memory_operand" ""))
19720 (match_scratch:QI 2 "q")]
19721 "!optimize_size && !TARGET_PUSH_MEMORY
19722 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19723 [(set (match_dup 2) (match_dup 1))
19724 (set (match_dup 0) (match_dup 2))]
19727 ;; Don't move an immediate directly to memory when the instruction
19730 [(match_scratch:SI 1 "r")
19731 (set (match_operand:SI 0 "memory_operand" "")
19734 && ! TARGET_USE_MOV0
19735 && TARGET_SPLIT_LONG_MOVES
19736 && get_attr_length (insn) >= ix86_cost->large_insn
19737 && peep2_regno_dead_p (0, FLAGS_REG)"
19738 [(parallel [(set (match_dup 1) (const_int 0))
19739 (clobber (reg:CC FLAGS_REG))])
19740 (set (match_dup 0) (match_dup 1))]
19744 [(match_scratch:HI 1 "r")
19745 (set (match_operand:HI 0 "memory_operand" "")
19748 && ! TARGET_USE_MOV0
19749 && TARGET_SPLIT_LONG_MOVES
19750 && get_attr_length (insn) >= ix86_cost->large_insn
19751 && peep2_regno_dead_p (0, FLAGS_REG)"
19752 [(parallel [(set (match_dup 2) (const_int 0))
19753 (clobber (reg:CC FLAGS_REG))])
19754 (set (match_dup 0) (match_dup 1))]
19755 "operands[2] = gen_lowpart (SImode, operands[1]);")
19758 [(match_scratch:QI 1 "q")
19759 (set (match_operand:QI 0 "memory_operand" "")
19762 && ! TARGET_USE_MOV0
19763 && TARGET_SPLIT_LONG_MOVES
19764 && get_attr_length (insn) >= ix86_cost->large_insn
19765 && peep2_regno_dead_p (0, FLAGS_REG)"
19766 [(parallel [(set (match_dup 2) (const_int 0))
19767 (clobber (reg:CC FLAGS_REG))])
19768 (set (match_dup 0) (match_dup 1))]
19769 "operands[2] = gen_lowpart (SImode, operands[1]);")
19772 [(match_scratch:SI 2 "r")
19773 (set (match_operand:SI 0 "memory_operand" "")
19774 (match_operand:SI 1 "immediate_operand" ""))]
19776 && get_attr_length (insn) >= ix86_cost->large_insn
19777 && TARGET_SPLIT_LONG_MOVES"
19778 [(set (match_dup 2) (match_dup 1))
19779 (set (match_dup 0) (match_dup 2))]
19783 [(match_scratch:HI 2 "r")
19784 (set (match_operand:HI 0 "memory_operand" "")
19785 (match_operand:HI 1 "immediate_operand" ""))]
19786 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19787 && TARGET_SPLIT_LONG_MOVES"
19788 [(set (match_dup 2) (match_dup 1))
19789 (set (match_dup 0) (match_dup 2))]
19793 [(match_scratch:QI 2 "q")
19794 (set (match_operand:QI 0 "memory_operand" "")
19795 (match_operand:QI 1 "immediate_operand" ""))]
19796 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19797 && TARGET_SPLIT_LONG_MOVES"
19798 [(set (match_dup 2) (match_dup 1))
19799 (set (match_dup 0) (match_dup 2))]
19802 ;; Don't compare memory with zero, load and use a test instead.
19804 [(set (match_operand 0 "flags_reg_operand" "")
19805 (match_operator 1 "compare_operator"
19806 [(match_operand:SI 2 "memory_operand" "")
19808 (match_scratch:SI 3 "r")]
19809 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19810 [(set (match_dup 3) (match_dup 2))
19811 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19814 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19815 ;; Don't split NOTs with a displacement operand, because resulting XOR
19816 ;; will not be pairable anyway.
19818 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19819 ;; represented using a modRM byte. The XOR replacement is long decoded,
19820 ;; so this split helps here as well.
19822 ;; Note: Can't do this as a regular split because we can't get proper
19823 ;; lifetime information then.
19826 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19827 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19829 && peep2_regno_dead_p (0, FLAGS_REG)
19830 && ((TARGET_PENTIUM
19831 && (!MEM_P (operands[0])
19832 || !memory_displacement_operand (operands[0], SImode)))
19833 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19834 [(parallel [(set (match_dup 0)
19835 (xor:SI (match_dup 1) (const_int -1)))
19836 (clobber (reg:CC FLAGS_REG))])]
19840 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19841 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19843 && peep2_regno_dead_p (0, FLAGS_REG)
19844 && ((TARGET_PENTIUM
19845 && (!MEM_P (operands[0])
19846 || !memory_displacement_operand (operands[0], HImode)))
19847 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19848 [(parallel [(set (match_dup 0)
19849 (xor:HI (match_dup 1) (const_int -1)))
19850 (clobber (reg:CC FLAGS_REG))])]
19854 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19855 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19857 && peep2_regno_dead_p (0, FLAGS_REG)
19858 && ((TARGET_PENTIUM
19859 && (!MEM_P (operands[0])
19860 || !memory_displacement_operand (operands[0], QImode)))
19861 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19862 [(parallel [(set (match_dup 0)
19863 (xor:QI (match_dup 1) (const_int -1)))
19864 (clobber (reg:CC FLAGS_REG))])]
19867 ;; Non pairable "test imm, reg" instructions can be translated to
19868 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19869 ;; byte opcode instead of two, have a short form for byte operands),
19870 ;; so do it for other CPUs as well. Given that the value was dead,
19871 ;; this should not create any new dependencies. Pass on the sub-word
19872 ;; versions if we're concerned about partial register stalls.
19875 [(set (match_operand 0 "flags_reg_operand" "")
19876 (match_operator 1 "compare_operator"
19877 [(and:SI (match_operand:SI 2 "register_operand" "")
19878 (match_operand:SI 3 "immediate_operand" ""))
19880 "ix86_match_ccmode (insn, CCNOmode)
19881 && (true_regnum (operands[2]) != 0
19882 || satisfies_constraint_K (operands[3]))
19883 && peep2_reg_dead_p (1, operands[2])"
19885 [(set (match_dup 0)
19886 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19889 (and:SI (match_dup 2) (match_dup 3)))])]
19892 ;; We don't need to handle HImode case, because it will be promoted to SImode
19893 ;; on ! TARGET_PARTIAL_REG_STALL
19896 [(set (match_operand 0 "flags_reg_operand" "")
19897 (match_operator 1 "compare_operator"
19898 [(and:QI (match_operand:QI 2 "register_operand" "")
19899 (match_operand:QI 3 "immediate_operand" ""))
19901 "! TARGET_PARTIAL_REG_STALL
19902 && ix86_match_ccmode (insn, CCNOmode)
19903 && true_regnum (operands[2]) != 0
19904 && peep2_reg_dead_p (1, operands[2])"
19906 [(set (match_dup 0)
19907 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19910 (and:QI (match_dup 2) (match_dup 3)))])]
19914 [(set (match_operand 0 "flags_reg_operand" "")
19915 (match_operator 1 "compare_operator"
19918 (match_operand 2 "ext_register_operand" "")
19921 (match_operand 3 "const_int_operand" ""))
19923 "! TARGET_PARTIAL_REG_STALL
19924 && ix86_match_ccmode (insn, CCNOmode)
19925 && true_regnum (operands[2]) != 0
19926 && peep2_reg_dead_p (1, operands[2])"
19927 [(parallel [(set (match_dup 0)
19936 (set (zero_extract:SI (match_dup 2)
19947 ;; Don't do logical operations with memory inputs.
19949 [(match_scratch:SI 2 "r")
19950 (parallel [(set (match_operand:SI 0 "register_operand" "")
19951 (match_operator:SI 3 "arith_or_logical_operator"
19953 (match_operand:SI 1 "memory_operand" "")]))
19954 (clobber (reg:CC FLAGS_REG))])]
19955 "! optimize_size && ! TARGET_READ_MODIFY"
19956 [(set (match_dup 2) (match_dup 1))
19957 (parallel [(set (match_dup 0)
19958 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19959 (clobber (reg:CC FLAGS_REG))])]
19963 [(match_scratch:SI 2 "r")
19964 (parallel [(set (match_operand:SI 0 "register_operand" "")
19965 (match_operator:SI 3 "arith_or_logical_operator"
19966 [(match_operand:SI 1 "memory_operand" "")
19968 (clobber (reg:CC FLAGS_REG))])]
19969 "! optimize_size && ! TARGET_READ_MODIFY"
19970 [(set (match_dup 2) (match_dup 1))
19971 (parallel [(set (match_dup 0)
19972 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19973 (clobber (reg:CC FLAGS_REG))])]
19976 ; Don't do logical operations with memory outputs
19978 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19979 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19980 ; the same decoder scheduling characteristics as the original.
19983 [(match_scratch:SI 2 "r")
19984 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19985 (match_operator:SI 3 "arith_or_logical_operator"
19987 (match_operand:SI 1 "nonmemory_operand" "")]))
19988 (clobber (reg:CC FLAGS_REG))])]
19989 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19990 [(set (match_dup 2) (match_dup 0))
19991 (parallel [(set (match_dup 2)
19992 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19993 (clobber (reg:CC FLAGS_REG))])
19994 (set (match_dup 0) (match_dup 2))]
19998 [(match_scratch:SI 2 "r")
19999 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20000 (match_operator:SI 3 "arith_or_logical_operator"
20001 [(match_operand:SI 1 "nonmemory_operand" "")
20003 (clobber (reg:CC FLAGS_REG))])]
20004 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20005 [(set (match_dup 2) (match_dup 0))
20006 (parallel [(set (match_dup 2)
20007 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20008 (clobber (reg:CC FLAGS_REG))])
20009 (set (match_dup 0) (match_dup 2))]
20012 ;; Attempt to always use XOR for zeroing registers.
20014 [(set (match_operand 0 "register_operand" "")
20015 (match_operand 1 "const0_operand" ""))]
20016 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20017 && (! TARGET_USE_MOV0 || optimize_size)
20018 && GENERAL_REG_P (operands[0])
20019 && peep2_regno_dead_p (0, FLAGS_REG)"
20020 [(parallel [(set (match_dup 0) (const_int 0))
20021 (clobber (reg:CC FLAGS_REG))])]
20023 operands[0] = gen_lowpart (word_mode, operands[0]);
20027 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20029 "(GET_MODE (operands[0]) == QImode
20030 || GET_MODE (operands[0]) == HImode)
20031 && (! TARGET_USE_MOV0 || optimize_size)
20032 && peep2_regno_dead_p (0, FLAGS_REG)"
20033 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20034 (clobber (reg:CC FLAGS_REG))])])
20036 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20038 [(set (match_operand 0 "register_operand" "")
20040 "(GET_MODE (operands[0]) == HImode
20041 || GET_MODE (operands[0]) == SImode
20042 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20043 && (optimize_size || TARGET_PENTIUM)
20044 && peep2_regno_dead_p (0, FLAGS_REG)"
20045 [(parallel [(set (match_dup 0) (const_int -1))
20046 (clobber (reg:CC FLAGS_REG))])]
20047 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20050 ;; Attempt to convert simple leas to adds. These can be created by
20053 [(set (match_operand:SI 0 "register_operand" "")
20054 (plus:SI (match_dup 0)
20055 (match_operand:SI 1 "nonmemory_operand" "")))]
20056 "peep2_regno_dead_p (0, FLAGS_REG)"
20057 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20058 (clobber (reg:CC FLAGS_REG))])]
20062 [(set (match_operand:SI 0 "register_operand" "")
20063 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20064 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20065 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20066 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20067 (clobber (reg:CC FLAGS_REG))])]
20068 "operands[2] = gen_lowpart (SImode, operands[2]);")
20071 [(set (match_operand:DI 0 "register_operand" "")
20072 (plus:DI (match_dup 0)
20073 (match_operand:DI 1 "x86_64_general_operand" "")))]
20074 "peep2_regno_dead_p (0, FLAGS_REG)"
20075 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20076 (clobber (reg:CC FLAGS_REG))])]
20080 [(set (match_operand:SI 0 "register_operand" "")
20081 (mult:SI (match_dup 0)
20082 (match_operand:SI 1 "const_int_operand" "")))]
20083 "exact_log2 (INTVAL (operands[1])) >= 0
20084 && peep2_regno_dead_p (0, FLAGS_REG)"
20085 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20086 (clobber (reg:CC FLAGS_REG))])]
20087 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20090 [(set (match_operand:DI 0 "register_operand" "")
20091 (mult:DI (match_dup 0)
20092 (match_operand:DI 1 "const_int_operand" "")))]
20093 "exact_log2 (INTVAL (operands[1])) >= 0
20094 && peep2_regno_dead_p (0, FLAGS_REG)"
20095 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20096 (clobber (reg:CC FLAGS_REG))])]
20097 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20100 [(set (match_operand:SI 0 "register_operand" "")
20101 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20102 (match_operand:DI 2 "const_int_operand" "")) 0))]
20103 "exact_log2 (INTVAL (operands[2])) >= 0
20104 && REGNO (operands[0]) == REGNO (operands[1])
20105 && peep2_regno_dead_p (0, FLAGS_REG)"
20106 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20107 (clobber (reg:CC FLAGS_REG))])]
20108 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20110 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20111 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20112 ;; many CPUs it is also faster, since special hardware to avoid esp
20113 ;; dependencies is present.
20115 ;; While some of these conversions may be done using splitters, we use peepholes
20116 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20118 ;; Convert prologue esp subtractions to push.
20119 ;; We need register to push. In order to keep verify_flow_info happy we have
20121 ;; - use scratch and clobber it in order to avoid dependencies
20122 ;; - use already live register
20123 ;; We can't use the second way right now, since there is no reliable way how to
20124 ;; verify that given register is live. First choice will also most likely in
20125 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20126 ;; call clobbered registers are dead. We may want to use base pointer as an
20127 ;; alternative when no register is available later.
20130 [(match_scratch:SI 0 "r")
20131 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20132 (clobber (reg:CC FLAGS_REG))
20133 (clobber (mem:BLK (scratch)))])]
20134 "optimize_size || !TARGET_SUB_ESP_4"
20135 [(clobber (match_dup 0))
20136 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20137 (clobber (mem:BLK (scratch)))])])
20140 [(match_scratch:SI 0 "r")
20141 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20142 (clobber (reg:CC FLAGS_REG))
20143 (clobber (mem:BLK (scratch)))])]
20144 "optimize_size || !TARGET_SUB_ESP_8"
20145 [(clobber (match_dup 0))
20146 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20147 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20148 (clobber (mem:BLK (scratch)))])])
20150 ;; Convert esp subtractions to push.
20152 [(match_scratch:SI 0 "r")
20153 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20154 (clobber (reg:CC FLAGS_REG))])]
20155 "optimize_size || !TARGET_SUB_ESP_4"
20156 [(clobber (match_dup 0))
20157 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20160 [(match_scratch:SI 0 "r")
20161 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20162 (clobber (reg:CC FLAGS_REG))])]
20163 "optimize_size || !TARGET_SUB_ESP_8"
20164 [(clobber (match_dup 0))
20165 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20166 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20168 ;; Convert epilogue deallocator to pop.
20170 [(match_scratch:SI 0 "r")
20171 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20172 (clobber (reg:CC FLAGS_REG))
20173 (clobber (mem:BLK (scratch)))])]
20174 "optimize_size || !TARGET_ADD_ESP_4"
20175 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20176 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20177 (clobber (mem:BLK (scratch)))])]
20180 ;; Two pops case is tricky, since pop causes dependency on destination register.
20181 ;; We use two registers if available.
20183 [(match_scratch:SI 0 "r")
20184 (match_scratch:SI 1 "r")
20185 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20186 (clobber (reg:CC FLAGS_REG))
20187 (clobber (mem:BLK (scratch)))])]
20188 "optimize_size || !TARGET_ADD_ESP_8"
20189 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20190 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20191 (clobber (mem:BLK (scratch)))])
20192 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20193 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20197 [(match_scratch:SI 0 "r")
20198 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20199 (clobber (reg:CC FLAGS_REG))
20200 (clobber (mem:BLK (scratch)))])]
20202 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20203 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20204 (clobber (mem:BLK (scratch)))])
20205 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20206 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20209 ;; Convert esp additions to pop.
20211 [(match_scratch:SI 0 "r")
20212 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20213 (clobber (reg:CC FLAGS_REG))])]
20215 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20216 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20219 ;; Two pops case is tricky, since pop causes dependency on destination register.
20220 ;; We use two registers if available.
20222 [(match_scratch:SI 0 "r")
20223 (match_scratch:SI 1 "r")
20224 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20225 (clobber (reg:CC FLAGS_REG))])]
20227 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20228 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20229 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20230 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20234 [(match_scratch:SI 0 "r")
20235 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20236 (clobber (reg:CC FLAGS_REG))])]
20238 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20239 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20240 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20241 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20244 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20245 ;; required and register dies. Similarly for 128 to plus -128.
20247 [(set (match_operand 0 "flags_reg_operand" "")
20248 (match_operator 1 "compare_operator"
20249 [(match_operand 2 "register_operand" "")
20250 (match_operand 3 "const_int_operand" "")]))]
20251 "(INTVAL (operands[3]) == -1
20252 || INTVAL (operands[3]) == 1
20253 || INTVAL (operands[3]) == 128)
20254 && ix86_match_ccmode (insn, CCGCmode)
20255 && peep2_reg_dead_p (1, operands[2])"
20256 [(parallel [(set (match_dup 0)
20257 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20258 (clobber (match_dup 2))])]
20262 [(match_scratch:DI 0 "r")
20263 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20264 (clobber (reg:CC FLAGS_REG))
20265 (clobber (mem:BLK (scratch)))])]
20266 "optimize_size || !TARGET_SUB_ESP_4"
20267 [(clobber (match_dup 0))
20268 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20269 (clobber (mem:BLK (scratch)))])])
20272 [(match_scratch:DI 0 "r")
20273 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20274 (clobber (reg:CC FLAGS_REG))
20275 (clobber (mem:BLK (scratch)))])]
20276 "optimize_size || !TARGET_SUB_ESP_8"
20277 [(clobber (match_dup 0))
20278 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20279 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20280 (clobber (mem:BLK (scratch)))])])
20282 ;; Convert esp subtractions to push.
20284 [(match_scratch:DI 0 "r")
20285 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20286 (clobber (reg:CC FLAGS_REG))])]
20287 "optimize_size || !TARGET_SUB_ESP_4"
20288 [(clobber (match_dup 0))
20289 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20292 [(match_scratch:DI 0 "r")
20293 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20294 (clobber (reg:CC FLAGS_REG))])]
20295 "optimize_size || !TARGET_SUB_ESP_8"
20296 [(clobber (match_dup 0))
20297 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20298 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20300 ;; Convert epilogue deallocator to pop.
20302 [(match_scratch:DI 0 "r")
20303 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20304 (clobber (reg:CC FLAGS_REG))
20305 (clobber (mem:BLK (scratch)))])]
20306 "optimize_size || !TARGET_ADD_ESP_4"
20307 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20308 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20309 (clobber (mem:BLK (scratch)))])]
20312 ;; Two pops case is tricky, since pop causes dependency on destination register.
20313 ;; We use two registers if available.
20315 [(match_scratch:DI 0 "r")
20316 (match_scratch:DI 1 "r")
20317 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20318 (clobber (reg:CC FLAGS_REG))
20319 (clobber (mem:BLK (scratch)))])]
20320 "optimize_size || !TARGET_ADD_ESP_8"
20321 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20322 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20323 (clobber (mem:BLK (scratch)))])
20324 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20325 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20329 [(match_scratch:DI 0 "r")
20330 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20331 (clobber (reg:CC FLAGS_REG))
20332 (clobber (mem:BLK (scratch)))])]
20334 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20335 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20336 (clobber (mem:BLK (scratch)))])
20337 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20338 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20341 ;; Convert esp additions to pop.
20343 [(match_scratch:DI 0 "r")
20344 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20345 (clobber (reg:CC FLAGS_REG))])]
20347 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20348 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20351 ;; Two pops case is tricky, since pop causes dependency on destination register.
20352 ;; We use two registers if available.
20354 [(match_scratch:DI 0 "r")
20355 (match_scratch:DI 1 "r")
20356 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20357 (clobber (reg:CC FLAGS_REG))])]
20359 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20360 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20361 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20362 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20366 [(match_scratch:DI 0 "r")
20367 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20368 (clobber (reg:CC FLAGS_REG))])]
20370 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20371 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20372 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20373 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20376 ;; Convert imul by three, five and nine into lea
20379 [(set (match_operand:SI 0 "register_operand" "")
20380 (mult:SI (match_operand:SI 1 "register_operand" "")
20381 (match_operand:SI 2 "const_int_operand" "")))
20382 (clobber (reg:CC FLAGS_REG))])]
20383 "INTVAL (operands[2]) == 3
20384 || INTVAL (operands[2]) == 5
20385 || INTVAL (operands[2]) == 9"
20386 [(set (match_dup 0)
20387 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20389 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20393 [(set (match_operand:SI 0 "register_operand" "")
20394 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20395 (match_operand:SI 2 "const_int_operand" "")))
20396 (clobber (reg:CC FLAGS_REG))])]
20398 && (INTVAL (operands[2]) == 3
20399 || INTVAL (operands[2]) == 5
20400 || INTVAL (operands[2]) == 9)"
20401 [(set (match_dup 0) (match_dup 1))
20403 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20405 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20409 [(set (match_operand:DI 0 "register_operand" "")
20410 (mult:DI (match_operand:DI 1 "register_operand" "")
20411 (match_operand:DI 2 "const_int_operand" "")))
20412 (clobber (reg:CC FLAGS_REG))])]
20414 && (INTVAL (operands[2]) == 3
20415 || INTVAL (operands[2]) == 5
20416 || INTVAL (operands[2]) == 9)"
20417 [(set (match_dup 0)
20418 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20420 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20424 [(set (match_operand:DI 0 "register_operand" "")
20425 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20426 (match_operand:DI 2 "const_int_operand" "")))
20427 (clobber (reg:CC FLAGS_REG))])]
20430 && (INTVAL (operands[2]) == 3
20431 || INTVAL (operands[2]) == 5
20432 || INTVAL (operands[2]) == 9)"
20433 [(set (match_dup 0) (match_dup 1))
20435 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20437 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20439 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20440 ;; imul $32bit_imm, reg, reg is direct decoded.
20442 [(match_scratch:DI 3 "r")
20443 (parallel [(set (match_operand:DI 0 "register_operand" "")
20444 (mult:DI (match_operand:DI 1 "memory_operand" "")
20445 (match_operand:DI 2 "immediate_operand" "")))
20446 (clobber (reg:CC FLAGS_REG))])]
20447 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20448 && !satisfies_constraint_K (operands[2])"
20449 [(set (match_dup 3) (match_dup 1))
20450 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20451 (clobber (reg:CC FLAGS_REG))])]
20455 [(match_scratch:SI 3 "r")
20456 (parallel [(set (match_operand:SI 0 "register_operand" "")
20457 (mult:SI (match_operand:SI 1 "memory_operand" "")
20458 (match_operand:SI 2 "immediate_operand" "")))
20459 (clobber (reg:CC FLAGS_REG))])]
20460 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20461 && !satisfies_constraint_K (operands[2])"
20462 [(set (match_dup 3) (match_dup 1))
20463 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20464 (clobber (reg:CC FLAGS_REG))])]
20468 [(match_scratch:SI 3 "r")
20469 (parallel [(set (match_operand:DI 0 "register_operand" "")
20471 (mult:SI (match_operand:SI 1 "memory_operand" "")
20472 (match_operand:SI 2 "immediate_operand" ""))))
20473 (clobber (reg:CC FLAGS_REG))])]
20474 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20475 && !satisfies_constraint_K (operands[2])"
20476 [(set (match_dup 3) (match_dup 1))
20477 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20478 (clobber (reg:CC FLAGS_REG))])]
20481 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20482 ;; Convert it into imul reg, reg
20483 ;; It would be better to force assembler to encode instruction using long
20484 ;; immediate, but there is apparently no way to do so.
20486 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20487 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20488 (match_operand:DI 2 "const_int_operand" "")))
20489 (clobber (reg:CC FLAGS_REG))])
20490 (match_scratch:DI 3 "r")]
20491 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20492 && satisfies_constraint_K (operands[2])"
20493 [(set (match_dup 3) (match_dup 2))
20494 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20495 (clobber (reg:CC FLAGS_REG))])]
20497 if (!rtx_equal_p (operands[0], operands[1]))
20498 emit_move_insn (operands[0], operands[1]);
20502 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20503 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20504 (match_operand:SI 2 "const_int_operand" "")))
20505 (clobber (reg:CC FLAGS_REG))])
20506 (match_scratch:SI 3 "r")]
20507 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20508 && satisfies_constraint_K (operands[2])"
20509 [(set (match_dup 3) (match_dup 2))
20510 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20511 (clobber (reg:CC FLAGS_REG))])]
20513 if (!rtx_equal_p (operands[0], operands[1]))
20514 emit_move_insn (operands[0], operands[1]);
20518 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20519 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20520 (match_operand:HI 2 "immediate_operand" "")))
20521 (clobber (reg:CC FLAGS_REG))])
20522 (match_scratch:HI 3 "r")]
20523 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20524 [(set (match_dup 3) (match_dup 2))
20525 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20526 (clobber (reg:CC FLAGS_REG))])]
20528 if (!rtx_equal_p (operands[0], operands[1]))
20529 emit_move_insn (operands[0], operands[1]);
20532 ;; After splitting up read-modify operations, array accesses with memory
20533 ;; operands might end up in form:
20535 ;; movl 4(%esp), %edx
20537 ;; instead of pre-splitting:
20539 ;; addl 4(%esp), %eax
20541 ;; movl 4(%esp), %edx
20542 ;; leal (%edx,%eax,4), %eax
20545 [(parallel [(set (match_operand 0 "register_operand" "")
20546 (ashift (match_operand 1 "register_operand" "")
20547 (match_operand 2 "const_int_operand" "")))
20548 (clobber (reg:CC FLAGS_REG))])
20549 (set (match_operand 3 "register_operand")
20550 (match_operand 4 "x86_64_general_operand" ""))
20551 (parallel [(set (match_operand 5 "register_operand" "")
20552 (plus (match_operand 6 "register_operand" "")
20553 (match_operand 7 "register_operand" "")))
20554 (clobber (reg:CC FLAGS_REG))])]
20555 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20556 /* Validate MODE for lea. */
20557 && ((!TARGET_PARTIAL_REG_STALL
20558 && (GET_MODE (operands[0]) == QImode
20559 || GET_MODE (operands[0]) == HImode))
20560 || GET_MODE (operands[0]) == SImode
20561 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20562 /* We reorder load and the shift. */
20563 && !rtx_equal_p (operands[1], operands[3])
20564 && !reg_overlap_mentioned_p (operands[0], operands[4])
20565 /* Last PLUS must consist of operand 0 and 3. */
20566 && !rtx_equal_p (operands[0], operands[3])
20567 && (rtx_equal_p (operands[3], operands[6])
20568 || rtx_equal_p (operands[3], operands[7]))
20569 && (rtx_equal_p (operands[0], operands[6])
20570 || rtx_equal_p (operands[0], operands[7]))
20571 /* The intermediate operand 0 must die or be same as output. */
20572 && (rtx_equal_p (operands[0], operands[5])
20573 || peep2_reg_dead_p (3, operands[0]))"
20574 [(set (match_dup 3) (match_dup 4))
20575 (set (match_dup 0) (match_dup 1))]
20577 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20578 int scale = 1 << INTVAL (operands[2]);
20579 rtx index = gen_lowpart (Pmode, operands[1]);
20580 rtx base = gen_lowpart (Pmode, operands[3]);
20581 rtx dest = gen_lowpart (mode, operands[5]);
20583 operands[1] = gen_rtx_PLUS (Pmode, base,
20584 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20586 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20587 operands[0] = dest;
20590 ;; Call-value patterns last so that the wildcard operand does not
20591 ;; disrupt insn-recog's switch tables.
20593 (define_insn "*call_value_pop_0"
20594 [(set (match_operand 0 "" "")
20595 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20596 (match_operand:SI 2 "" "")))
20597 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20598 (match_operand:SI 3 "immediate_operand" "")))]
20601 if (SIBLING_CALL_P (insn))
20604 return "call\t%P1";
20606 [(set_attr "type" "callv")])
20608 (define_insn "*call_value_pop_1"
20609 [(set (match_operand 0 "" "")
20610 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20611 (match_operand:SI 2 "" "")))
20612 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20613 (match_operand:SI 3 "immediate_operand" "i")))]
20616 if (constant_call_address_operand (operands[1], Pmode))
20618 if (SIBLING_CALL_P (insn))
20621 return "call\t%P1";
20623 if (SIBLING_CALL_P (insn))
20626 return "call\t%A1";
20628 [(set_attr "type" "callv")])
20630 (define_insn "*call_value_0"
20631 [(set (match_operand 0 "" "")
20632 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20633 (match_operand:SI 2 "" "")))]
20636 if (SIBLING_CALL_P (insn))
20639 return "call\t%P1";
20641 [(set_attr "type" "callv")])
20643 (define_insn "*call_value_0_rex64"
20644 [(set (match_operand 0 "" "")
20645 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20646 (match_operand:DI 2 "const_int_operand" "")))]
20649 if (SIBLING_CALL_P (insn))
20652 return "call\t%P1";
20654 [(set_attr "type" "callv")])
20656 (define_insn "*call_value_1"
20657 [(set (match_operand 0 "" "")
20658 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20659 (match_operand:SI 2 "" "")))]
20660 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20662 if (constant_call_address_operand (operands[1], Pmode))
20663 return "call\t%P1";
20664 return "call\t%A1";
20666 [(set_attr "type" "callv")])
20668 (define_insn "*sibcall_value_1"
20669 [(set (match_operand 0 "" "")
20670 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20671 (match_operand:SI 2 "" "")))]
20672 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20674 if (constant_call_address_operand (operands[1], Pmode))
20678 [(set_attr "type" "callv")])
20680 (define_insn "*call_value_1_rex64"
20681 [(set (match_operand 0 "" "")
20682 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20683 (match_operand:DI 2 "" "")))]
20684 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20686 if (constant_call_address_operand (operands[1], Pmode))
20687 return "call\t%P1";
20688 return "call\t%A1";
20690 [(set_attr "type" "callv")])
20692 (define_insn "*sibcall_value_1_rex64"
20693 [(set (match_operand 0 "" "")
20694 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20695 (match_operand:DI 2 "" "")))]
20696 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20698 [(set_attr "type" "callv")])
20700 (define_insn "*sibcall_value_1_rex64_v"
20701 [(set (match_operand 0 "" "")
20702 (call (mem:QI (reg:DI R11_REG))
20703 (match_operand:DI 1 "" "")))]
20704 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20706 [(set_attr "type" "callv")])
20708 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20709 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20710 ;; caught for use by garbage collectors and the like. Using an insn that
20711 ;; maps to SIGILL makes it more likely the program will rightfully die.
20712 ;; Keeping with tradition, "6" is in honor of #UD.
20713 (define_insn "trap"
20714 [(trap_if (const_int 1) (const_int 6))]
20716 { return ASM_SHORT "0x0b0f"; }
20717 [(set_attr "length" "2")])
20719 (define_expand "sse_prologue_save"
20720 [(parallel [(set (match_operand:BLK 0 "" "")
20721 (unspec:BLK [(reg:DI 21)
20728 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20729 (use (match_operand:DI 1 "register_operand" ""))
20730 (use (match_operand:DI 2 "immediate_operand" ""))
20731 (use (label_ref:DI (match_operand 3 "" "")))])]
20735 (define_insn "*sse_prologue_save_insn"
20736 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20737 (match_operand:DI 4 "const_int_operand" "n")))
20738 (unspec:BLK [(reg:DI 21)
20745 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20746 (use (match_operand:DI 1 "register_operand" "r"))
20747 (use (match_operand:DI 2 "const_int_operand" "i"))
20748 (use (label_ref:DI (match_operand 3 "" "X")))]
20750 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20751 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20755 operands[0] = gen_rtx_MEM (Pmode,
20756 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20757 output_asm_insn (\"jmp\\t%A1\", operands);
20758 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20760 operands[4] = adjust_address (operands[0], DImode, i*16);
20761 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20762 PUT_MODE (operands[4], TImode);
20763 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20764 output_asm_insn (\"rex\", operands);
20765 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20767 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20768 CODE_LABEL_NUMBER (operands[3]));
20772 [(set_attr "type" "other")
20773 (set_attr "length_immediate" "0")
20774 (set_attr "length_address" "0")
20775 (set_attr "length" "135")
20776 (set_attr "memory" "store")
20777 (set_attr "modrm" "0")
20778 (set_attr "mode" "DI")])
20780 (define_expand "prefetch"
20781 [(prefetch (match_operand 0 "address_operand" "")
20782 (match_operand:SI 1 "const_int_operand" "")
20783 (match_operand:SI 2 "const_int_operand" ""))]
20784 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20786 int rw = INTVAL (operands[1]);
20787 int locality = INTVAL (operands[2]);
20789 gcc_assert (rw == 0 || rw == 1);
20790 gcc_assert (locality >= 0 && locality <= 3);
20791 gcc_assert (GET_MODE (operands[0]) == Pmode
20792 || GET_MODE (operands[0]) == VOIDmode);
20794 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20795 supported by SSE counterpart or the SSE prefetch is not available
20796 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20798 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20799 operands[2] = GEN_INT (3);
20801 operands[1] = const0_rtx;
20804 (define_insn "*prefetch_sse"
20805 [(prefetch (match_operand:SI 0 "address_operand" "p")
20807 (match_operand:SI 1 "const_int_operand" ""))]
20808 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20810 static const char * const patterns[4] = {
20811 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20814 int locality = INTVAL (operands[1]);
20815 gcc_assert (locality >= 0 && locality <= 3);
20817 return patterns[locality];
20819 [(set_attr "type" "sse")
20820 (set_attr "memory" "none")])
20822 (define_insn "*prefetch_sse_rex"
20823 [(prefetch (match_operand:DI 0 "address_operand" "p")
20825 (match_operand:SI 1 "const_int_operand" ""))]
20826 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20828 static const char * const patterns[4] = {
20829 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20832 int locality = INTVAL (operands[1]);
20833 gcc_assert (locality >= 0 && locality <= 3);
20835 return patterns[locality];
20837 [(set_attr "type" "sse")
20838 (set_attr "memory" "none")])
20840 (define_insn "*prefetch_3dnow"
20841 [(prefetch (match_operand:SI 0 "address_operand" "p")
20842 (match_operand:SI 1 "const_int_operand" "n")
20844 "TARGET_3DNOW && !TARGET_64BIT"
20846 if (INTVAL (operands[1]) == 0)
20847 return "prefetch\t%a0";
20849 return "prefetchw\t%a0";
20851 [(set_attr "type" "mmx")
20852 (set_attr "memory" "none")])
20854 (define_insn "*prefetch_3dnow_rex"
20855 [(prefetch (match_operand:DI 0 "address_operand" "p")
20856 (match_operand:SI 1 "const_int_operand" "n")
20858 "TARGET_3DNOW && TARGET_64BIT"
20860 if (INTVAL (operands[1]) == 0)
20861 return "prefetch\t%a0";
20863 return "prefetchw\t%a0";
20865 [(set_attr "type" "mmx")
20866 (set_attr "memory" "none")])
20868 (define_expand "stack_protect_set"
20869 [(match_operand 0 "memory_operand" "")
20870 (match_operand 1 "memory_operand" "")]
20873 #ifdef TARGET_THREAD_SSP_OFFSET
20875 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20876 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20878 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20879 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20882 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20884 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20889 (define_insn "stack_protect_set_si"
20890 [(set (match_operand:SI 0 "memory_operand" "=m")
20891 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20892 (set (match_scratch:SI 2 "=&r") (const_int 0))
20893 (clobber (reg:CC FLAGS_REG))]
20895 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20896 [(set_attr "type" "multi")])
20898 (define_insn "stack_protect_set_di"
20899 [(set (match_operand:DI 0 "memory_operand" "=m")
20900 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20901 (set (match_scratch:DI 2 "=&r") (const_int 0))
20902 (clobber (reg:CC FLAGS_REG))]
20904 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20905 [(set_attr "type" "multi")])
20907 (define_insn "stack_tls_protect_set_si"
20908 [(set (match_operand:SI 0 "memory_operand" "=m")
20909 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20910 (set (match_scratch:SI 2 "=&r") (const_int 0))
20911 (clobber (reg:CC FLAGS_REG))]
20913 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20914 [(set_attr "type" "multi")])
20916 (define_insn "stack_tls_protect_set_di"
20917 [(set (match_operand:DI 0 "memory_operand" "=m")
20918 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20919 (set (match_scratch:DI 2 "=&r") (const_int 0))
20920 (clobber (reg:CC FLAGS_REG))]
20923 /* The kernel uses a different segment register for performance reasons; a
20924 system call would not have to trash the userspace segment register,
20925 which would be expensive */
20926 if (ix86_cmodel != CM_KERNEL)
20927 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20929 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20931 [(set_attr "type" "multi")])
20933 (define_expand "stack_protect_test"
20934 [(match_operand 0 "memory_operand" "")
20935 (match_operand 1 "memory_operand" "")
20936 (match_operand 2 "" "")]
20939 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20940 ix86_compare_op0 = operands[0];
20941 ix86_compare_op1 = operands[1];
20942 ix86_compare_emitted = flags;
20944 #ifdef TARGET_THREAD_SSP_OFFSET
20946 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20947 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20949 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20950 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20953 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20955 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20957 emit_jump_insn (gen_beq (operands[2]));
20961 (define_insn "stack_protect_test_si"
20962 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20963 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20964 (match_operand:SI 2 "memory_operand" "m")]
20966 (clobber (match_scratch:SI 3 "=&r"))]
20968 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20969 [(set_attr "type" "multi")])
20971 (define_insn "stack_protect_test_di"
20972 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20973 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20974 (match_operand:DI 2 "memory_operand" "m")]
20976 (clobber (match_scratch:DI 3 "=&r"))]
20978 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20979 [(set_attr "type" "multi")])
20981 (define_insn "stack_tls_protect_test_si"
20982 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20983 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20984 (match_operand:SI 2 "const_int_operand" "i")]
20985 UNSPEC_SP_TLS_TEST))
20986 (clobber (match_scratch:SI 3 "=r"))]
20988 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20989 [(set_attr "type" "multi")])
20991 (define_insn "stack_tls_protect_test_di"
20992 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20993 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20994 (match_operand:DI 2 "const_int_operand" "i")]
20995 UNSPEC_SP_TLS_TEST))
20996 (clobber (match_scratch:DI 3 "=r"))]
20999 /* The kernel uses a different segment register for performance reasons; a
21000 system call would not have to trash the userspace segment register,
21001 which would be expensive */
21002 if (ix86_cmodel != CM_KERNEL)
21003 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21005 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21007 [(set_attr "type" "multi")])
21011 (include "sync.md")