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 ;; When SSE is available, it is always faster to use it!
4335 (define_insn "fix_truncsfdi_sse"
4336 [(set (match_operand:DI 0 "register_operand" "=r,r")
4337 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4338 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4339 "cvttss2si{q}\t{%1, %0|%0, %1}"
4340 [(set_attr "type" "sseicvt")
4341 (set_attr "mode" "SF")
4342 (set_attr "athlon_decode" "double,vector")
4343 (set_attr "amdfam10_decode" "double,double")])
4345 (define_insn "fix_truncdfdi_sse"
4346 [(set (match_operand:DI 0 "register_operand" "=r,r")
4347 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4348 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4349 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4350 [(set_attr "type" "sseicvt")
4351 (set_attr "mode" "DF")
4352 (set_attr "athlon_decode" "double,vector")
4353 (set_attr "amdfam10_decode" "double,double")])
4355 (define_insn "fix_truncsfsi_sse"
4356 [(set (match_operand:SI 0 "register_operand" "=r,r")
4357 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4358 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4359 "cvttss2si\t{%1, %0|%0, %1}"
4360 [(set_attr "type" "sseicvt")
4361 (set_attr "mode" "DF")
4362 (set_attr "athlon_decode" "double,vector")
4363 (set_attr "amdfam10_decode" "double,double")])
4365 (define_insn "fix_truncdfsi_sse"
4366 [(set (match_operand:SI 0 "register_operand" "=r,r")
4367 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4368 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4369 "cvttsd2si\t{%1, %0|%0, %1}"
4370 [(set_attr "type" "sseicvt")
4371 (set_attr "mode" "DF")
4372 (set_attr "athlon_decode" "double,vector")
4373 (set_attr "amdfam10_decode" "double,double")])
4375 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4377 [(set (match_operand:DF 0 "register_operand" "")
4378 (match_operand:DF 1 "memory_operand" ""))
4379 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4380 (fix:SSEMODEI24 (match_dup 0)))]
4382 && peep2_reg_dead_p (2, operands[0])"
4383 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4387 [(set (match_operand:SF 0 "register_operand" "")
4388 (match_operand:SF 1 "memory_operand" ""))
4389 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4390 (fix:SSEMODEI24 (match_dup 0)))]
4392 && peep2_reg_dead_p (2, operands[0])"
4393 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4396 ;; Avoid vector decoded forms of the instruction.
4398 [(match_scratch:DF 2 "Y")
4399 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4400 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4401 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4402 [(set (match_dup 2) (match_dup 1))
4403 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4407 [(match_scratch:SF 2 "x")
4408 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4409 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4410 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4411 [(set (match_dup 2) (match_dup 1))
4412 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4415 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4416 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4417 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4419 && FLOAT_MODE_P (GET_MODE (operands[1]))
4420 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4421 && (TARGET_64BIT || <MODE>mode != DImode))
4423 && !(reload_completed || reload_in_progress)"
4428 if (memory_operand (operands[0], VOIDmode))
4429 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4432 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4433 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4439 [(set_attr "type" "fisttp")
4440 (set_attr "mode" "<MODE>")])
4442 (define_insn "fix_trunc<mode>_i387_fisttp"
4443 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4444 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4445 (clobber (match_scratch:XF 2 "=&1f"))]
4447 && FLOAT_MODE_P (GET_MODE (operands[1]))
4448 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4449 && (TARGET_64BIT || <MODE>mode != DImode))
4450 && TARGET_SSE_MATH)"
4451 "* return output_fix_trunc (insn, operands, 1);"
4452 [(set_attr "type" "fisttp")
4453 (set_attr "mode" "<MODE>")])
4455 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4456 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4457 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4458 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4459 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4461 && FLOAT_MODE_P (GET_MODE (operands[1]))
4462 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4463 && (TARGET_64BIT || <MODE>mode != DImode))
4464 && TARGET_SSE_MATH)"
4466 [(set_attr "type" "fisttp")
4467 (set_attr "mode" "<MODE>")])
4470 [(set (match_operand:X87MODEI 0 "register_operand" "")
4471 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4472 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4473 (clobber (match_scratch 3 ""))]
4475 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4476 (clobber (match_dup 3))])
4477 (set (match_dup 0) (match_dup 2))]
4481 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4482 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4483 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4484 (clobber (match_scratch 3 ""))]
4486 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4487 (clobber (match_dup 3))])]
4490 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4491 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4492 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4493 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4494 ;; function in i386.c.
4495 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4496 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4497 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4498 (clobber (reg:CC FLAGS_REG))]
4499 "TARGET_80387 && !TARGET_FISTTP
4500 && FLOAT_MODE_P (GET_MODE (operands[1]))
4501 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4502 && (TARGET_64BIT || <MODE>mode != DImode))
4503 && !(reload_completed || reload_in_progress)"
4508 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4510 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4511 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4512 if (memory_operand (operands[0], VOIDmode))
4513 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4514 operands[2], operands[3]));
4517 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4518 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4519 operands[2], operands[3],
4524 [(set_attr "type" "fistp")
4525 (set_attr "i387_cw" "trunc")
4526 (set_attr "mode" "<MODE>")])
4528 (define_insn "fix_truncdi_i387"
4529 [(set (match_operand:DI 0 "memory_operand" "=m")
4530 (fix:DI (match_operand 1 "register_operand" "f")))
4531 (use (match_operand:HI 2 "memory_operand" "m"))
4532 (use (match_operand:HI 3 "memory_operand" "m"))
4533 (clobber (match_scratch:XF 4 "=&1f"))]
4534 "TARGET_80387 && !TARGET_FISTTP
4535 && FLOAT_MODE_P (GET_MODE (operands[1]))
4536 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4537 "* return output_fix_trunc (insn, operands, 0);"
4538 [(set_attr "type" "fistp")
4539 (set_attr "i387_cw" "trunc")
4540 (set_attr "mode" "DI")])
4542 (define_insn "fix_truncdi_i387_with_temp"
4543 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4544 (fix:DI (match_operand 1 "register_operand" "f,f")))
4545 (use (match_operand:HI 2 "memory_operand" "m,m"))
4546 (use (match_operand:HI 3 "memory_operand" "m,m"))
4547 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4548 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4549 "TARGET_80387 && !TARGET_FISTTP
4550 && FLOAT_MODE_P (GET_MODE (operands[1]))
4551 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4553 [(set_attr "type" "fistp")
4554 (set_attr "i387_cw" "trunc")
4555 (set_attr "mode" "DI")])
4558 [(set (match_operand:DI 0 "register_operand" "")
4559 (fix:DI (match_operand 1 "register_operand" "")))
4560 (use (match_operand:HI 2 "memory_operand" ""))
4561 (use (match_operand:HI 3 "memory_operand" ""))
4562 (clobber (match_operand:DI 4 "memory_operand" ""))
4563 (clobber (match_scratch 5 ""))]
4565 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4568 (clobber (match_dup 5))])
4569 (set (match_dup 0) (match_dup 4))]
4573 [(set (match_operand:DI 0 "memory_operand" "")
4574 (fix:DI (match_operand 1 "register_operand" "")))
4575 (use (match_operand:HI 2 "memory_operand" ""))
4576 (use (match_operand:HI 3 "memory_operand" ""))
4577 (clobber (match_operand:DI 4 "memory_operand" ""))
4578 (clobber (match_scratch 5 ""))]
4580 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4583 (clobber (match_dup 5))])]
4586 (define_insn "fix_trunc<mode>_i387"
4587 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4588 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4589 (use (match_operand:HI 2 "memory_operand" "m"))
4590 (use (match_operand:HI 3 "memory_operand" "m"))]
4591 "TARGET_80387 && !TARGET_FISTTP
4592 && FLOAT_MODE_P (GET_MODE (operands[1]))
4593 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4594 "* return output_fix_trunc (insn, operands, 0);"
4595 [(set_attr "type" "fistp")
4596 (set_attr "i387_cw" "trunc")
4597 (set_attr "mode" "<MODE>")])
4599 (define_insn "fix_trunc<mode>_i387_with_temp"
4600 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4601 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4602 (use (match_operand:HI 2 "memory_operand" "m,m"))
4603 (use (match_operand:HI 3 "memory_operand" "m,m"))
4604 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4605 "TARGET_80387 && !TARGET_FISTTP
4606 && FLOAT_MODE_P (GET_MODE (operands[1]))
4607 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4609 [(set_attr "type" "fistp")
4610 (set_attr "i387_cw" "trunc")
4611 (set_attr "mode" "<MODE>")])
4614 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4615 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4616 (use (match_operand:HI 2 "memory_operand" ""))
4617 (use (match_operand:HI 3 "memory_operand" ""))
4618 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4620 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4622 (use (match_dup 3))])
4623 (set (match_dup 0) (match_dup 4))]
4627 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4628 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4629 (use (match_operand:HI 2 "memory_operand" ""))
4630 (use (match_operand:HI 3 "memory_operand" ""))
4631 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4633 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4635 (use (match_dup 3))])]
4638 (define_insn "x86_fnstcw_1"
4639 [(set (match_operand:HI 0 "memory_operand" "=m")
4640 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4643 [(set_attr "length" "2")
4644 (set_attr "mode" "HI")
4645 (set_attr "unit" "i387")])
4647 (define_insn "x86_fldcw_1"
4648 [(set (reg:HI FPCR_REG)
4649 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4652 [(set_attr "length" "2")
4653 (set_attr "mode" "HI")
4654 (set_attr "unit" "i387")
4655 (set_attr "athlon_decode" "vector")
4656 (set_attr "amdfam10_decode" "vector")])
4658 ;; Conversion between fixed point and floating point.
4660 ;; Even though we only accept memory inputs, the backend _really_
4661 ;; wants to be able to do this between registers.
4663 (define_expand "floathisf2"
4664 [(set (match_operand:SF 0 "register_operand" "")
4665 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4666 "TARGET_80387 || TARGET_SSE_MATH"
4668 if (TARGET_SSE_MATH)
4670 emit_insn (gen_floatsisf2 (operands[0],
4671 convert_to_mode (SImode, operands[1], 0)));
4676 (define_insn "*floathisf2_i387"
4677 [(set (match_operand:SF 0 "register_operand" "=f,f")
4678 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4679 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4683 [(set_attr "type" "fmov,multi")
4684 (set_attr "mode" "SF")
4685 (set_attr "unit" "*,i387")
4686 (set_attr "fp_int_src" "true")])
4688 (define_expand "floatsisf2"
4689 [(set (match_operand:SF 0 "register_operand" "")
4690 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4691 "TARGET_80387 || TARGET_SSE_MATH"
4694 (define_insn "*floatsisf2_mixed"
4695 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4696 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4697 "TARGET_MIX_SSE_I387"
4701 cvtsi2ss\t{%1, %0|%0, %1}
4702 cvtsi2ss\t{%1, %0|%0, %1}"
4703 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4704 (set_attr "mode" "SF")
4705 (set_attr "unit" "*,i387,*,*")
4706 (set_attr "athlon_decode" "*,*,vector,double")
4707 (set_attr "amdfam10_decode" "*,*,vector,double")
4708 (set_attr "fp_int_src" "true")])
4710 (define_insn "*floatsisf2_sse"
4711 [(set (match_operand:SF 0 "register_operand" "=x,x")
4712 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4714 "cvtsi2ss\t{%1, %0|%0, %1}"
4715 [(set_attr "type" "sseicvt")
4716 (set_attr "mode" "SF")
4717 (set_attr "athlon_decode" "vector,double")
4718 (set_attr "amdfam10_decode" "vector,double")
4719 (set_attr "fp_int_src" "true")])
4721 (define_insn "*floatsisf2_i387"
4722 [(set (match_operand:SF 0 "register_operand" "=f,f")
4723 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4728 [(set_attr "type" "fmov,multi")
4729 (set_attr "mode" "SF")
4730 (set_attr "unit" "*,i387")
4731 (set_attr "fp_int_src" "true")])
4733 (define_expand "floatdisf2"
4734 [(set (match_operand:SF 0 "register_operand" "")
4735 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4736 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4739 (define_insn "*floatdisf2_mixed"
4740 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4741 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4742 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4746 cvtsi2ss{q}\t{%1, %0|%0, %1}
4747 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4748 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4749 (set_attr "mode" "SF")
4750 (set_attr "unit" "*,i387,*,*")
4751 (set_attr "athlon_decode" "*,*,vector,double")
4752 (set_attr "amdfam10_decode" "*,*,vector,double")
4753 (set_attr "fp_int_src" "true")])
4755 (define_insn "*floatdisf2_sse"
4756 [(set (match_operand:SF 0 "register_operand" "=x,x")
4757 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4758 "TARGET_64BIT && TARGET_SSE_MATH"
4759 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4760 [(set_attr "type" "sseicvt")
4761 (set_attr "mode" "SF")
4762 (set_attr "athlon_decode" "vector,double")
4763 (set_attr "amdfam10_decode" "vector,double")
4764 (set_attr "fp_int_src" "true")])
4766 (define_insn "*floatdisf2_i387"
4767 [(set (match_operand:SF 0 "register_operand" "=f,f")
4768 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4773 [(set_attr "type" "fmov,multi")
4774 (set_attr "mode" "SF")
4775 (set_attr "unit" "*,i387")
4776 (set_attr "fp_int_src" "true")])
4778 (define_expand "floathidf2"
4779 [(set (match_operand:DF 0 "register_operand" "")
4780 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4781 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4783 if (TARGET_SSE2 && TARGET_SSE_MATH)
4785 emit_insn (gen_floatsidf2 (operands[0],
4786 convert_to_mode (SImode, operands[1], 0)));
4791 (define_insn "*floathidf2_i387"
4792 [(set (match_operand:DF 0 "register_operand" "=f,f")
4793 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4794 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4798 [(set_attr "type" "fmov,multi")
4799 (set_attr "mode" "DF")
4800 (set_attr "unit" "*,i387")
4801 (set_attr "fp_int_src" "true")])
4803 (define_expand "floatsidf2"
4804 [(set (match_operand:DF 0 "register_operand" "")
4805 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4806 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4809 (define_insn "*floatsidf2_mixed"
4810 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4811 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4812 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4816 cvtsi2sd\t{%1, %0|%0, %1}
4817 cvtsi2sd\t{%1, %0|%0, %1}"
4818 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4819 (set_attr "mode" "DF")
4820 (set_attr "unit" "*,i387,*,*")
4821 (set_attr "athlon_decode" "*,*,double,direct")
4822 (set_attr "amdfam10_decode" "*,*,vector,double")
4823 (set_attr "fp_int_src" "true")])
4825 (define_insn "*floatsidf2_sse"
4826 [(set (match_operand:DF 0 "register_operand" "=x,x")
4827 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4828 "TARGET_SSE2 && TARGET_SSE_MATH"
4829 "cvtsi2sd\t{%1, %0|%0, %1}"
4830 [(set_attr "type" "sseicvt")
4831 (set_attr "mode" "DF")
4832 (set_attr "athlon_decode" "double,direct")
4833 (set_attr "amdfam10_decode" "vector,double")
4834 (set_attr "fp_int_src" "true")])
4836 (define_insn "*floatsidf2_i387"
4837 [(set (match_operand:DF 0 "register_operand" "=f,f")
4838 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4843 [(set_attr "type" "fmov,multi")
4844 (set_attr "mode" "DF")
4845 (set_attr "unit" "*,i387")
4846 (set_attr "fp_int_src" "true")])
4848 (define_expand "floatdidf2"
4849 [(set (match_operand:DF 0 "register_operand" "")
4850 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4851 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4854 (define_insn "*floatdidf2_mixed"
4855 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4856 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4857 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4861 cvtsi2sd{q}\t{%1, %0|%0, %1}
4862 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4863 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4864 (set_attr "mode" "DF")
4865 (set_attr "unit" "*,i387,*,*")
4866 (set_attr "athlon_decode" "*,*,double,direct")
4867 (set_attr "amdfam10_decode" "*,*,vector,double")
4868 (set_attr "fp_int_src" "true")])
4870 (define_insn "*floatdidf2_sse"
4871 [(set (match_operand:DF 0 "register_operand" "=x,x")
4872 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4873 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4874 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4875 [(set_attr "type" "sseicvt")
4876 (set_attr "mode" "DF")
4877 (set_attr "athlon_decode" "double,direct")
4878 (set_attr "amdfam10_decode" "vector,double")
4879 (set_attr "fp_int_src" "true")])
4881 (define_insn "*floatdidf2_i387"
4882 [(set (match_operand:DF 0 "register_operand" "=f,f")
4883 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4888 [(set_attr "type" "fmov,multi")
4889 (set_attr "mode" "DF")
4890 (set_attr "unit" "*,i387")
4891 (set_attr "fp_int_src" "true")])
4893 (define_insn "floathixf2"
4894 [(set (match_operand:XF 0 "register_operand" "=f,f")
4895 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4900 [(set_attr "type" "fmov,multi")
4901 (set_attr "mode" "XF")
4902 (set_attr "unit" "*,i387")
4903 (set_attr "fp_int_src" "true")])
4905 (define_insn "floatsixf2"
4906 [(set (match_operand:XF 0 "register_operand" "=f,f")
4907 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4912 [(set_attr "type" "fmov,multi")
4913 (set_attr "mode" "XF")
4914 (set_attr "unit" "*,i387")
4915 (set_attr "fp_int_src" "true")])
4917 (define_insn "floatdixf2"
4918 [(set (match_operand:XF 0 "register_operand" "=f,f")
4919 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4924 [(set_attr "type" "fmov,multi")
4925 (set_attr "mode" "XF")
4926 (set_attr "unit" "*,i387")
4927 (set_attr "fp_int_src" "true")])
4929 ;; %%% Kill these when reload knows how to do it.
4931 [(set (match_operand 0 "fp_register_operand" "")
4932 (float (match_operand 1 "register_operand" "")))]
4935 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4938 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4939 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4940 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4941 ix86_free_from_memory (GET_MODE (operands[1]));
4945 (define_expand "floatunssisf2"
4946 [(use (match_operand:SF 0 "register_operand" ""))
4947 (use (match_operand:SI 1 "register_operand" ""))]
4948 "!TARGET_64BIT && TARGET_SSE_MATH"
4949 "x86_emit_floatuns (operands); DONE;")
4951 (define_expand "floatunsdisf2"
4952 [(use (match_operand:SF 0 "register_operand" ""))
4953 (use (match_operand:DI 1 "register_operand" ""))]
4954 "TARGET_64BIT && TARGET_SSE_MATH"
4955 "x86_emit_floatuns (operands); DONE;")
4957 (define_expand "floatunsdidf2"
4958 [(use (match_operand:DF 0 "register_operand" ""))
4959 (use (match_operand:DI 1 "register_operand" ""))]
4960 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4961 "x86_emit_floatuns (operands); DONE;")
4963 ;; SSE extract/set expanders
4968 ;; %%% splits for addditi3
4970 (define_expand "addti3"
4971 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4972 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4973 (match_operand:TI 2 "x86_64_general_operand" "")))
4974 (clobber (reg:CC FLAGS_REG))]
4976 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4978 (define_insn "*addti3_1"
4979 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4980 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4981 (match_operand:TI 2 "general_operand" "roiF,riF")))
4982 (clobber (reg:CC FLAGS_REG))]
4983 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4987 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4988 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4989 (match_operand:TI 2 "general_operand" "")))
4990 (clobber (reg:CC FLAGS_REG))]
4991 "TARGET_64BIT && reload_completed"
4992 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4994 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4995 (parallel [(set (match_dup 3)
4996 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4999 (clobber (reg:CC FLAGS_REG))])]
5000 "split_ti (operands+0, 1, operands+0, operands+3);
5001 split_ti (operands+1, 1, operands+1, operands+4);
5002 split_ti (operands+2, 1, operands+2, operands+5);")
5004 ;; %%% splits for addsidi3
5005 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5006 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5007 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5009 (define_expand "adddi3"
5010 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5011 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5012 (match_operand:DI 2 "x86_64_general_operand" "")))
5013 (clobber (reg:CC FLAGS_REG))]
5015 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5017 (define_insn "*adddi3_1"
5018 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5019 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5020 (match_operand:DI 2 "general_operand" "roiF,riF")))
5021 (clobber (reg:CC FLAGS_REG))]
5022 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5026 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5027 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5028 (match_operand:DI 2 "general_operand" "")))
5029 (clobber (reg:CC FLAGS_REG))]
5030 "!TARGET_64BIT && reload_completed"
5031 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5033 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5034 (parallel [(set (match_dup 3)
5035 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5038 (clobber (reg:CC FLAGS_REG))])]
5039 "split_di (operands+0, 1, operands+0, operands+3);
5040 split_di (operands+1, 1, operands+1, operands+4);
5041 split_di (operands+2, 1, operands+2, operands+5);")
5043 (define_insn "adddi3_carry_rex64"
5044 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5045 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5046 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5047 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5048 (clobber (reg:CC FLAGS_REG))]
5049 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5050 "adc{q}\t{%2, %0|%0, %2}"
5051 [(set_attr "type" "alu")
5052 (set_attr "pent_pair" "pu")
5053 (set_attr "mode" "DI")])
5055 (define_insn "*adddi3_cc_rex64"
5056 [(set (reg:CC FLAGS_REG)
5057 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5058 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5060 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5061 (plus:DI (match_dup 1) (match_dup 2)))]
5062 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5063 "add{q}\t{%2, %0|%0, %2}"
5064 [(set_attr "type" "alu")
5065 (set_attr "mode" "DI")])
5067 (define_insn "addqi3_carry"
5068 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5069 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5070 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5071 (match_operand:QI 2 "general_operand" "qi,qm")))
5072 (clobber (reg:CC FLAGS_REG))]
5073 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5074 "adc{b}\t{%2, %0|%0, %2}"
5075 [(set_attr "type" "alu")
5076 (set_attr "pent_pair" "pu")
5077 (set_attr "mode" "QI")])
5079 (define_insn "addhi3_carry"
5080 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5081 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5082 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5083 (match_operand:HI 2 "general_operand" "ri,rm")))
5084 (clobber (reg:CC FLAGS_REG))]
5085 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5086 "adc{w}\t{%2, %0|%0, %2}"
5087 [(set_attr "type" "alu")
5088 (set_attr "pent_pair" "pu")
5089 (set_attr "mode" "HI")])
5091 (define_insn "addsi3_carry"
5092 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5093 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5094 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5095 (match_operand:SI 2 "general_operand" "ri,rm")))
5096 (clobber (reg:CC FLAGS_REG))]
5097 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5098 "adc{l}\t{%2, %0|%0, %2}"
5099 [(set_attr "type" "alu")
5100 (set_attr "pent_pair" "pu")
5101 (set_attr "mode" "SI")])
5103 (define_insn "*addsi3_carry_zext"
5104 [(set (match_operand:DI 0 "register_operand" "=r")
5106 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5107 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5108 (match_operand:SI 2 "general_operand" "rim"))))
5109 (clobber (reg:CC FLAGS_REG))]
5110 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5111 "adc{l}\t{%2, %k0|%k0, %2}"
5112 [(set_attr "type" "alu")
5113 (set_attr "pent_pair" "pu")
5114 (set_attr "mode" "SI")])
5116 (define_insn "*addsi3_cc"
5117 [(set (reg:CC FLAGS_REG)
5118 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5119 (match_operand:SI 2 "general_operand" "ri,rm")]
5121 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5122 (plus:SI (match_dup 1) (match_dup 2)))]
5123 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5124 "add{l}\t{%2, %0|%0, %2}"
5125 [(set_attr "type" "alu")
5126 (set_attr "mode" "SI")])
5128 (define_insn "addqi3_cc"
5129 [(set (reg:CC FLAGS_REG)
5130 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5131 (match_operand:QI 2 "general_operand" "qi,qm")]
5133 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5134 (plus:QI (match_dup 1) (match_dup 2)))]
5135 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5136 "add{b}\t{%2, %0|%0, %2}"
5137 [(set_attr "type" "alu")
5138 (set_attr "mode" "QI")])
5140 (define_expand "addsi3"
5141 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5142 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5143 (match_operand:SI 2 "general_operand" "")))
5144 (clobber (reg:CC FLAGS_REG))])]
5146 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5148 (define_insn "*lea_1"
5149 [(set (match_operand:SI 0 "register_operand" "=r")
5150 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5152 "lea{l}\t{%a1, %0|%0, %a1}"
5153 [(set_attr "type" "lea")
5154 (set_attr "mode" "SI")])
5156 (define_insn "*lea_1_rex64"
5157 [(set (match_operand:SI 0 "register_operand" "=r")
5158 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5160 "lea{l}\t{%a1, %0|%0, %a1}"
5161 [(set_attr "type" "lea")
5162 (set_attr "mode" "SI")])
5164 (define_insn "*lea_1_zext"
5165 [(set (match_operand:DI 0 "register_operand" "=r")
5167 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5169 "lea{l}\t{%a1, %k0|%k0, %a1}"
5170 [(set_attr "type" "lea")
5171 (set_attr "mode" "SI")])
5173 (define_insn "*lea_2_rex64"
5174 [(set (match_operand:DI 0 "register_operand" "=r")
5175 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5177 "lea{q}\t{%a1, %0|%0, %a1}"
5178 [(set_attr "type" "lea")
5179 (set_attr "mode" "DI")])
5181 ;; The lea patterns for non-Pmodes needs to be matched by several
5182 ;; insns converted to real lea by splitters.
5184 (define_insn_and_split "*lea_general_1"
5185 [(set (match_operand 0 "register_operand" "=r")
5186 (plus (plus (match_operand 1 "index_register_operand" "l")
5187 (match_operand 2 "register_operand" "r"))
5188 (match_operand 3 "immediate_operand" "i")))]
5189 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5190 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5191 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5192 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5193 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5194 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5195 || GET_MODE (operands[3]) == VOIDmode)"
5197 "&& reload_completed"
5201 operands[0] = gen_lowpart (SImode, operands[0]);
5202 operands[1] = gen_lowpart (Pmode, operands[1]);
5203 operands[2] = gen_lowpart (Pmode, operands[2]);
5204 operands[3] = gen_lowpart (Pmode, operands[3]);
5205 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5207 if (Pmode != SImode)
5208 pat = gen_rtx_SUBREG (SImode, pat, 0);
5209 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5212 [(set_attr "type" "lea")
5213 (set_attr "mode" "SI")])
5215 (define_insn_and_split "*lea_general_1_zext"
5216 [(set (match_operand:DI 0 "register_operand" "=r")
5218 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5219 (match_operand:SI 2 "register_operand" "r"))
5220 (match_operand:SI 3 "immediate_operand" "i"))))]
5223 "&& reload_completed"
5225 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5227 (match_dup 3)) 0)))]
5229 operands[1] = gen_lowpart (Pmode, operands[1]);
5230 operands[2] = gen_lowpart (Pmode, operands[2]);
5231 operands[3] = gen_lowpart (Pmode, operands[3]);
5233 [(set_attr "type" "lea")
5234 (set_attr "mode" "SI")])
5236 (define_insn_and_split "*lea_general_2"
5237 [(set (match_operand 0 "register_operand" "=r")
5238 (plus (mult (match_operand 1 "index_register_operand" "l")
5239 (match_operand 2 "const248_operand" "i"))
5240 (match_operand 3 "nonmemory_operand" "ri")))]
5241 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5242 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5243 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5244 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5245 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5246 || GET_MODE (operands[3]) == VOIDmode)"
5248 "&& reload_completed"
5252 operands[0] = gen_lowpart (SImode, operands[0]);
5253 operands[1] = gen_lowpart (Pmode, operands[1]);
5254 operands[3] = gen_lowpart (Pmode, operands[3]);
5255 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5257 if (Pmode != SImode)
5258 pat = gen_rtx_SUBREG (SImode, pat, 0);
5259 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5262 [(set_attr "type" "lea")
5263 (set_attr "mode" "SI")])
5265 (define_insn_and_split "*lea_general_2_zext"
5266 [(set (match_operand:DI 0 "register_operand" "=r")
5268 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5269 (match_operand:SI 2 "const248_operand" "n"))
5270 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5273 "&& reload_completed"
5275 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5277 (match_dup 3)) 0)))]
5279 operands[1] = gen_lowpart (Pmode, operands[1]);
5280 operands[3] = gen_lowpart (Pmode, operands[3]);
5282 [(set_attr "type" "lea")
5283 (set_attr "mode" "SI")])
5285 (define_insn_and_split "*lea_general_3"
5286 [(set (match_operand 0 "register_operand" "=r")
5287 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5288 (match_operand 2 "const248_operand" "i"))
5289 (match_operand 3 "register_operand" "r"))
5290 (match_operand 4 "immediate_operand" "i")))]
5291 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5292 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5293 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5294 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5295 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5297 "&& reload_completed"
5301 operands[0] = gen_lowpart (SImode, operands[0]);
5302 operands[1] = gen_lowpart (Pmode, operands[1]);
5303 operands[3] = gen_lowpart (Pmode, operands[3]);
5304 operands[4] = gen_lowpart (Pmode, operands[4]);
5305 pat = gen_rtx_PLUS (Pmode,
5306 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5310 if (Pmode != SImode)
5311 pat = gen_rtx_SUBREG (SImode, pat, 0);
5312 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5315 [(set_attr "type" "lea")
5316 (set_attr "mode" "SI")])
5318 (define_insn_and_split "*lea_general_3_zext"
5319 [(set (match_operand:DI 0 "register_operand" "=r")
5321 (plus:SI (plus:SI (mult:SI
5322 (match_operand:SI 1 "index_register_operand" "l")
5323 (match_operand:SI 2 "const248_operand" "n"))
5324 (match_operand:SI 3 "register_operand" "r"))
5325 (match_operand:SI 4 "immediate_operand" "i"))))]
5328 "&& reload_completed"
5330 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5333 (match_dup 4)) 0)))]
5335 operands[1] = gen_lowpart (Pmode, operands[1]);
5336 operands[3] = gen_lowpart (Pmode, operands[3]);
5337 operands[4] = gen_lowpart (Pmode, operands[4]);
5339 [(set_attr "type" "lea")
5340 (set_attr "mode" "SI")])
5342 (define_insn "*adddi_1_rex64"
5343 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5344 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5345 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5346 (clobber (reg:CC FLAGS_REG))]
5347 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5349 switch (get_attr_type (insn))
5352 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5353 return "lea{q}\t{%a2, %0|%0, %a2}";
5356 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5357 if (operands[2] == const1_rtx)
5358 return "inc{q}\t%0";
5361 gcc_assert (operands[2] == constm1_rtx);
5362 return "dec{q}\t%0";
5366 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5368 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5369 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5370 if (CONST_INT_P (operands[2])
5371 /* Avoid overflows. */
5372 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5373 && (INTVAL (operands[2]) == 128
5374 || (INTVAL (operands[2]) < 0
5375 && INTVAL (operands[2]) != -128)))
5377 operands[2] = GEN_INT (-INTVAL (operands[2]));
5378 return "sub{q}\t{%2, %0|%0, %2}";
5380 return "add{q}\t{%2, %0|%0, %2}";
5384 (cond [(eq_attr "alternative" "2")
5385 (const_string "lea")
5386 ; Current assemblers are broken and do not allow @GOTOFF in
5387 ; ought but a memory context.
5388 (match_operand:DI 2 "pic_symbolic_operand" "")
5389 (const_string "lea")
5390 (match_operand:DI 2 "incdec_operand" "")
5391 (const_string "incdec")
5393 (const_string "alu")))
5394 (set_attr "mode" "DI")])
5396 ;; Convert lea to the lea pattern to avoid flags dependency.
5398 [(set (match_operand:DI 0 "register_operand" "")
5399 (plus:DI (match_operand:DI 1 "register_operand" "")
5400 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5401 (clobber (reg:CC FLAGS_REG))]
5402 "TARGET_64BIT && reload_completed
5403 && true_regnum (operands[0]) != true_regnum (operands[1])"
5405 (plus:DI (match_dup 1)
5409 (define_insn "*adddi_2_rex64"
5410 [(set (reg FLAGS_REG)
5412 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5413 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5415 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5416 (plus:DI (match_dup 1) (match_dup 2)))]
5417 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5418 && ix86_binary_operator_ok (PLUS, DImode, operands)
5419 /* Current assemblers are broken and do not allow @GOTOFF in
5420 ought but a memory context. */
5421 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5423 switch (get_attr_type (insn))
5426 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5427 if (operands[2] == const1_rtx)
5428 return "inc{q}\t%0";
5431 gcc_assert (operands[2] == constm1_rtx);
5432 return "dec{q}\t%0";
5436 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5437 /* ???? We ought to handle there the 32bit case too
5438 - do we need new constraint? */
5439 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5440 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5441 if (CONST_INT_P (operands[2])
5442 /* Avoid overflows. */
5443 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5444 && (INTVAL (operands[2]) == 128
5445 || (INTVAL (operands[2]) < 0
5446 && INTVAL (operands[2]) != -128)))
5448 operands[2] = GEN_INT (-INTVAL (operands[2]));
5449 return "sub{q}\t{%2, %0|%0, %2}";
5451 return "add{q}\t{%2, %0|%0, %2}";
5455 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5456 (const_string "incdec")
5457 (const_string "alu")))
5458 (set_attr "mode" "DI")])
5460 (define_insn "*adddi_3_rex64"
5461 [(set (reg FLAGS_REG)
5462 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5463 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5464 (clobber (match_scratch:DI 0 "=r"))]
5466 && ix86_match_ccmode (insn, CCZmode)
5467 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5468 /* Current assemblers are broken and do not allow @GOTOFF in
5469 ought but a memory context. */
5470 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5472 switch (get_attr_type (insn))
5475 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5476 if (operands[2] == const1_rtx)
5477 return "inc{q}\t%0";
5480 gcc_assert (operands[2] == constm1_rtx);
5481 return "dec{q}\t%0";
5485 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5486 /* ???? We ought to handle there the 32bit case too
5487 - do we need new constraint? */
5488 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5489 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5490 if (CONST_INT_P (operands[2])
5491 /* Avoid overflows. */
5492 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5493 && (INTVAL (operands[2]) == 128
5494 || (INTVAL (operands[2]) < 0
5495 && INTVAL (operands[2]) != -128)))
5497 operands[2] = GEN_INT (-INTVAL (operands[2]));
5498 return "sub{q}\t{%2, %0|%0, %2}";
5500 return "add{q}\t{%2, %0|%0, %2}";
5504 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5505 (const_string "incdec")
5506 (const_string "alu")))
5507 (set_attr "mode" "DI")])
5509 ; For comparisons against 1, -1 and 128, we may generate better code
5510 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5511 ; is matched then. We can't accept general immediate, because for
5512 ; case of overflows, the result is messed up.
5513 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5515 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5516 ; only for comparisons not depending on it.
5517 (define_insn "*adddi_4_rex64"
5518 [(set (reg FLAGS_REG)
5519 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5520 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5521 (clobber (match_scratch:DI 0 "=rm"))]
5523 && ix86_match_ccmode (insn, CCGCmode)"
5525 switch (get_attr_type (insn))
5528 if (operands[2] == constm1_rtx)
5529 return "inc{q}\t%0";
5532 gcc_assert (operands[2] == const1_rtx);
5533 return "dec{q}\t%0";
5537 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5538 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5539 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5540 if ((INTVAL (operands[2]) == -128
5541 || (INTVAL (operands[2]) > 0
5542 && INTVAL (operands[2]) != 128))
5543 /* Avoid overflows. */
5544 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5545 return "sub{q}\t{%2, %0|%0, %2}";
5546 operands[2] = GEN_INT (-INTVAL (operands[2]));
5547 return "add{q}\t{%2, %0|%0, %2}";
5551 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5552 (const_string "incdec")
5553 (const_string "alu")))
5554 (set_attr "mode" "DI")])
5556 (define_insn "*adddi_5_rex64"
5557 [(set (reg FLAGS_REG)
5559 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5560 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5562 (clobber (match_scratch:DI 0 "=r"))]
5564 && ix86_match_ccmode (insn, CCGOCmode)
5565 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5566 /* Current assemblers are broken and do not allow @GOTOFF in
5567 ought but a memory context. */
5568 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5570 switch (get_attr_type (insn))
5573 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5574 if (operands[2] == const1_rtx)
5575 return "inc{q}\t%0";
5578 gcc_assert (operands[2] == constm1_rtx);
5579 return "dec{q}\t%0";
5583 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5584 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5585 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5586 if (CONST_INT_P (operands[2])
5587 /* Avoid overflows. */
5588 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5589 && (INTVAL (operands[2]) == 128
5590 || (INTVAL (operands[2]) < 0
5591 && INTVAL (operands[2]) != -128)))
5593 operands[2] = GEN_INT (-INTVAL (operands[2]));
5594 return "sub{q}\t{%2, %0|%0, %2}";
5596 return "add{q}\t{%2, %0|%0, %2}";
5600 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5601 (const_string "incdec")
5602 (const_string "alu")))
5603 (set_attr "mode" "DI")])
5606 (define_insn "*addsi_1"
5607 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5608 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5609 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5610 (clobber (reg:CC FLAGS_REG))]
5611 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5613 switch (get_attr_type (insn))
5616 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5617 return "lea{l}\t{%a2, %0|%0, %a2}";
5620 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5621 if (operands[2] == const1_rtx)
5622 return "inc{l}\t%0";
5625 gcc_assert (operands[2] == constm1_rtx);
5626 return "dec{l}\t%0";
5630 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5632 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5633 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5634 if (CONST_INT_P (operands[2])
5635 && (INTVAL (operands[2]) == 128
5636 || (INTVAL (operands[2]) < 0
5637 && INTVAL (operands[2]) != -128)))
5639 operands[2] = GEN_INT (-INTVAL (operands[2]));
5640 return "sub{l}\t{%2, %0|%0, %2}";
5642 return "add{l}\t{%2, %0|%0, %2}";
5646 (cond [(eq_attr "alternative" "2")
5647 (const_string "lea")
5648 ; Current assemblers are broken and do not allow @GOTOFF in
5649 ; ought but a memory context.
5650 (match_operand:SI 2 "pic_symbolic_operand" "")
5651 (const_string "lea")
5652 (match_operand:SI 2 "incdec_operand" "")
5653 (const_string "incdec")
5655 (const_string "alu")))
5656 (set_attr "mode" "SI")])
5658 ;; Convert lea to the lea pattern to avoid flags dependency.
5660 [(set (match_operand 0 "register_operand" "")
5661 (plus (match_operand 1 "register_operand" "")
5662 (match_operand 2 "nonmemory_operand" "")))
5663 (clobber (reg:CC FLAGS_REG))]
5665 && true_regnum (operands[0]) != true_regnum (operands[1])"
5669 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5670 may confuse gen_lowpart. */
5671 if (GET_MODE (operands[0]) != Pmode)
5673 operands[1] = gen_lowpart (Pmode, operands[1]);
5674 operands[2] = gen_lowpart (Pmode, operands[2]);
5676 operands[0] = gen_lowpart (SImode, operands[0]);
5677 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5678 if (Pmode != SImode)
5679 pat = gen_rtx_SUBREG (SImode, pat, 0);
5680 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5684 ;; It may seem that nonimmediate operand is proper one for operand 1.
5685 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5686 ;; we take care in ix86_binary_operator_ok to not allow two memory
5687 ;; operands so proper swapping will be done in reload. This allow
5688 ;; patterns constructed from addsi_1 to match.
5689 (define_insn "addsi_1_zext"
5690 [(set (match_operand:DI 0 "register_operand" "=r,r")
5692 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5693 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5694 (clobber (reg:CC FLAGS_REG))]
5695 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5697 switch (get_attr_type (insn))
5700 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5701 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5704 if (operands[2] == const1_rtx)
5705 return "inc{l}\t%k0";
5708 gcc_assert (operands[2] == constm1_rtx);
5709 return "dec{l}\t%k0";
5713 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5714 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5715 if (CONST_INT_P (operands[2])
5716 && (INTVAL (operands[2]) == 128
5717 || (INTVAL (operands[2]) < 0
5718 && INTVAL (operands[2]) != -128)))
5720 operands[2] = GEN_INT (-INTVAL (operands[2]));
5721 return "sub{l}\t{%2, %k0|%k0, %2}";
5723 return "add{l}\t{%2, %k0|%k0, %2}";
5727 (cond [(eq_attr "alternative" "1")
5728 (const_string "lea")
5729 ; Current assemblers are broken and do not allow @GOTOFF in
5730 ; ought but a memory context.
5731 (match_operand:SI 2 "pic_symbolic_operand" "")
5732 (const_string "lea")
5733 (match_operand:SI 2 "incdec_operand" "")
5734 (const_string "incdec")
5736 (const_string "alu")))
5737 (set_attr "mode" "SI")])
5739 ;; Convert lea to the lea pattern to avoid flags dependency.
5741 [(set (match_operand:DI 0 "register_operand" "")
5743 (plus:SI (match_operand:SI 1 "register_operand" "")
5744 (match_operand:SI 2 "nonmemory_operand" ""))))
5745 (clobber (reg:CC FLAGS_REG))]
5746 "TARGET_64BIT && reload_completed
5747 && true_regnum (operands[0]) != true_regnum (operands[1])"
5749 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5751 operands[1] = gen_lowpart (Pmode, operands[1]);
5752 operands[2] = gen_lowpart (Pmode, operands[2]);
5755 (define_insn "*addsi_2"
5756 [(set (reg FLAGS_REG)
5758 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5759 (match_operand:SI 2 "general_operand" "rmni,rni"))
5761 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5762 (plus:SI (match_dup 1) (match_dup 2)))]
5763 "ix86_match_ccmode (insn, CCGOCmode)
5764 && ix86_binary_operator_ok (PLUS, SImode, operands)
5765 /* Current assemblers are broken and do not allow @GOTOFF in
5766 ought but a memory context. */
5767 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5769 switch (get_attr_type (insn))
5772 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5773 if (operands[2] == const1_rtx)
5774 return "inc{l}\t%0";
5777 gcc_assert (operands[2] == constm1_rtx);
5778 return "dec{l}\t%0";
5782 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5783 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5784 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5785 if (CONST_INT_P (operands[2])
5786 && (INTVAL (operands[2]) == 128
5787 || (INTVAL (operands[2]) < 0
5788 && INTVAL (operands[2]) != -128)))
5790 operands[2] = GEN_INT (-INTVAL (operands[2]));
5791 return "sub{l}\t{%2, %0|%0, %2}";
5793 return "add{l}\t{%2, %0|%0, %2}";
5797 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5798 (const_string "incdec")
5799 (const_string "alu")))
5800 (set_attr "mode" "SI")])
5802 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5803 (define_insn "*addsi_2_zext"
5804 [(set (reg FLAGS_REG)
5806 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5807 (match_operand:SI 2 "general_operand" "rmni"))
5809 (set (match_operand:DI 0 "register_operand" "=r")
5810 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5811 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5812 && ix86_binary_operator_ok (PLUS, SImode, operands)
5813 /* Current assemblers are broken and do not allow @GOTOFF in
5814 ought but a memory context. */
5815 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5817 switch (get_attr_type (insn))
5820 if (operands[2] == const1_rtx)
5821 return "inc{l}\t%k0";
5824 gcc_assert (operands[2] == constm1_rtx);
5825 return "dec{l}\t%k0";
5829 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5830 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5831 if (CONST_INT_P (operands[2])
5832 && (INTVAL (operands[2]) == 128
5833 || (INTVAL (operands[2]) < 0
5834 && INTVAL (operands[2]) != -128)))
5836 operands[2] = GEN_INT (-INTVAL (operands[2]));
5837 return "sub{l}\t{%2, %k0|%k0, %2}";
5839 return "add{l}\t{%2, %k0|%k0, %2}";
5843 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5844 (const_string "incdec")
5845 (const_string "alu")))
5846 (set_attr "mode" "SI")])
5848 (define_insn "*addsi_3"
5849 [(set (reg FLAGS_REG)
5850 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5851 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5852 (clobber (match_scratch:SI 0 "=r"))]
5853 "ix86_match_ccmode (insn, CCZmode)
5854 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5855 /* Current assemblers are broken and do not allow @GOTOFF in
5856 ought but a memory context. */
5857 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5859 switch (get_attr_type (insn))
5862 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5863 if (operands[2] == const1_rtx)
5864 return "inc{l}\t%0";
5867 gcc_assert (operands[2] == constm1_rtx);
5868 return "dec{l}\t%0";
5872 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5873 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5875 if (CONST_INT_P (operands[2])
5876 && (INTVAL (operands[2]) == 128
5877 || (INTVAL (operands[2]) < 0
5878 && INTVAL (operands[2]) != -128)))
5880 operands[2] = GEN_INT (-INTVAL (operands[2]));
5881 return "sub{l}\t{%2, %0|%0, %2}";
5883 return "add{l}\t{%2, %0|%0, %2}";
5887 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5888 (const_string "incdec")
5889 (const_string "alu")))
5890 (set_attr "mode" "SI")])
5892 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5893 (define_insn "*addsi_3_zext"
5894 [(set (reg FLAGS_REG)
5895 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5896 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5897 (set (match_operand:DI 0 "register_operand" "=r")
5898 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5899 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5900 && ix86_binary_operator_ok (PLUS, SImode, operands)
5901 /* Current assemblers are broken and do not allow @GOTOFF in
5902 ought but a memory context. */
5903 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5905 switch (get_attr_type (insn))
5908 if (operands[2] == const1_rtx)
5909 return "inc{l}\t%k0";
5912 gcc_assert (operands[2] == constm1_rtx);
5913 return "dec{l}\t%k0";
5917 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5918 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5919 if (CONST_INT_P (operands[2])
5920 && (INTVAL (operands[2]) == 128
5921 || (INTVAL (operands[2]) < 0
5922 && INTVAL (operands[2]) != -128)))
5924 operands[2] = GEN_INT (-INTVAL (operands[2]));
5925 return "sub{l}\t{%2, %k0|%k0, %2}";
5927 return "add{l}\t{%2, %k0|%k0, %2}";
5931 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5932 (const_string "incdec")
5933 (const_string "alu")))
5934 (set_attr "mode" "SI")])
5936 ; For comparisons against 1, -1 and 128, we may generate better code
5937 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5938 ; is matched then. We can't accept general immediate, because for
5939 ; case of overflows, the result is messed up.
5940 ; This pattern also don't hold of 0x80000000, since the value overflows
5942 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5943 ; only for comparisons not depending on it.
5944 (define_insn "*addsi_4"
5945 [(set (reg FLAGS_REG)
5946 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5947 (match_operand:SI 2 "const_int_operand" "n")))
5948 (clobber (match_scratch:SI 0 "=rm"))]
5949 "ix86_match_ccmode (insn, CCGCmode)
5950 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5952 switch (get_attr_type (insn))
5955 if (operands[2] == constm1_rtx)
5956 return "inc{l}\t%0";
5959 gcc_assert (operands[2] == const1_rtx);
5960 return "dec{l}\t%0";
5964 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5965 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5966 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5967 if ((INTVAL (operands[2]) == -128
5968 || (INTVAL (operands[2]) > 0
5969 && INTVAL (operands[2]) != 128)))
5970 return "sub{l}\t{%2, %0|%0, %2}";
5971 operands[2] = GEN_INT (-INTVAL (operands[2]));
5972 return "add{l}\t{%2, %0|%0, %2}";
5976 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5977 (const_string "incdec")
5978 (const_string "alu")))
5979 (set_attr "mode" "SI")])
5981 (define_insn "*addsi_5"
5982 [(set (reg FLAGS_REG)
5984 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5985 (match_operand:SI 2 "general_operand" "rmni"))
5987 (clobber (match_scratch:SI 0 "=r"))]
5988 "ix86_match_ccmode (insn, CCGOCmode)
5989 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5990 /* Current assemblers are broken and do not allow @GOTOFF in
5991 ought but a memory context. */
5992 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5994 switch (get_attr_type (insn))
5997 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5998 if (operands[2] == const1_rtx)
5999 return "inc{l}\t%0";
6002 gcc_assert (operands[2] == constm1_rtx);
6003 return "dec{l}\t%0";
6007 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6008 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6009 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6010 if (CONST_INT_P (operands[2])
6011 && (INTVAL (operands[2]) == 128
6012 || (INTVAL (operands[2]) < 0
6013 && INTVAL (operands[2]) != -128)))
6015 operands[2] = GEN_INT (-INTVAL (operands[2]));
6016 return "sub{l}\t{%2, %0|%0, %2}";
6018 return "add{l}\t{%2, %0|%0, %2}";
6022 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6023 (const_string "incdec")
6024 (const_string "alu")))
6025 (set_attr "mode" "SI")])
6027 (define_expand "addhi3"
6028 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6029 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6030 (match_operand:HI 2 "general_operand" "")))
6031 (clobber (reg:CC FLAGS_REG))])]
6032 "TARGET_HIMODE_MATH"
6033 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6035 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6036 ;; type optimizations enabled by define-splits. This is not important
6037 ;; for PII, and in fact harmful because of partial register stalls.
6039 (define_insn "*addhi_1_lea"
6040 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6041 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6042 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6043 (clobber (reg:CC FLAGS_REG))]
6044 "!TARGET_PARTIAL_REG_STALL
6045 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6047 switch (get_attr_type (insn))
6052 if (operands[2] == const1_rtx)
6053 return "inc{w}\t%0";
6056 gcc_assert (operands[2] == constm1_rtx);
6057 return "dec{w}\t%0";
6061 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6062 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6063 if (CONST_INT_P (operands[2])
6064 && (INTVAL (operands[2]) == 128
6065 || (INTVAL (operands[2]) < 0
6066 && INTVAL (operands[2]) != -128)))
6068 operands[2] = GEN_INT (-INTVAL (operands[2]));
6069 return "sub{w}\t{%2, %0|%0, %2}";
6071 return "add{w}\t{%2, %0|%0, %2}";
6075 (if_then_else (eq_attr "alternative" "2")
6076 (const_string "lea")
6077 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6078 (const_string "incdec")
6079 (const_string "alu"))))
6080 (set_attr "mode" "HI,HI,SI")])
6082 (define_insn "*addhi_1"
6083 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6084 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6085 (match_operand:HI 2 "general_operand" "ri,rm")))
6086 (clobber (reg:CC FLAGS_REG))]
6087 "TARGET_PARTIAL_REG_STALL
6088 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6090 switch (get_attr_type (insn))
6093 if (operands[2] == const1_rtx)
6094 return "inc{w}\t%0";
6097 gcc_assert (operands[2] == constm1_rtx);
6098 return "dec{w}\t%0";
6102 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6103 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6104 if (CONST_INT_P (operands[2])
6105 && (INTVAL (operands[2]) == 128
6106 || (INTVAL (operands[2]) < 0
6107 && INTVAL (operands[2]) != -128)))
6109 operands[2] = GEN_INT (-INTVAL (operands[2]));
6110 return "sub{w}\t{%2, %0|%0, %2}";
6112 return "add{w}\t{%2, %0|%0, %2}";
6116 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6117 (const_string "incdec")
6118 (const_string "alu")))
6119 (set_attr "mode" "HI")])
6121 (define_insn "*addhi_2"
6122 [(set (reg FLAGS_REG)
6124 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6125 (match_operand:HI 2 "general_operand" "rmni,rni"))
6127 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6128 (plus:HI (match_dup 1) (match_dup 2)))]
6129 "ix86_match_ccmode (insn, CCGOCmode)
6130 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6132 switch (get_attr_type (insn))
6135 if (operands[2] == const1_rtx)
6136 return "inc{w}\t%0";
6139 gcc_assert (operands[2] == constm1_rtx);
6140 return "dec{w}\t%0";
6144 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6145 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6146 if (CONST_INT_P (operands[2])
6147 && (INTVAL (operands[2]) == 128
6148 || (INTVAL (operands[2]) < 0
6149 && INTVAL (operands[2]) != -128)))
6151 operands[2] = GEN_INT (-INTVAL (operands[2]));
6152 return "sub{w}\t{%2, %0|%0, %2}";
6154 return "add{w}\t{%2, %0|%0, %2}";
6158 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6159 (const_string "incdec")
6160 (const_string "alu")))
6161 (set_attr "mode" "HI")])
6163 (define_insn "*addhi_3"
6164 [(set (reg FLAGS_REG)
6165 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6166 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6167 (clobber (match_scratch:HI 0 "=r"))]
6168 "ix86_match_ccmode (insn, CCZmode)
6169 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6171 switch (get_attr_type (insn))
6174 if (operands[2] == const1_rtx)
6175 return "inc{w}\t%0";
6178 gcc_assert (operands[2] == constm1_rtx);
6179 return "dec{w}\t%0";
6183 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6184 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6185 if (CONST_INT_P (operands[2])
6186 && (INTVAL (operands[2]) == 128
6187 || (INTVAL (operands[2]) < 0
6188 && INTVAL (operands[2]) != -128)))
6190 operands[2] = GEN_INT (-INTVAL (operands[2]));
6191 return "sub{w}\t{%2, %0|%0, %2}";
6193 return "add{w}\t{%2, %0|%0, %2}";
6197 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6198 (const_string "incdec")
6199 (const_string "alu")))
6200 (set_attr "mode" "HI")])
6202 ; See comments above addsi_4 for details.
6203 (define_insn "*addhi_4"
6204 [(set (reg FLAGS_REG)
6205 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6206 (match_operand:HI 2 "const_int_operand" "n")))
6207 (clobber (match_scratch:HI 0 "=rm"))]
6208 "ix86_match_ccmode (insn, CCGCmode)
6209 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6211 switch (get_attr_type (insn))
6214 if (operands[2] == constm1_rtx)
6215 return "inc{w}\t%0";
6218 gcc_assert (operands[2] == const1_rtx);
6219 return "dec{w}\t%0";
6223 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6224 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6225 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6226 if ((INTVAL (operands[2]) == -128
6227 || (INTVAL (operands[2]) > 0
6228 && INTVAL (operands[2]) != 128)))
6229 return "sub{w}\t{%2, %0|%0, %2}";
6230 operands[2] = GEN_INT (-INTVAL (operands[2]));
6231 return "add{w}\t{%2, %0|%0, %2}";
6235 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6236 (const_string "incdec")
6237 (const_string "alu")))
6238 (set_attr "mode" "SI")])
6241 (define_insn "*addhi_5"
6242 [(set (reg FLAGS_REG)
6244 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6245 (match_operand:HI 2 "general_operand" "rmni"))
6247 (clobber (match_scratch:HI 0 "=r"))]
6248 "ix86_match_ccmode (insn, CCGOCmode)
6249 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6251 switch (get_attr_type (insn))
6254 if (operands[2] == const1_rtx)
6255 return "inc{w}\t%0";
6258 gcc_assert (operands[2] == constm1_rtx);
6259 return "dec{w}\t%0";
6263 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6264 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6265 if (CONST_INT_P (operands[2])
6266 && (INTVAL (operands[2]) == 128
6267 || (INTVAL (operands[2]) < 0
6268 && INTVAL (operands[2]) != -128)))
6270 operands[2] = GEN_INT (-INTVAL (operands[2]));
6271 return "sub{w}\t{%2, %0|%0, %2}";
6273 return "add{w}\t{%2, %0|%0, %2}";
6277 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6278 (const_string "incdec")
6279 (const_string "alu")))
6280 (set_attr "mode" "HI")])
6282 (define_expand "addqi3"
6283 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6284 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6285 (match_operand:QI 2 "general_operand" "")))
6286 (clobber (reg:CC FLAGS_REG))])]
6287 "TARGET_QIMODE_MATH"
6288 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6290 ;; %%% Potential partial reg stall on alternative 2. What to do?
6291 (define_insn "*addqi_1_lea"
6292 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6293 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6294 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6295 (clobber (reg:CC FLAGS_REG))]
6296 "!TARGET_PARTIAL_REG_STALL
6297 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6299 int widen = (which_alternative == 2);
6300 switch (get_attr_type (insn))
6305 if (operands[2] == const1_rtx)
6306 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6309 gcc_assert (operands[2] == constm1_rtx);
6310 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6314 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6315 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6316 if (CONST_INT_P (operands[2])
6317 && (INTVAL (operands[2]) == 128
6318 || (INTVAL (operands[2]) < 0
6319 && INTVAL (operands[2]) != -128)))
6321 operands[2] = GEN_INT (-INTVAL (operands[2]));
6323 return "sub{l}\t{%2, %k0|%k0, %2}";
6325 return "sub{b}\t{%2, %0|%0, %2}";
6328 return "add{l}\t{%k2, %k0|%k0, %k2}";
6330 return "add{b}\t{%2, %0|%0, %2}";
6334 (if_then_else (eq_attr "alternative" "3")
6335 (const_string "lea")
6336 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6337 (const_string "incdec")
6338 (const_string "alu"))))
6339 (set_attr "mode" "QI,QI,SI,SI")])
6341 (define_insn "*addqi_1"
6342 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6343 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6344 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6345 (clobber (reg:CC FLAGS_REG))]
6346 "TARGET_PARTIAL_REG_STALL
6347 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6349 int widen = (which_alternative == 2);
6350 switch (get_attr_type (insn))
6353 if (operands[2] == const1_rtx)
6354 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6357 gcc_assert (operands[2] == constm1_rtx);
6358 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6362 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6363 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6364 if (CONST_INT_P (operands[2])
6365 && (INTVAL (operands[2]) == 128
6366 || (INTVAL (operands[2]) < 0
6367 && INTVAL (operands[2]) != -128)))
6369 operands[2] = GEN_INT (-INTVAL (operands[2]));
6371 return "sub{l}\t{%2, %k0|%k0, %2}";
6373 return "sub{b}\t{%2, %0|%0, %2}";
6376 return "add{l}\t{%k2, %k0|%k0, %k2}";
6378 return "add{b}\t{%2, %0|%0, %2}";
6382 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6383 (const_string "incdec")
6384 (const_string "alu")))
6385 (set_attr "mode" "QI,QI,SI")])
6387 (define_insn "*addqi_1_slp"
6388 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6389 (plus:QI (match_dup 0)
6390 (match_operand:QI 1 "general_operand" "qn,qnm")))
6391 (clobber (reg:CC FLAGS_REG))]
6392 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6393 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6395 switch (get_attr_type (insn))
6398 if (operands[1] == const1_rtx)
6399 return "inc{b}\t%0";
6402 gcc_assert (operands[1] == constm1_rtx);
6403 return "dec{b}\t%0";
6407 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6408 if (CONST_INT_P (operands[1])
6409 && INTVAL (operands[1]) < 0)
6411 operands[1] = GEN_INT (-INTVAL (operands[1]));
6412 return "sub{b}\t{%1, %0|%0, %1}";
6414 return "add{b}\t{%1, %0|%0, %1}";
6418 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6419 (const_string "incdec")
6420 (const_string "alu1")))
6421 (set (attr "memory")
6422 (if_then_else (match_operand 1 "memory_operand" "")
6423 (const_string "load")
6424 (const_string "none")))
6425 (set_attr "mode" "QI")])
6427 (define_insn "*addqi_2"
6428 [(set (reg FLAGS_REG)
6430 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6431 (match_operand:QI 2 "general_operand" "qmni,qni"))
6433 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6434 (plus:QI (match_dup 1) (match_dup 2)))]
6435 "ix86_match_ccmode (insn, CCGOCmode)
6436 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6438 switch (get_attr_type (insn))
6441 if (operands[2] == const1_rtx)
6442 return "inc{b}\t%0";
6445 gcc_assert (operands[2] == constm1_rtx
6446 || (CONST_INT_P (operands[2])
6447 && INTVAL (operands[2]) == 255));
6448 return "dec{b}\t%0";
6452 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6453 if (CONST_INT_P (operands[2])
6454 && INTVAL (operands[2]) < 0)
6456 operands[2] = GEN_INT (-INTVAL (operands[2]));
6457 return "sub{b}\t{%2, %0|%0, %2}";
6459 return "add{b}\t{%2, %0|%0, %2}";
6463 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6464 (const_string "incdec")
6465 (const_string "alu")))
6466 (set_attr "mode" "QI")])
6468 (define_insn "*addqi_3"
6469 [(set (reg FLAGS_REG)
6470 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6471 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6472 (clobber (match_scratch:QI 0 "=q"))]
6473 "ix86_match_ccmode (insn, CCZmode)
6474 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6476 switch (get_attr_type (insn))
6479 if (operands[2] == const1_rtx)
6480 return "inc{b}\t%0";
6483 gcc_assert (operands[2] == constm1_rtx
6484 || (CONST_INT_P (operands[2])
6485 && INTVAL (operands[2]) == 255));
6486 return "dec{b}\t%0";
6490 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6491 if (CONST_INT_P (operands[2])
6492 && INTVAL (operands[2]) < 0)
6494 operands[2] = GEN_INT (-INTVAL (operands[2]));
6495 return "sub{b}\t{%2, %0|%0, %2}";
6497 return "add{b}\t{%2, %0|%0, %2}";
6501 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6502 (const_string "incdec")
6503 (const_string "alu")))
6504 (set_attr "mode" "QI")])
6506 ; See comments above addsi_4 for details.
6507 (define_insn "*addqi_4"
6508 [(set (reg FLAGS_REG)
6509 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6510 (match_operand:QI 2 "const_int_operand" "n")))
6511 (clobber (match_scratch:QI 0 "=qm"))]
6512 "ix86_match_ccmode (insn, CCGCmode)
6513 && (INTVAL (operands[2]) & 0xff) != 0x80"
6515 switch (get_attr_type (insn))
6518 if (operands[2] == constm1_rtx
6519 || (CONST_INT_P (operands[2])
6520 && INTVAL (operands[2]) == 255))
6521 return "inc{b}\t%0";
6524 gcc_assert (operands[2] == const1_rtx);
6525 return "dec{b}\t%0";
6529 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6530 if (INTVAL (operands[2]) < 0)
6532 operands[2] = GEN_INT (-INTVAL (operands[2]));
6533 return "add{b}\t{%2, %0|%0, %2}";
6535 return "sub{b}\t{%2, %0|%0, %2}";
6539 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6540 (const_string "incdec")
6541 (const_string "alu")))
6542 (set_attr "mode" "QI")])
6545 (define_insn "*addqi_5"
6546 [(set (reg FLAGS_REG)
6548 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6549 (match_operand:QI 2 "general_operand" "qmni"))
6551 (clobber (match_scratch:QI 0 "=q"))]
6552 "ix86_match_ccmode (insn, CCGOCmode)
6553 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6555 switch (get_attr_type (insn))
6558 if (operands[2] == const1_rtx)
6559 return "inc{b}\t%0";
6562 gcc_assert (operands[2] == constm1_rtx
6563 || (CONST_INT_P (operands[2])
6564 && INTVAL (operands[2]) == 255));
6565 return "dec{b}\t%0";
6569 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6570 if (CONST_INT_P (operands[2])
6571 && INTVAL (operands[2]) < 0)
6573 operands[2] = GEN_INT (-INTVAL (operands[2]));
6574 return "sub{b}\t{%2, %0|%0, %2}";
6576 return "add{b}\t{%2, %0|%0, %2}";
6580 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6581 (const_string "incdec")
6582 (const_string "alu")))
6583 (set_attr "mode" "QI")])
6586 (define_insn "addqi_ext_1"
6587 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6592 (match_operand 1 "ext_register_operand" "0")
6595 (match_operand:QI 2 "general_operand" "Qmn")))
6596 (clobber (reg:CC FLAGS_REG))]
6599 switch (get_attr_type (insn))
6602 if (operands[2] == const1_rtx)
6603 return "inc{b}\t%h0";
6606 gcc_assert (operands[2] == constm1_rtx
6607 || (CONST_INT_P (operands[2])
6608 && INTVAL (operands[2]) == 255));
6609 return "dec{b}\t%h0";
6613 return "add{b}\t{%2, %h0|%h0, %2}";
6617 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6618 (const_string "incdec")
6619 (const_string "alu")))
6620 (set_attr "mode" "QI")])
6622 (define_insn "*addqi_ext_1_rex64"
6623 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6628 (match_operand 1 "ext_register_operand" "0")
6631 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6632 (clobber (reg:CC FLAGS_REG))]
6635 switch (get_attr_type (insn))
6638 if (operands[2] == const1_rtx)
6639 return "inc{b}\t%h0";
6642 gcc_assert (operands[2] == constm1_rtx
6643 || (CONST_INT_P (operands[2])
6644 && INTVAL (operands[2]) == 255));
6645 return "dec{b}\t%h0";
6649 return "add{b}\t{%2, %h0|%h0, %2}";
6653 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6654 (const_string "incdec")
6655 (const_string "alu")))
6656 (set_attr "mode" "QI")])
6658 (define_insn "*addqi_ext_2"
6659 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6664 (match_operand 1 "ext_register_operand" "%0")
6668 (match_operand 2 "ext_register_operand" "Q")
6671 (clobber (reg:CC FLAGS_REG))]
6673 "add{b}\t{%h2, %h0|%h0, %h2}"
6674 [(set_attr "type" "alu")
6675 (set_attr "mode" "QI")])
6677 ;; The patterns that match these are at the end of this file.
6679 (define_expand "addxf3"
6680 [(set (match_operand:XF 0 "register_operand" "")
6681 (plus:XF (match_operand:XF 1 "register_operand" "")
6682 (match_operand:XF 2 "register_operand" "")))]
6686 (define_expand "adddf3"
6687 [(set (match_operand:DF 0 "register_operand" "")
6688 (plus:DF (match_operand:DF 1 "register_operand" "")
6689 (match_operand:DF 2 "nonimmediate_operand" "")))]
6690 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6693 (define_expand "addsf3"
6694 [(set (match_operand:SF 0 "register_operand" "")
6695 (plus:SF (match_operand:SF 1 "register_operand" "")
6696 (match_operand:SF 2 "nonimmediate_operand" "")))]
6697 "TARGET_80387 || TARGET_SSE_MATH"
6700 ;; Subtract instructions
6702 ;; %%% splits for subditi3
6704 (define_expand "subti3"
6705 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6706 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6707 (match_operand:TI 2 "x86_64_general_operand" "")))
6708 (clobber (reg:CC FLAGS_REG))])]
6710 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6712 (define_insn "*subti3_1"
6713 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6714 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6715 (match_operand:TI 2 "general_operand" "roiF,riF")))
6716 (clobber (reg:CC FLAGS_REG))]
6717 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6721 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6722 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6723 (match_operand:TI 2 "general_operand" "")))
6724 (clobber (reg:CC FLAGS_REG))]
6725 "TARGET_64BIT && reload_completed"
6726 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6727 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6728 (parallel [(set (match_dup 3)
6729 (minus:DI (match_dup 4)
6730 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6732 (clobber (reg:CC FLAGS_REG))])]
6733 "split_ti (operands+0, 1, operands+0, operands+3);
6734 split_ti (operands+1, 1, operands+1, operands+4);
6735 split_ti (operands+2, 1, operands+2, operands+5);")
6737 ;; %%% splits for subsidi3
6739 (define_expand "subdi3"
6740 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6741 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6742 (match_operand:DI 2 "x86_64_general_operand" "")))
6743 (clobber (reg:CC FLAGS_REG))])]
6745 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6747 (define_insn "*subdi3_1"
6748 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6749 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6750 (match_operand:DI 2 "general_operand" "roiF,riF")))
6751 (clobber (reg:CC FLAGS_REG))]
6752 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6756 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6757 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6758 (match_operand:DI 2 "general_operand" "")))
6759 (clobber (reg:CC FLAGS_REG))]
6760 "!TARGET_64BIT && reload_completed"
6761 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6762 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6763 (parallel [(set (match_dup 3)
6764 (minus:SI (match_dup 4)
6765 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6767 (clobber (reg:CC FLAGS_REG))])]
6768 "split_di (operands+0, 1, operands+0, operands+3);
6769 split_di (operands+1, 1, operands+1, operands+4);
6770 split_di (operands+2, 1, operands+2, operands+5);")
6772 (define_insn "subdi3_carry_rex64"
6773 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6774 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6775 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6776 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6777 (clobber (reg:CC FLAGS_REG))]
6778 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6779 "sbb{q}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "pent_pair" "pu")
6782 (set_attr "mode" "DI")])
6784 (define_insn "*subdi_1_rex64"
6785 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6786 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6787 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6788 (clobber (reg:CC FLAGS_REG))]
6789 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6790 "sub{q}\t{%2, %0|%0, %2}"
6791 [(set_attr "type" "alu")
6792 (set_attr "mode" "DI")])
6794 (define_insn "*subdi_2_rex64"
6795 [(set (reg FLAGS_REG)
6797 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6798 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6800 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6801 (minus:DI (match_dup 1) (match_dup 2)))]
6802 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6803 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6804 "sub{q}\t{%2, %0|%0, %2}"
6805 [(set_attr "type" "alu")
6806 (set_attr "mode" "DI")])
6808 (define_insn "*subdi_3_rex63"
6809 [(set (reg FLAGS_REG)
6810 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6811 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6812 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6813 (minus:DI (match_dup 1) (match_dup 2)))]
6814 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6815 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6816 "sub{q}\t{%2, %0|%0, %2}"
6817 [(set_attr "type" "alu")
6818 (set_attr "mode" "DI")])
6820 (define_insn "subqi3_carry"
6821 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6822 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6823 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6824 (match_operand:QI 2 "general_operand" "qi,qm"))))
6825 (clobber (reg:CC FLAGS_REG))]
6826 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6827 "sbb{b}\t{%2, %0|%0, %2}"
6828 [(set_attr "type" "alu")
6829 (set_attr "pent_pair" "pu")
6830 (set_attr "mode" "QI")])
6832 (define_insn "subhi3_carry"
6833 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6834 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6835 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6836 (match_operand:HI 2 "general_operand" "ri,rm"))))
6837 (clobber (reg:CC FLAGS_REG))]
6838 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6839 "sbb{w}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "pent_pair" "pu")
6842 (set_attr "mode" "HI")])
6844 (define_insn "subsi3_carry"
6845 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6846 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6847 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6848 (match_operand:SI 2 "general_operand" "ri,rm"))))
6849 (clobber (reg:CC FLAGS_REG))]
6850 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6851 "sbb{l}\t{%2, %0|%0, %2}"
6852 [(set_attr "type" "alu")
6853 (set_attr "pent_pair" "pu")
6854 (set_attr "mode" "SI")])
6856 (define_insn "subsi3_carry_zext"
6857 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6859 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6860 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6861 (match_operand:SI 2 "general_operand" "ri,rm")))))
6862 (clobber (reg:CC FLAGS_REG))]
6863 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6864 "sbb{l}\t{%2, %k0|%k0, %2}"
6865 [(set_attr "type" "alu")
6866 (set_attr "pent_pair" "pu")
6867 (set_attr "mode" "SI")])
6869 (define_expand "subsi3"
6870 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6871 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6872 (match_operand:SI 2 "general_operand" "")))
6873 (clobber (reg:CC FLAGS_REG))])]
6875 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6877 (define_insn "*subsi_1"
6878 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6879 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6880 (match_operand:SI 2 "general_operand" "ri,rm")))
6881 (clobber (reg:CC FLAGS_REG))]
6882 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6883 "sub{l}\t{%2, %0|%0, %2}"
6884 [(set_attr "type" "alu")
6885 (set_attr "mode" "SI")])
6887 (define_insn "*subsi_1_zext"
6888 [(set (match_operand:DI 0 "register_operand" "=r")
6890 (minus:SI (match_operand:SI 1 "register_operand" "0")
6891 (match_operand:SI 2 "general_operand" "rim"))))
6892 (clobber (reg:CC FLAGS_REG))]
6893 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6894 "sub{l}\t{%2, %k0|%k0, %2}"
6895 [(set_attr "type" "alu")
6896 (set_attr "mode" "SI")])
6898 (define_insn "*subsi_2"
6899 [(set (reg FLAGS_REG)
6901 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6902 (match_operand:SI 2 "general_operand" "ri,rm"))
6904 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6905 (minus:SI (match_dup 1) (match_dup 2)))]
6906 "ix86_match_ccmode (insn, CCGOCmode)
6907 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6908 "sub{l}\t{%2, %0|%0, %2}"
6909 [(set_attr "type" "alu")
6910 (set_attr "mode" "SI")])
6912 (define_insn "*subsi_2_zext"
6913 [(set (reg FLAGS_REG)
6915 (minus:SI (match_operand:SI 1 "register_operand" "0")
6916 (match_operand:SI 2 "general_operand" "rim"))
6918 (set (match_operand:DI 0 "register_operand" "=r")
6920 (minus:SI (match_dup 1)
6922 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6923 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6924 "sub{l}\t{%2, %k0|%k0, %2}"
6925 [(set_attr "type" "alu")
6926 (set_attr "mode" "SI")])
6928 (define_insn "*subsi_3"
6929 [(set (reg FLAGS_REG)
6930 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6931 (match_operand:SI 2 "general_operand" "ri,rm")))
6932 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6933 (minus:SI (match_dup 1) (match_dup 2)))]
6934 "ix86_match_ccmode (insn, CCmode)
6935 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6936 "sub{l}\t{%2, %0|%0, %2}"
6937 [(set_attr "type" "alu")
6938 (set_attr "mode" "SI")])
6940 (define_insn "*subsi_3_zext"
6941 [(set (reg FLAGS_REG)
6942 (compare (match_operand:SI 1 "register_operand" "0")
6943 (match_operand:SI 2 "general_operand" "rim")))
6944 (set (match_operand:DI 0 "register_operand" "=r")
6946 (minus:SI (match_dup 1)
6948 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6949 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6950 "sub{l}\t{%2, %1|%1, %2}"
6951 [(set_attr "type" "alu")
6952 (set_attr "mode" "DI")])
6954 (define_expand "subhi3"
6955 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6956 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6957 (match_operand:HI 2 "general_operand" "")))
6958 (clobber (reg:CC FLAGS_REG))])]
6959 "TARGET_HIMODE_MATH"
6960 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6962 (define_insn "*subhi_1"
6963 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6964 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6965 (match_operand:HI 2 "general_operand" "ri,rm")))
6966 (clobber (reg:CC FLAGS_REG))]
6967 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6968 "sub{w}\t{%2, %0|%0, %2}"
6969 [(set_attr "type" "alu")
6970 (set_attr "mode" "HI")])
6972 (define_insn "*subhi_2"
6973 [(set (reg FLAGS_REG)
6975 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6976 (match_operand:HI 2 "general_operand" "ri,rm"))
6978 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6979 (minus:HI (match_dup 1) (match_dup 2)))]
6980 "ix86_match_ccmode (insn, CCGOCmode)
6981 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6982 "sub{w}\t{%2, %0|%0, %2}"
6983 [(set_attr "type" "alu")
6984 (set_attr "mode" "HI")])
6986 (define_insn "*subhi_3"
6987 [(set (reg FLAGS_REG)
6988 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6989 (match_operand:HI 2 "general_operand" "ri,rm")))
6990 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6991 (minus:HI (match_dup 1) (match_dup 2)))]
6992 "ix86_match_ccmode (insn, CCmode)
6993 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6994 "sub{w}\t{%2, %0|%0, %2}"
6995 [(set_attr "type" "alu")
6996 (set_attr "mode" "HI")])
6998 (define_expand "subqi3"
6999 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7000 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7001 (match_operand:QI 2 "general_operand" "")))
7002 (clobber (reg:CC FLAGS_REG))])]
7003 "TARGET_QIMODE_MATH"
7004 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7006 (define_insn "*subqi_1"
7007 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7008 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7009 (match_operand:QI 2 "general_operand" "qn,qmn")))
7010 (clobber (reg:CC FLAGS_REG))]
7011 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7012 "sub{b}\t{%2, %0|%0, %2}"
7013 [(set_attr "type" "alu")
7014 (set_attr "mode" "QI")])
7016 (define_insn "*subqi_1_slp"
7017 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7018 (minus:QI (match_dup 0)
7019 (match_operand:QI 1 "general_operand" "qn,qmn")))
7020 (clobber (reg:CC FLAGS_REG))]
7021 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7022 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7023 "sub{b}\t{%1, %0|%0, %1}"
7024 [(set_attr "type" "alu1")
7025 (set_attr "mode" "QI")])
7027 (define_insn "*subqi_2"
7028 [(set (reg FLAGS_REG)
7030 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7031 (match_operand:QI 2 "general_operand" "qi,qm"))
7033 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7034 (minus:HI (match_dup 1) (match_dup 2)))]
7035 "ix86_match_ccmode (insn, CCGOCmode)
7036 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7037 "sub{b}\t{%2, %0|%0, %2}"
7038 [(set_attr "type" "alu")
7039 (set_attr "mode" "QI")])
7041 (define_insn "*subqi_3"
7042 [(set (reg FLAGS_REG)
7043 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7044 (match_operand:QI 2 "general_operand" "qi,qm")))
7045 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7046 (minus:HI (match_dup 1) (match_dup 2)))]
7047 "ix86_match_ccmode (insn, CCmode)
7048 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7049 "sub{b}\t{%2, %0|%0, %2}"
7050 [(set_attr "type" "alu")
7051 (set_attr "mode" "QI")])
7053 ;; The patterns that match these are at the end of this file.
7055 (define_expand "subxf3"
7056 [(set (match_operand:XF 0 "register_operand" "")
7057 (minus:XF (match_operand:XF 1 "register_operand" "")
7058 (match_operand:XF 2 "register_operand" "")))]
7062 (define_expand "subdf3"
7063 [(set (match_operand:DF 0 "register_operand" "")
7064 (minus:DF (match_operand:DF 1 "register_operand" "")
7065 (match_operand:DF 2 "nonimmediate_operand" "")))]
7066 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7069 (define_expand "subsf3"
7070 [(set (match_operand:SF 0 "register_operand" "")
7071 (minus:SF (match_operand:SF 1 "register_operand" "")
7072 (match_operand:SF 2 "nonimmediate_operand" "")))]
7073 "TARGET_80387 || TARGET_SSE_MATH"
7076 ;; Multiply instructions
7078 (define_expand "muldi3"
7079 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7080 (mult:DI (match_operand:DI 1 "register_operand" "")
7081 (match_operand:DI 2 "x86_64_general_operand" "")))
7082 (clobber (reg:CC FLAGS_REG))])]
7087 ;; IMUL reg64, reg64, imm8 Direct
7088 ;; IMUL reg64, mem64, imm8 VectorPath
7089 ;; IMUL reg64, reg64, imm32 Direct
7090 ;; IMUL reg64, mem64, imm32 VectorPath
7091 ;; IMUL reg64, reg64 Direct
7092 ;; IMUL reg64, mem64 Direct
7094 (define_insn "*muldi3_1_rex64"
7095 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7096 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7097 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7098 (clobber (reg:CC FLAGS_REG))]
7100 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7102 imul{q}\t{%2, %1, %0|%0, %1, %2}
7103 imul{q}\t{%2, %1, %0|%0, %1, %2}
7104 imul{q}\t{%2, %0|%0, %2}"
7105 [(set_attr "type" "imul")
7106 (set_attr "prefix_0f" "0,0,1")
7107 (set (attr "athlon_decode")
7108 (cond [(eq_attr "cpu" "athlon")
7109 (const_string "vector")
7110 (eq_attr "alternative" "1")
7111 (const_string "vector")
7112 (and (eq_attr "alternative" "2")
7113 (match_operand 1 "memory_operand" ""))
7114 (const_string "vector")]
7115 (const_string "direct")))
7116 (set (attr "amdfam10_decode")
7117 (cond [(and (eq_attr "alternative" "0,1")
7118 (match_operand 1 "memory_operand" ""))
7119 (const_string "vector")]
7120 (const_string "direct")))
7121 (set_attr "mode" "DI")])
7123 (define_expand "mulsi3"
7124 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7125 (mult:SI (match_operand:SI 1 "register_operand" "")
7126 (match_operand:SI 2 "general_operand" "")))
7127 (clobber (reg:CC FLAGS_REG))])]
7132 ;; IMUL reg32, reg32, imm8 Direct
7133 ;; IMUL reg32, mem32, imm8 VectorPath
7134 ;; IMUL reg32, reg32, imm32 Direct
7135 ;; IMUL reg32, mem32, imm32 VectorPath
7136 ;; IMUL reg32, reg32 Direct
7137 ;; IMUL reg32, mem32 Direct
7139 (define_insn "*mulsi3_1"
7140 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7141 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7142 (match_operand:SI 2 "general_operand" "K,i,mr")))
7143 (clobber (reg:CC FLAGS_REG))]
7144 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7146 imul{l}\t{%2, %1, %0|%0, %1, %2}
7147 imul{l}\t{%2, %1, %0|%0, %1, %2}
7148 imul{l}\t{%2, %0|%0, %2}"
7149 [(set_attr "type" "imul")
7150 (set_attr "prefix_0f" "0,0,1")
7151 (set (attr "athlon_decode")
7152 (cond [(eq_attr "cpu" "athlon")
7153 (const_string "vector")
7154 (eq_attr "alternative" "1")
7155 (const_string "vector")
7156 (and (eq_attr "alternative" "2")
7157 (match_operand 1 "memory_operand" ""))
7158 (const_string "vector")]
7159 (const_string "direct")))
7160 (set (attr "amdfam10_decode")
7161 (cond [(and (eq_attr "alternative" "0,1")
7162 (match_operand 1 "memory_operand" ""))
7163 (const_string "vector")]
7164 (const_string "direct")))
7165 (set_attr "mode" "SI")])
7167 (define_insn "*mulsi3_1_zext"
7168 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7170 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7171 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7172 (clobber (reg:CC FLAGS_REG))]
7174 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7176 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7177 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7178 imul{l}\t{%2, %k0|%k0, %2}"
7179 [(set_attr "type" "imul")
7180 (set_attr "prefix_0f" "0,0,1")
7181 (set (attr "athlon_decode")
7182 (cond [(eq_attr "cpu" "athlon")
7183 (const_string "vector")
7184 (eq_attr "alternative" "1")
7185 (const_string "vector")
7186 (and (eq_attr "alternative" "2")
7187 (match_operand 1 "memory_operand" ""))
7188 (const_string "vector")]
7189 (const_string "direct")))
7190 (set (attr "amdfam10_decode")
7191 (cond [(and (eq_attr "alternative" "0,1")
7192 (match_operand 1 "memory_operand" ""))
7193 (const_string "vector")]
7194 (const_string "direct")))
7195 (set_attr "mode" "SI")])
7197 (define_expand "mulhi3"
7198 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7199 (mult:HI (match_operand:HI 1 "register_operand" "")
7200 (match_operand:HI 2 "general_operand" "")))
7201 (clobber (reg:CC FLAGS_REG))])]
7202 "TARGET_HIMODE_MATH"
7206 ;; IMUL reg16, reg16, imm8 VectorPath
7207 ;; IMUL reg16, mem16, imm8 VectorPath
7208 ;; IMUL reg16, reg16, imm16 VectorPath
7209 ;; IMUL reg16, mem16, imm16 VectorPath
7210 ;; IMUL reg16, reg16 Direct
7211 ;; IMUL reg16, mem16 Direct
7212 (define_insn "*mulhi3_1"
7213 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7214 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7215 (match_operand:HI 2 "general_operand" "K,i,mr")))
7216 (clobber (reg:CC FLAGS_REG))]
7217 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7219 imul{w}\t{%2, %1, %0|%0, %1, %2}
7220 imul{w}\t{%2, %1, %0|%0, %1, %2}
7221 imul{w}\t{%2, %0|%0, %2}"
7222 [(set_attr "type" "imul")
7223 (set_attr "prefix_0f" "0,0,1")
7224 (set (attr "athlon_decode")
7225 (cond [(eq_attr "cpu" "athlon")
7226 (const_string "vector")
7227 (eq_attr "alternative" "1,2")
7228 (const_string "vector")]
7229 (const_string "direct")))
7230 (set (attr "amdfam10_decode")
7231 (cond [(eq_attr "alternative" "0,1")
7232 (const_string "vector")]
7233 (const_string "direct")))
7234 (set_attr "mode" "HI")])
7236 (define_expand "mulqi3"
7237 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7238 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7239 (match_operand:QI 2 "register_operand" "")))
7240 (clobber (reg:CC FLAGS_REG))])]
7241 "TARGET_QIMODE_MATH"
7248 (define_insn "*mulqi3_1"
7249 [(set (match_operand:QI 0 "register_operand" "=a")
7250 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7251 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7252 (clobber (reg:CC FLAGS_REG))]
7254 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7256 [(set_attr "type" "imul")
7257 (set_attr "length_immediate" "0")
7258 (set (attr "athlon_decode")
7259 (if_then_else (eq_attr "cpu" "athlon")
7260 (const_string "vector")
7261 (const_string "direct")))
7262 (set_attr "amdfam10_decode" "direct")
7263 (set_attr "mode" "QI")])
7265 (define_expand "umulqihi3"
7266 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7267 (mult:HI (zero_extend:HI
7268 (match_operand:QI 1 "nonimmediate_operand" ""))
7270 (match_operand:QI 2 "register_operand" ""))))
7271 (clobber (reg:CC FLAGS_REG))])]
7272 "TARGET_QIMODE_MATH"
7275 (define_insn "*umulqihi3_1"
7276 [(set (match_operand:HI 0 "register_operand" "=a")
7277 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7278 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7279 (clobber (reg:CC FLAGS_REG))]
7281 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7283 [(set_attr "type" "imul")
7284 (set_attr "length_immediate" "0")
7285 (set (attr "athlon_decode")
7286 (if_then_else (eq_attr "cpu" "athlon")
7287 (const_string "vector")
7288 (const_string "direct")))
7289 (set_attr "amdfam10_decode" "direct")
7290 (set_attr "mode" "QI")])
7292 (define_expand "mulqihi3"
7293 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7294 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7295 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7296 (clobber (reg:CC FLAGS_REG))])]
7297 "TARGET_QIMODE_MATH"
7300 (define_insn "*mulqihi3_insn"
7301 [(set (match_operand:HI 0 "register_operand" "=a")
7302 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7303 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7304 (clobber (reg:CC FLAGS_REG))]
7306 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7308 [(set_attr "type" "imul")
7309 (set_attr "length_immediate" "0")
7310 (set (attr "athlon_decode")
7311 (if_then_else (eq_attr "cpu" "athlon")
7312 (const_string "vector")
7313 (const_string "direct")))
7314 (set_attr "amdfam10_decode" "direct")
7315 (set_attr "mode" "QI")])
7317 (define_expand "umulditi3"
7318 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7319 (mult:TI (zero_extend:TI
7320 (match_operand:DI 1 "nonimmediate_operand" ""))
7322 (match_operand:DI 2 "register_operand" ""))))
7323 (clobber (reg:CC FLAGS_REG))])]
7327 (define_insn "*umulditi3_insn"
7328 [(set (match_operand:TI 0 "register_operand" "=A")
7329 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7330 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7331 (clobber (reg:CC FLAGS_REG))]
7333 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7335 [(set_attr "type" "imul")
7336 (set_attr "length_immediate" "0")
7337 (set (attr "athlon_decode")
7338 (if_then_else (eq_attr "cpu" "athlon")
7339 (const_string "vector")
7340 (const_string "double")))
7341 (set_attr "amdfam10_decode" "double")
7342 (set_attr "mode" "DI")])
7344 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7345 (define_expand "umulsidi3"
7346 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7347 (mult:DI (zero_extend:DI
7348 (match_operand:SI 1 "nonimmediate_operand" ""))
7350 (match_operand:SI 2 "register_operand" ""))))
7351 (clobber (reg:CC FLAGS_REG))])]
7355 (define_insn "*umulsidi3_insn"
7356 [(set (match_operand:DI 0 "register_operand" "=A")
7357 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7358 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7359 (clobber (reg:CC FLAGS_REG))]
7361 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7363 [(set_attr "type" "imul")
7364 (set_attr "length_immediate" "0")
7365 (set (attr "athlon_decode")
7366 (if_then_else (eq_attr "cpu" "athlon")
7367 (const_string "vector")
7368 (const_string "double")))
7369 (set_attr "amdfam10_decode" "double")
7370 (set_attr "mode" "SI")])
7372 (define_expand "mulditi3"
7373 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7374 (mult:TI (sign_extend:TI
7375 (match_operand:DI 1 "nonimmediate_operand" ""))
7377 (match_operand:DI 2 "register_operand" ""))))
7378 (clobber (reg:CC FLAGS_REG))])]
7382 (define_insn "*mulditi3_insn"
7383 [(set (match_operand:TI 0 "register_operand" "=A")
7384 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7385 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7386 (clobber (reg:CC FLAGS_REG))]
7388 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7390 [(set_attr "type" "imul")
7391 (set_attr "length_immediate" "0")
7392 (set (attr "athlon_decode")
7393 (if_then_else (eq_attr "cpu" "athlon")
7394 (const_string "vector")
7395 (const_string "double")))
7396 (set_attr "amdfam10_decode" "double")
7397 (set_attr "mode" "DI")])
7399 (define_expand "mulsidi3"
7400 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7401 (mult:DI (sign_extend:DI
7402 (match_operand:SI 1 "nonimmediate_operand" ""))
7404 (match_operand:SI 2 "register_operand" ""))))
7405 (clobber (reg:CC FLAGS_REG))])]
7409 (define_insn "*mulsidi3_insn"
7410 [(set (match_operand:DI 0 "register_operand" "=A")
7411 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7412 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7413 (clobber (reg:CC FLAGS_REG))]
7415 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7417 [(set_attr "type" "imul")
7418 (set_attr "length_immediate" "0")
7419 (set (attr "athlon_decode")
7420 (if_then_else (eq_attr "cpu" "athlon")
7421 (const_string "vector")
7422 (const_string "double")))
7423 (set_attr "amdfam10_decode" "double")
7424 (set_attr "mode" "SI")])
7426 (define_expand "umuldi3_highpart"
7427 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7430 (mult:TI (zero_extend:TI
7431 (match_operand:DI 1 "nonimmediate_operand" ""))
7433 (match_operand:DI 2 "register_operand" "")))
7435 (clobber (match_scratch:DI 3 ""))
7436 (clobber (reg:CC FLAGS_REG))])]
7440 (define_insn "*umuldi3_highpart_rex64"
7441 [(set (match_operand:DI 0 "register_operand" "=d")
7444 (mult:TI (zero_extend:TI
7445 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7447 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7449 (clobber (match_scratch:DI 3 "=1"))
7450 (clobber (reg:CC FLAGS_REG))]
7452 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7454 [(set_attr "type" "imul")
7455 (set_attr "length_immediate" "0")
7456 (set (attr "athlon_decode")
7457 (if_then_else (eq_attr "cpu" "athlon")
7458 (const_string "vector")
7459 (const_string "double")))
7460 (set_attr "amdfam10_decode" "double")
7461 (set_attr "mode" "DI")])
7463 (define_expand "umulsi3_highpart"
7464 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7467 (mult:DI (zero_extend:DI
7468 (match_operand:SI 1 "nonimmediate_operand" ""))
7470 (match_operand:SI 2 "register_operand" "")))
7472 (clobber (match_scratch:SI 3 ""))
7473 (clobber (reg:CC FLAGS_REG))])]
7477 (define_insn "*umulsi3_highpart_insn"
7478 [(set (match_operand:SI 0 "register_operand" "=d")
7481 (mult:DI (zero_extend:DI
7482 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7484 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7486 (clobber (match_scratch:SI 3 "=1"))
7487 (clobber (reg:CC FLAGS_REG))]
7488 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7490 [(set_attr "type" "imul")
7491 (set_attr "length_immediate" "0")
7492 (set (attr "athlon_decode")
7493 (if_then_else (eq_attr "cpu" "athlon")
7494 (const_string "vector")
7495 (const_string "double")))
7496 (set_attr "amdfam10_decode" "double")
7497 (set_attr "mode" "SI")])
7499 (define_insn "*umulsi3_highpart_zext"
7500 [(set (match_operand:DI 0 "register_operand" "=d")
7501 (zero_extend:DI (truncate:SI
7503 (mult:DI (zero_extend:DI
7504 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7506 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7508 (clobber (match_scratch:SI 3 "=1"))
7509 (clobber (reg:CC FLAGS_REG))]
7511 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7513 [(set_attr "type" "imul")
7514 (set_attr "length_immediate" "0")
7515 (set (attr "athlon_decode")
7516 (if_then_else (eq_attr "cpu" "athlon")
7517 (const_string "vector")
7518 (const_string "double")))
7519 (set_attr "amdfam10_decode" "double")
7520 (set_attr "mode" "SI")])
7522 (define_expand "smuldi3_highpart"
7523 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7526 (mult:TI (sign_extend:TI
7527 (match_operand:DI 1 "nonimmediate_operand" ""))
7529 (match_operand:DI 2 "register_operand" "")))
7531 (clobber (match_scratch:DI 3 ""))
7532 (clobber (reg:CC FLAGS_REG))])]
7536 (define_insn "*smuldi3_highpart_rex64"
7537 [(set (match_operand:DI 0 "register_operand" "=d")
7540 (mult:TI (sign_extend:TI
7541 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7543 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7545 (clobber (match_scratch:DI 3 "=1"))
7546 (clobber (reg:CC FLAGS_REG))]
7548 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7550 [(set_attr "type" "imul")
7551 (set (attr "athlon_decode")
7552 (if_then_else (eq_attr "cpu" "athlon")
7553 (const_string "vector")
7554 (const_string "double")))
7555 (set_attr "amdfam10_decode" "double")
7556 (set_attr "mode" "DI")])
7558 (define_expand "smulsi3_highpart"
7559 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7562 (mult:DI (sign_extend:DI
7563 (match_operand:SI 1 "nonimmediate_operand" ""))
7565 (match_operand:SI 2 "register_operand" "")))
7567 (clobber (match_scratch:SI 3 ""))
7568 (clobber (reg:CC FLAGS_REG))])]
7572 (define_insn "*smulsi3_highpart_insn"
7573 [(set (match_operand:SI 0 "register_operand" "=d")
7576 (mult:DI (sign_extend:DI
7577 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7579 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7581 (clobber (match_scratch:SI 3 "=1"))
7582 (clobber (reg:CC FLAGS_REG))]
7583 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7585 [(set_attr "type" "imul")
7586 (set (attr "athlon_decode")
7587 (if_then_else (eq_attr "cpu" "athlon")
7588 (const_string "vector")
7589 (const_string "double")))
7590 (set_attr "amdfam10_decode" "double")
7591 (set_attr "mode" "SI")])
7593 (define_insn "*smulsi3_highpart_zext"
7594 [(set (match_operand:DI 0 "register_operand" "=d")
7595 (zero_extend:DI (truncate:SI
7597 (mult:DI (sign_extend:DI
7598 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7600 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7602 (clobber (match_scratch:SI 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" "SI")])
7615 ;; The patterns that match these are at the end of this file.
7617 (define_expand "mulxf3"
7618 [(set (match_operand:XF 0 "register_operand" "")
7619 (mult:XF (match_operand:XF 1 "register_operand" "")
7620 (match_operand:XF 2 "register_operand" "")))]
7624 (define_expand "muldf3"
7625 [(set (match_operand:DF 0 "register_operand" "")
7626 (mult:DF (match_operand:DF 1 "register_operand" "")
7627 (match_operand:DF 2 "nonimmediate_operand" "")))]
7628 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7631 (define_expand "mulsf3"
7632 [(set (match_operand:SF 0 "register_operand" "")
7633 (mult:SF (match_operand:SF 1 "register_operand" "")
7634 (match_operand:SF 2 "nonimmediate_operand" "")))]
7635 "TARGET_80387 || TARGET_SSE_MATH"
7638 ;; Divide instructions
7640 (define_insn "divqi3"
7641 [(set (match_operand:QI 0 "register_operand" "=a")
7642 (div:QI (match_operand:HI 1 "register_operand" "0")
7643 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7644 (clobber (reg:CC FLAGS_REG))]
7645 "TARGET_QIMODE_MATH"
7647 [(set_attr "type" "idiv")
7648 (set_attr "mode" "QI")])
7650 (define_insn "udivqi3"
7651 [(set (match_operand:QI 0 "register_operand" "=a")
7652 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7653 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7654 (clobber (reg:CC FLAGS_REG))]
7655 "TARGET_QIMODE_MATH"
7657 [(set_attr "type" "idiv")
7658 (set_attr "mode" "QI")])
7660 ;; The patterns that match these are at the end of this file.
7662 (define_expand "divxf3"
7663 [(set (match_operand:XF 0 "register_operand" "")
7664 (div:XF (match_operand:XF 1 "register_operand" "")
7665 (match_operand:XF 2 "register_operand" "")))]
7669 (define_expand "divdf3"
7670 [(set (match_operand:DF 0 "register_operand" "")
7671 (div:DF (match_operand:DF 1 "register_operand" "")
7672 (match_operand:DF 2 "nonimmediate_operand" "")))]
7673 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7676 (define_expand "divsf3"
7677 [(set (match_operand:SF 0 "register_operand" "")
7678 (div:SF (match_operand:SF 1 "register_operand" "")
7679 (match_operand:SF 2 "nonimmediate_operand" "")))]
7680 "TARGET_80387 || TARGET_SSE_MATH"
7683 ;; Remainder instructions.
7685 (define_expand "divmoddi4"
7686 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7687 (div:DI (match_operand:DI 1 "register_operand" "")
7688 (match_operand:DI 2 "nonimmediate_operand" "")))
7689 (set (match_operand:DI 3 "register_operand" "")
7690 (mod:DI (match_dup 1) (match_dup 2)))
7691 (clobber (reg:CC FLAGS_REG))])]
7695 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7696 ;; Penalize eax case slightly because it results in worse scheduling
7698 (define_insn "*divmoddi4_nocltd_rex64"
7699 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7700 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7701 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7702 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7703 (mod:DI (match_dup 2) (match_dup 3)))
7704 (clobber (reg:CC FLAGS_REG))]
7705 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7707 [(set_attr "type" "multi")])
7709 (define_insn "*divmoddi4_cltd_rex64"
7710 [(set (match_operand:DI 0 "register_operand" "=a")
7711 (div:DI (match_operand:DI 2 "register_operand" "a")
7712 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7713 (set (match_operand:DI 1 "register_operand" "=&d")
7714 (mod:DI (match_dup 2) (match_dup 3)))
7715 (clobber (reg:CC FLAGS_REG))]
7716 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7718 [(set_attr "type" "multi")])
7720 (define_insn "*divmoddi_noext_rex64"
7721 [(set (match_operand:DI 0 "register_operand" "=a")
7722 (div:DI (match_operand:DI 1 "register_operand" "0")
7723 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7724 (set (match_operand:DI 3 "register_operand" "=d")
7725 (mod:DI (match_dup 1) (match_dup 2)))
7726 (use (match_operand:DI 4 "register_operand" "3"))
7727 (clobber (reg:CC FLAGS_REG))]
7730 [(set_attr "type" "idiv")
7731 (set_attr "mode" "DI")])
7734 [(set (match_operand:DI 0 "register_operand" "")
7735 (div:DI (match_operand:DI 1 "register_operand" "")
7736 (match_operand:DI 2 "nonimmediate_operand" "")))
7737 (set (match_operand:DI 3 "register_operand" "")
7738 (mod:DI (match_dup 1) (match_dup 2)))
7739 (clobber (reg:CC FLAGS_REG))]
7740 "TARGET_64BIT && reload_completed"
7741 [(parallel [(set (match_dup 3)
7742 (ashiftrt:DI (match_dup 4) (const_int 63)))
7743 (clobber (reg:CC FLAGS_REG))])
7744 (parallel [(set (match_dup 0)
7745 (div:DI (reg:DI 0) (match_dup 2)))
7747 (mod:DI (reg:DI 0) (match_dup 2)))
7749 (clobber (reg:CC FLAGS_REG))])]
7751 /* Avoid use of cltd in favor of a mov+shift. */
7752 if (!TARGET_USE_CLTD && !optimize_size)
7754 if (true_regnum (operands[1]))
7755 emit_move_insn (operands[0], operands[1]);
7757 emit_move_insn (operands[3], operands[1]);
7758 operands[4] = operands[3];
7762 gcc_assert (!true_regnum (operands[1]));
7763 operands[4] = operands[1];
7768 (define_expand "divmodsi4"
7769 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7770 (div:SI (match_operand:SI 1 "register_operand" "")
7771 (match_operand:SI 2 "nonimmediate_operand" "")))
7772 (set (match_operand:SI 3 "register_operand" "")
7773 (mod:SI (match_dup 1) (match_dup 2)))
7774 (clobber (reg:CC FLAGS_REG))])]
7778 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7779 ;; Penalize eax case slightly because it results in worse scheduling
7781 (define_insn "*divmodsi4_nocltd"
7782 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7783 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7784 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7785 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7786 (mod:SI (match_dup 2) (match_dup 3)))
7787 (clobber (reg:CC FLAGS_REG))]
7788 "!optimize_size && !TARGET_USE_CLTD"
7790 [(set_attr "type" "multi")])
7792 (define_insn "*divmodsi4_cltd"
7793 [(set (match_operand:SI 0 "register_operand" "=a")
7794 (div:SI (match_operand:SI 2 "register_operand" "a")
7795 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7796 (set (match_operand:SI 1 "register_operand" "=&d")
7797 (mod:SI (match_dup 2) (match_dup 3)))
7798 (clobber (reg:CC FLAGS_REG))]
7799 "optimize_size || TARGET_USE_CLTD"
7801 [(set_attr "type" "multi")])
7803 (define_insn "*divmodsi_noext"
7804 [(set (match_operand:SI 0 "register_operand" "=a")
7805 (div:SI (match_operand:SI 1 "register_operand" "0")
7806 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7807 (set (match_operand:SI 3 "register_operand" "=d")
7808 (mod:SI (match_dup 1) (match_dup 2)))
7809 (use (match_operand:SI 4 "register_operand" "3"))
7810 (clobber (reg:CC FLAGS_REG))]
7813 [(set_attr "type" "idiv")
7814 (set_attr "mode" "SI")])
7817 [(set (match_operand:SI 0 "register_operand" "")
7818 (div:SI (match_operand:SI 1 "register_operand" "")
7819 (match_operand:SI 2 "nonimmediate_operand" "")))
7820 (set (match_operand:SI 3 "register_operand" "")
7821 (mod:SI (match_dup 1) (match_dup 2)))
7822 (clobber (reg:CC FLAGS_REG))]
7824 [(parallel [(set (match_dup 3)
7825 (ashiftrt:SI (match_dup 4) (const_int 31)))
7826 (clobber (reg:CC FLAGS_REG))])
7827 (parallel [(set (match_dup 0)
7828 (div:SI (reg:SI 0) (match_dup 2)))
7830 (mod:SI (reg:SI 0) (match_dup 2)))
7832 (clobber (reg:CC FLAGS_REG))])]
7834 /* Avoid use of cltd in favor of a mov+shift. */
7835 if (!TARGET_USE_CLTD && !optimize_size)
7837 if (true_regnum (operands[1]))
7838 emit_move_insn (operands[0], operands[1]);
7840 emit_move_insn (operands[3], operands[1]);
7841 operands[4] = operands[3];
7845 gcc_assert (!true_regnum (operands[1]));
7846 operands[4] = operands[1];
7850 (define_insn "divmodhi4"
7851 [(set (match_operand:HI 0 "register_operand" "=a")
7852 (div:HI (match_operand:HI 1 "register_operand" "0")
7853 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7854 (set (match_operand:HI 3 "register_operand" "=&d")
7855 (mod:HI (match_dup 1) (match_dup 2)))
7856 (clobber (reg:CC FLAGS_REG))]
7857 "TARGET_HIMODE_MATH"
7859 [(set_attr "type" "multi")
7860 (set_attr "length_immediate" "0")
7861 (set_attr "mode" "SI")])
7863 (define_insn "udivmoddi4"
7864 [(set (match_operand:DI 0 "register_operand" "=a")
7865 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7866 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7867 (set (match_operand:DI 3 "register_operand" "=&d")
7868 (umod:DI (match_dup 1) (match_dup 2)))
7869 (clobber (reg:CC FLAGS_REG))]
7871 "xor{q}\t%3, %3\;div{q}\t%2"
7872 [(set_attr "type" "multi")
7873 (set_attr "length_immediate" "0")
7874 (set_attr "mode" "DI")])
7876 (define_insn "*udivmoddi4_noext"
7877 [(set (match_operand:DI 0 "register_operand" "=a")
7878 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7879 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7880 (set (match_operand:DI 3 "register_operand" "=d")
7881 (umod:DI (match_dup 1) (match_dup 2)))
7883 (clobber (reg:CC FLAGS_REG))]
7886 [(set_attr "type" "idiv")
7887 (set_attr "mode" "DI")])
7890 [(set (match_operand:DI 0 "register_operand" "")
7891 (udiv:DI (match_operand:DI 1 "register_operand" "")
7892 (match_operand:DI 2 "nonimmediate_operand" "")))
7893 (set (match_operand:DI 3 "register_operand" "")
7894 (umod:DI (match_dup 1) (match_dup 2)))
7895 (clobber (reg:CC FLAGS_REG))]
7896 "TARGET_64BIT && reload_completed"
7897 [(set (match_dup 3) (const_int 0))
7898 (parallel [(set (match_dup 0)
7899 (udiv:DI (match_dup 1) (match_dup 2)))
7901 (umod:DI (match_dup 1) (match_dup 2)))
7903 (clobber (reg:CC FLAGS_REG))])]
7906 (define_insn "udivmodsi4"
7907 [(set (match_operand:SI 0 "register_operand" "=a")
7908 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7909 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7910 (set (match_operand:SI 3 "register_operand" "=&d")
7911 (umod:SI (match_dup 1) (match_dup 2)))
7912 (clobber (reg:CC FLAGS_REG))]
7914 "xor{l}\t%3, %3\;div{l}\t%2"
7915 [(set_attr "type" "multi")
7916 (set_attr "length_immediate" "0")
7917 (set_attr "mode" "SI")])
7919 (define_insn "*udivmodsi4_noext"
7920 [(set (match_operand:SI 0 "register_operand" "=a")
7921 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7922 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7923 (set (match_operand:SI 3 "register_operand" "=d")
7924 (umod:SI (match_dup 1) (match_dup 2)))
7926 (clobber (reg:CC FLAGS_REG))]
7929 [(set_attr "type" "idiv")
7930 (set_attr "mode" "SI")])
7933 [(set (match_operand:SI 0 "register_operand" "")
7934 (udiv:SI (match_operand:SI 1 "register_operand" "")
7935 (match_operand:SI 2 "nonimmediate_operand" "")))
7936 (set (match_operand:SI 3 "register_operand" "")
7937 (umod:SI (match_dup 1) (match_dup 2)))
7938 (clobber (reg:CC FLAGS_REG))]
7940 [(set (match_dup 3) (const_int 0))
7941 (parallel [(set (match_dup 0)
7942 (udiv:SI (match_dup 1) (match_dup 2)))
7944 (umod:SI (match_dup 1) (match_dup 2)))
7946 (clobber (reg:CC FLAGS_REG))])]
7949 (define_expand "udivmodhi4"
7950 [(set (match_dup 4) (const_int 0))
7951 (parallel [(set (match_operand:HI 0 "register_operand" "")
7952 (udiv:HI (match_operand:HI 1 "register_operand" "")
7953 (match_operand:HI 2 "nonimmediate_operand" "")))
7954 (set (match_operand:HI 3 "register_operand" "")
7955 (umod:HI (match_dup 1) (match_dup 2)))
7957 (clobber (reg:CC FLAGS_REG))])]
7958 "TARGET_HIMODE_MATH"
7959 "operands[4] = gen_reg_rtx (HImode);")
7961 (define_insn "*udivmodhi_noext"
7962 [(set (match_operand:HI 0 "register_operand" "=a")
7963 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7964 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7965 (set (match_operand:HI 3 "register_operand" "=d")
7966 (umod:HI (match_dup 1) (match_dup 2)))
7967 (use (match_operand:HI 4 "register_operand" "3"))
7968 (clobber (reg:CC FLAGS_REG))]
7971 [(set_attr "type" "idiv")
7972 (set_attr "mode" "HI")])
7974 ;; We cannot use div/idiv for double division, because it causes
7975 ;; "division by zero" on the overflow and that's not what we expect
7976 ;; from truncate. Because true (non truncating) double division is
7977 ;; never generated, we can't create this insn anyway.
7980 ; [(set (match_operand:SI 0 "register_operand" "=a")
7982 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7984 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7985 ; (set (match_operand:SI 3 "register_operand" "=d")
7987 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7988 ; (clobber (reg:CC FLAGS_REG))]
7990 ; "div{l}\t{%2, %0|%0, %2}"
7991 ; [(set_attr "type" "idiv")])
7993 ;;- Logical AND instructions
7995 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7996 ;; Note that this excludes ah.
7998 (define_insn "*testdi_1_rex64"
7999 [(set (reg FLAGS_REG)
8001 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8002 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8004 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8005 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8007 test{l}\t{%k1, %k0|%k0, %k1}
8008 test{l}\t{%k1, %k0|%k0, %k1}
8009 test{q}\t{%1, %0|%0, %1}
8010 test{q}\t{%1, %0|%0, %1}
8011 test{q}\t{%1, %0|%0, %1}"
8012 [(set_attr "type" "test")
8013 (set_attr "modrm" "0,1,0,1,1")
8014 (set_attr "mode" "SI,SI,DI,DI,DI")
8015 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8017 (define_insn "testsi_1"
8018 [(set (reg FLAGS_REG)
8020 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8021 (match_operand:SI 1 "general_operand" "in,in,rin"))
8023 "ix86_match_ccmode (insn, CCNOmode)
8024 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8025 "test{l}\t{%1, %0|%0, %1}"
8026 [(set_attr "type" "test")
8027 (set_attr "modrm" "0,1,1")
8028 (set_attr "mode" "SI")
8029 (set_attr "pent_pair" "uv,np,uv")])
8031 (define_expand "testsi_ccno_1"
8032 [(set (reg:CCNO FLAGS_REG)
8034 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8035 (match_operand:SI 1 "nonmemory_operand" ""))
8040 (define_insn "*testhi_1"
8041 [(set (reg FLAGS_REG)
8042 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8043 (match_operand:HI 1 "general_operand" "n,n,rn"))
8045 "ix86_match_ccmode (insn, CCNOmode)
8046 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8047 "test{w}\t{%1, %0|%0, %1}"
8048 [(set_attr "type" "test")
8049 (set_attr "modrm" "0,1,1")
8050 (set_attr "mode" "HI")
8051 (set_attr "pent_pair" "uv,np,uv")])
8053 (define_expand "testqi_ccz_1"
8054 [(set (reg:CCZ FLAGS_REG)
8055 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8056 (match_operand:QI 1 "nonmemory_operand" ""))
8061 (define_insn "*testqi_1_maybe_si"
8062 [(set (reg FLAGS_REG)
8065 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8066 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8068 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8069 && ix86_match_ccmode (insn,
8070 CONST_INT_P (operands[1])
8071 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8073 if (which_alternative == 3)
8075 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8076 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8077 return "test{l}\t{%1, %k0|%k0, %1}";
8079 return "test{b}\t{%1, %0|%0, %1}";
8081 [(set_attr "type" "test")
8082 (set_attr "modrm" "0,1,1,1")
8083 (set_attr "mode" "QI,QI,QI,SI")
8084 (set_attr "pent_pair" "uv,np,uv,np")])
8086 (define_insn "*testqi_1"
8087 [(set (reg FLAGS_REG)
8090 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8091 (match_operand:QI 1 "general_operand" "n,n,qn"))
8093 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8094 && ix86_match_ccmode (insn, CCNOmode)"
8095 "test{b}\t{%1, %0|%0, %1}"
8096 [(set_attr "type" "test")
8097 (set_attr "modrm" "0,1,1")
8098 (set_attr "mode" "QI")
8099 (set_attr "pent_pair" "uv,np,uv")])
8101 (define_expand "testqi_ext_ccno_0"
8102 [(set (reg:CCNO FLAGS_REG)
8106 (match_operand 0 "ext_register_operand" "")
8109 (match_operand 1 "const_int_operand" ""))
8114 (define_insn "*testqi_ext_0"
8115 [(set (reg FLAGS_REG)
8119 (match_operand 0 "ext_register_operand" "Q")
8122 (match_operand 1 "const_int_operand" "n"))
8124 "ix86_match_ccmode (insn, CCNOmode)"
8125 "test{b}\t{%1, %h0|%h0, %1}"
8126 [(set_attr "type" "test")
8127 (set_attr "mode" "QI")
8128 (set_attr "length_immediate" "1")
8129 (set_attr "pent_pair" "np")])
8131 (define_insn "*testqi_ext_1"
8132 [(set (reg FLAGS_REG)
8136 (match_operand 0 "ext_register_operand" "Q")
8140 (match_operand:QI 1 "general_operand" "Qm")))
8142 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8143 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8144 "test{b}\t{%1, %h0|%h0, %1}"
8145 [(set_attr "type" "test")
8146 (set_attr "mode" "QI")])
8148 (define_insn "*testqi_ext_1_rex64"
8149 [(set (reg FLAGS_REG)
8153 (match_operand 0 "ext_register_operand" "Q")
8157 (match_operand:QI 1 "register_operand" "Q")))
8159 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8160 "test{b}\t{%1, %h0|%h0, %1}"
8161 [(set_attr "type" "test")
8162 (set_attr "mode" "QI")])
8164 (define_insn "*testqi_ext_2"
8165 [(set (reg FLAGS_REG)
8169 (match_operand 0 "ext_register_operand" "Q")
8173 (match_operand 1 "ext_register_operand" "Q")
8177 "ix86_match_ccmode (insn, CCNOmode)"
8178 "test{b}\t{%h1, %h0|%h0, %h1}"
8179 [(set_attr "type" "test")
8180 (set_attr "mode" "QI")])
8182 ;; Combine likes to form bit extractions for some tests. Humor it.
8183 (define_insn "*testqi_ext_3"
8184 [(set (reg FLAGS_REG)
8185 (compare (zero_extract:SI
8186 (match_operand 0 "nonimmediate_operand" "rm")
8187 (match_operand:SI 1 "const_int_operand" "")
8188 (match_operand:SI 2 "const_int_operand" ""))
8190 "ix86_match_ccmode (insn, CCNOmode)
8191 && INTVAL (operands[1]) > 0
8192 && INTVAL (operands[2]) >= 0
8193 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8194 && (GET_MODE (operands[0]) == SImode
8195 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8196 || GET_MODE (operands[0]) == HImode
8197 || GET_MODE (operands[0]) == QImode)"
8200 (define_insn "*testqi_ext_3_rex64"
8201 [(set (reg FLAGS_REG)
8202 (compare (zero_extract:DI
8203 (match_operand 0 "nonimmediate_operand" "rm")
8204 (match_operand:DI 1 "const_int_operand" "")
8205 (match_operand:DI 2 "const_int_operand" ""))
8208 && ix86_match_ccmode (insn, CCNOmode)
8209 && INTVAL (operands[1]) > 0
8210 && INTVAL (operands[2]) >= 0
8211 /* Ensure that resulting mask is zero or sign extended operand. */
8212 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8213 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8214 && INTVAL (operands[1]) > 32))
8215 && (GET_MODE (operands[0]) == SImode
8216 || GET_MODE (operands[0]) == DImode
8217 || GET_MODE (operands[0]) == HImode
8218 || GET_MODE (operands[0]) == QImode)"
8222 [(set (match_operand 0 "flags_reg_operand" "")
8223 (match_operator 1 "compare_operator"
8225 (match_operand 2 "nonimmediate_operand" "")
8226 (match_operand 3 "const_int_operand" "")
8227 (match_operand 4 "const_int_operand" ""))
8229 "ix86_match_ccmode (insn, CCNOmode)"
8230 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8232 rtx val = operands[2];
8233 HOST_WIDE_INT len = INTVAL (operands[3]);
8234 HOST_WIDE_INT pos = INTVAL (operands[4]);
8236 enum machine_mode mode, submode;
8238 mode = GET_MODE (val);
8241 /* ??? Combine likes to put non-volatile mem extractions in QImode
8242 no matter the size of the test. So find a mode that works. */
8243 if (! MEM_VOLATILE_P (val))
8245 mode = smallest_mode_for_size (pos + len, MODE_INT);
8246 val = adjust_address (val, mode, 0);
8249 else if (GET_CODE (val) == SUBREG
8250 && (submode = GET_MODE (SUBREG_REG (val)),
8251 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8252 && pos + len <= GET_MODE_BITSIZE (submode))
8254 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8256 val = SUBREG_REG (val);
8258 else if (mode == HImode && pos + len <= 8)
8260 /* Small HImode tests can be converted to QImode. */
8262 val = gen_lowpart (QImode, val);
8265 if (len == HOST_BITS_PER_WIDE_INT)
8268 mask = ((HOST_WIDE_INT)1 << len) - 1;
8271 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8274 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8275 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8276 ;; this is relatively important trick.
8277 ;; Do the conversion only post-reload to avoid limiting of the register class
8280 [(set (match_operand 0 "flags_reg_operand" "")
8281 (match_operator 1 "compare_operator"
8282 [(and (match_operand 2 "register_operand" "")
8283 (match_operand 3 "const_int_operand" ""))
8286 && QI_REG_P (operands[2])
8287 && GET_MODE (operands[2]) != QImode
8288 && ((ix86_match_ccmode (insn, CCZmode)
8289 && !(INTVAL (operands[3]) & ~(255 << 8)))
8290 || (ix86_match_ccmode (insn, CCNOmode)
8291 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8294 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8297 "operands[2] = gen_lowpart (SImode, operands[2]);
8298 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8301 [(set (match_operand 0 "flags_reg_operand" "")
8302 (match_operator 1 "compare_operator"
8303 [(and (match_operand 2 "nonimmediate_operand" "")
8304 (match_operand 3 "const_int_operand" ""))
8307 && GET_MODE (operands[2]) != QImode
8308 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8309 && ((ix86_match_ccmode (insn, CCZmode)
8310 && !(INTVAL (operands[3]) & ~255))
8311 || (ix86_match_ccmode (insn, CCNOmode)
8312 && !(INTVAL (operands[3]) & ~127)))"
8314 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8316 "operands[2] = gen_lowpart (QImode, operands[2]);
8317 operands[3] = gen_lowpart (QImode, operands[3]);")
8320 ;; %%% This used to optimize known byte-wide and operations to memory,
8321 ;; and sometimes to QImode registers. If this is considered useful,
8322 ;; it should be done with splitters.
8324 (define_expand "anddi3"
8325 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8326 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8327 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8328 (clobber (reg:CC FLAGS_REG))]
8330 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8332 (define_insn "*anddi_1_rex64"
8333 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8334 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8335 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8336 (clobber (reg:CC FLAGS_REG))]
8337 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8339 switch (get_attr_type (insn))
8343 enum machine_mode mode;
8345 gcc_assert (CONST_INT_P (operands[2]));
8346 if (INTVAL (operands[2]) == 0xff)
8350 gcc_assert (INTVAL (operands[2]) == 0xffff);
8354 operands[1] = gen_lowpart (mode, operands[1]);
8356 return "movz{bq|x}\t{%1,%0|%0, %1}";
8358 return "movz{wq|x}\t{%1,%0|%0, %1}";
8362 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8363 if (get_attr_mode (insn) == MODE_SI)
8364 return "and{l}\t{%k2, %k0|%k0, %k2}";
8366 return "and{q}\t{%2, %0|%0, %2}";
8369 [(set_attr "type" "alu,alu,alu,imovx")
8370 (set_attr "length_immediate" "*,*,*,0")
8371 (set_attr "mode" "SI,DI,DI,DI")])
8373 (define_insn "*anddi_2"
8374 [(set (reg FLAGS_REG)
8375 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8376 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8378 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8379 (and:DI (match_dup 1) (match_dup 2)))]
8380 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8381 && ix86_binary_operator_ok (AND, DImode, operands)"
8383 and{l}\t{%k2, %k0|%k0, %k2}
8384 and{q}\t{%2, %0|%0, %2}
8385 and{q}\t{%2, %0|%0, %2}"
8386 [(set_attr "type" "alu")
8387 (set_attr "mode" "SI,DI,DI")])
8389 (define_expand "andsi3"
8390 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8391 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8392 (match_operand:SI 2 "general_operand" "")))
8393 (clobber (reg:CC FLAGS_REG))]
8395 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8397 (define_insn "*andsi_1"
8398 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8399 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8400 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8401 (clobber (reg:CC FLAGS_REG))]
8402 "ix86_binary_operator_ok (AND, SImode, operands)"
8404 switch (get_attr_type (insn))
8408 enum machine_mode mode;
8410 gcc_assert (CONST_INT_P (operands[2]));
8411 if (INTVAL (operands[2]) == 0xff)
8415 gcc_assert (INTVAL (operands[2]) == 0xffff);
8419 operands[1] = gen_lowpart (mode, operands[1]);
8421 return "movz{bl|x}\t{%1,%0|%0, %1}";
8423 return "movz{wl|x}\t{%1,%0|%0, %1}";
8427 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8428 return "and{l}\t{%2, %0|%0, %2}";
8431 [(set_attr "type" "alu,alu,imovx")
8432 (set_attr "length_immediate" "*,*,0")
8433 (set_attr "mode" "SI")])
8436 [(set (match_operand 0 "register_operand" "")
8438 (const_int -65536)))
8439 (clobber (reg:CC FLAGS_REG))]
8440 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8441 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8442 "operands[1] = gen_lowpart (HImode, operands[0]);")
8445 [(set (match_operand 0 "ext_register_operand" "")
8448 (clobber (reg:CC FLAGS_REG))]
8449 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8450 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8451 "operands[1] = gen_lowpart (QImode, operands[0]);")
8454 [(set (match_operand 0 "ext_register_operand" "")
8456 (const_int -65281)))
8457 (clobber (reg:CC FLAGS_REG))]
8458 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8459 [(parallel [(set (zero_extract:SI (match_dup 0)
8463 (zero_extract:SI (match_dup 0)
8466 (zero_extract:SI (match_dup 0)
8469 (clobber (reg:CC FLAGS_REG))])]
8470 "operands[0] = gen_lowpart (SImode, operands[0]);")
8472 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8473 (define_insn "*andsi_1_zext"
8474 [(set (match_operand:DI 0 "register_operand" "=r")
8476 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8477 (match_operand:SI 2 "general_operand" "rim"))))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8480 "and{l}\t{%2, %k0|%k0, %2}"
8481 [(set_attr "type" "alu")
8482 (set_attr "mode" "SI")])
8484 (define_insn "*andsi_2"
8485 [(set (reg FLAGS_REG)
8486 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8487 (match_operand:SI 2 "general_operand" "rim,ri"))
8489 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8490 (and:SI (match_dup 1) (match_dup 2)))]
8491 "ix86_match_ccmode (insn, CCNOmode)
8492 && ix86_binary_operator_ok (AND, SImode, operands)"
8493 "and{l}\t{%2, %0|%0, %2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "mode" "SI")])
8497 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8498 (define_insn "*andsi_2_zext"
8499 [(set (reg FLAGS_REG)
8500 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8501 (match_operand:SI 2 "general_operand" "rim"))
8503 (set (match_operand:DI 0 "register_operand" "=r")
8504 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8505 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8506 && ix86_binary_operator_ok (AND, SImode, operands)"
8507 "and{l}\t{%2, %k0|%k0, %2}"
8508 [(set_attr "type" "alu")
8509 (set_attr "mode" "SI")])
8511 (define_expand "andhi3"
8512 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8513 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8514 (match_operand:HI 2 "general_operand" "")))
8515 (clobber (reg:CC FLAGS_REG))]
8516 "TARGET_HIMODE_MATH"
8517 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8519 (define_insn "*andhi_1"
8520 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8521 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8522 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8523 (clobber (reg:CC FLAGS_REG))]
8524 "ix86_binary_operator_ok (AND, HImode, operands)"
8526 switch (get_attr_type (insn))
8529 gcc_assert (CONST_INT_P (operands[2]));
8530 gcc_assert (INTVAL (operands[2]) == 0xff);
8531 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8534 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8536 return "and{w}\t{%2, %0|%0, %2}";
8539 [(set_attr "type" "alu,alu,imovx")
8540 (set_attr "length_immediate" "*,*,0")
8541 (set_attr "mode" "HI,HI,SI")])
8543 (define_insn "*andhi_2"
8544 [(set (reg FLAGS_REG)
8545 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8546 (match_operand:HI 2 "general_operand" "rim,ri"))
8548 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8549 (and:HI (match_dup 1) (match_dup 2)))]
8550 "ix86_match_ccmode (insn, CCNOmode)
8551 && ix86_binary_operator_ok (AND, HImode, operands)"
8552 "and{w}\t{%2, %0|%0, %2}"
8553 [(set_attr "type" "alu")
8554 (set_attr "mode" "HI")])
8556 (define_expand "andqi3"
8557 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8558 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8559 (match_operand:QI 2 "general_operand" "")))
8560 (clobber (reg:CC FLAGS_REG))]
8561 "TARGET_QIMODE_MATH"
8562 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8564 ;; %%% Potential partial reg stall on alternative 2. What to do?
8565 (define_insn "*andqi_1"
8566 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8567 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8568 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8569 (clobber (reg:CC FLAGS_REG))]
8570 "ix86_binary_operator_ok (AND, QImode, operands)"
8572 and{b}\t{%2, %0|%0, %2}
8573 and{b}\t{%2, %0|%0, %2}
8574 and{l}\t{%k2, %k0|%k0, %k2}"
8575 [(set_attr "type" "alu")
8576 (set_attr "mode" "QI,QI,SI")])
8578 (define_insn "*andqi_1_slp"
8579 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8580 (and:QI (match_dup 0)
8581 (match_operand:QI 1 "general_operand" "qi,qmi")))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8584 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8585 "and{b}\t{%1, %0|%0, %1}"
8586 [(set_attr "type" "alu1")
8587 (set_attr "mode" "QI")])
8589 (define_insn "*andqi_2_maybe_si"
8590 [(set (reg FLAGS_REG)
8592 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8593 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8595 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8596 (and:QI (match_dup 1) (match_dup 2)))]
8597 "ix86_binary_operator_ok (AND, QImode, operands)
8598 && ix86_match_ccmode (insn,
8599 CONST_INT_P (operands[2])
8600 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8602 if (which_alternative == 2)
8604 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8605 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8606 return "and{l}\t{%2, %k0|%k0, %2}";
8608 return "and{b}\t{%2, %0|%0, %2}";
8610 [(set_attr "type" "alu")
8611 (set_attr "mode" "QI,QI,SI")])
8613 (define_insn "*andqi_2"
8614 [(set (reg FLAGS_REG)
8616 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8617 (match_operand:QI 2 "general_operand" "qim,qi"))
8619 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8620 (and:QI (match_dup 1) (match_dup 2)))]
8621 "ix86_match_ccmode (insn, CCNOmode)
8622 && ix86_binary_operator_ok (AND, QImode, operands)"
8623 "and{b}\t{%2, %0|%0, %2}"
8624 [(set_attr "type" "alu")
8625 (set_attr "mode" "QI")])
8627 (define_insn "*andqi_2_slp"
8628 [(set (reg FLAGS_REG)
8630 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8631 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8633 (set (strict_low_part (match_dup 0))
8634 (and:QI (match_dup 0) (match_dup 1)))]
8635 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8636 && ix86_match_ccmode (insn, CCNOmode)
8637 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8638 "and{b}\t{%1, %0|%0, %1}"
8639 [(set_attr "type" "alu1")
8640 (set_attr "mode" "QI")])
8642 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8643 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8644 ;; for a QImode operand, which of course failed.
8646 (define_insn "andqi_ext_0"
8647 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8652 (match_operand 1 "ext_register_operand" "0")
8655 (match_operand 2 "const_int_operand" "n")))
8656 (clobber (reg:CC FLAGS_REG))]
8658 "and{b}\t{%2, %h0|%h0, %2}"
8659 [(set_attr "type" "alu")
8660 (set_attr "length_immediate" "1")
8661 (set_attr "mode" "QI")])
8663 ;; Generated by peephole translating test to and. This shows up
8664 ;; often in fp comparisons.
8666 (define_insn "*andqi_ext_0_cc"
8667 [(set (reg FLAGS_REG)
8671 (match_operand 1 "ext_register_operand" "0")
8674 (match_operand 2 "const_int_operand" "n"))
8676 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8685 "ix86_match_ccmode (insn, CCNOmode)"
8686 "and{b}\t{%2, %h0|%h0, %2}"
8687 [(set_attr "type" "alu")
8688 (set_attr "length_immediate" "1")
8689 (set_attr "mode" "QI")])
8691 (define_insn "*andqi_ext_1"
8692 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8697 (match_operand 1 "ext_register_operand" "0")
8701 (match_operand:QI 2 "general_operand" "Qm"))))
8702 (clobber (reg:CC FLAGS_REG))]
8704 "and{b}\t{%2, %h0|%h0, %2}"
8705 [(set_attr "type" "alu")
8706 (set_attr "length_immediate" "0")
8707 (set_attr "mode" "QI")])
8709 (define_insn "*andqi_ext_1_rex64"
8710 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8715 (match_operand 1 "ext_register_operand" "0")
8719 (match_operand 2 "ext_register_operand" "Q"))))
8720 (clobber (reg:CC FLAGS_REG))]
8722 "and{b}\t{%2, %h0|%h0, %2}"
8723 [(set_attr "type" "alu")
8724 (set_attr "length_immediate" "0")
8725 (set_attr "mode" "QI")])
8727 (define_insn "*andqi_ext_2"
8728 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8733 (match_operand 1 "ext_register_operand" "%0")
8737 (match_operand 2 "ext_register_operand" "Q")
8740 (clobber (reg:CC FLAGS_REG))]
8742 "and{b}\t{%h2, %h0|%h0, %h2}"
8743 [(set_attr "type" "alu")
8744 (set_attr "length_immediate" "0")
8745 (set_attr "mode" "QI")])
8747 ;; Convert wide AND instructions with immediate operand to shorter QImode
8748 ;; equivalents when possible.
8749 ;; Don't do the splitting with memory operands, since it introduces risk
8750 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8751 ;; for size, but that can (should?) be handled by generic code instead.
8753 [(set (match_operand 0 "register_operand" "")
8754 (and (match_operand 1 "register_operand" "")
8755 (match_operand 2 "const_int_operand" "")))
8756 (clobber (reg:CC FLAGS_REG))]
8758 && QI_REG_P (operands[0])
8759 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8760 && !(~INTVAL (operands[2]) & ~(255 << 8))
8761 && GET_MODE (operands[0]) != QImode"
8762 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8763 (and:SI (zero_extract:SI (match_dup 1)
8764 (const_int 8) (const_int 8))
8766 (clobber (reg:CC FLAGS_REG))])]
8767 "operands[0] = gen_lowpart (SImode, operands[0]);
8768 operands[1] = gen_lowpart (SImode, operands[1]);
8769 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8771 ;; Since AND can be encoded with sign extended immediate, this is only
8772 ;; profitable when 7th bit is not set.
8774 [(set (match_operand 0 "register_operand" "")
8775 (and (match_operand 1 "general_operand" "")
8776 (match_operand 2 "const_int_operand" "")))
8777 (clobber (reg:CC FLAGS_REG))]
8779 && ANY_QI_REG_P (operands[0])
8780 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8781 && !(~INTVAL (operands[2]) & ~255)
8782 && !(INTVAL (operands[2]) & 128)
8783 && GET_MODE (operands[0]) != QImode"
8784 [(parallel [(set (strict_low_part (match_dup 0))
8785 (and:QI (match_dup 1)
8787 (clobber (reg:CC FLAGS_REG))])]
8788 "operands[0] = gen_lowpart (QImode, operands[0]);
8789 operands[1] = gen_lowpart (QImode, operands[1]);
8790 operands[2] = gen_lowpart (QImode, operands[2]);")
8792 ;; Logical inclusive OR instructions
8794 ;; %%% This used to optimize known byte-wide and operations to memory.
8795 ;; If this is considered useful, it should be done with splitters.
8797 (define_expand "iordi3"
8798 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8799 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8800 (match_operand:DI 2 "x86_64_general_operand" "")))
8801 (clobber (reg:CC FLAGS_REG))]
8803 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8805 (define_insn "*iordi_1_rex64"
8806 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8807 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8808 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8809 (clobber (reg:CC FLAGS_REG))]
8811 && ix86_binary_operator_ok (IOR, DImode, operands)"
8812 "or{q}\t{%2, %0|%0, %2}"
8813 [(set_attr "type" "alu")
8814 (set_attr "mode" "DI")])
8816 (define_insn "*iordi_2_rex64"
8817 [(set (reg FLAGS_REG)
8818 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8819 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8821 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8822 (ior:DI (match_dup 1) (match_dup 2)))]
8824 && ix86_match_ccmode (insn, CCNOmode)
8825 && ix86_binary_operator_ok (IOR, DImode, operands)"
8826 "or{q}\t{%2, %0|%0, %2}"
8827 [(set_attr "type" "alu")
8828 (set_attr "mode" "DI")])
8830 (define_insn "*iordi_3_rex64"
8831 [(set (reg FLAGS_REG)
8832 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8833 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8835 (clobber (match_scratch:DI 0 "=r"))]
8837 && ix86_match_ccmode (insn, CCNOmode)
8838 && ix86_binary_operator_ok (IOR, DImode, operands)"
8839 "or{q}\t{%2, %0|%0, %2}"
8840 [(set_attr "type" "alu")
8841 (set_attr "mode" "DI")])
8844 (define_expand "iorsi3"
8845 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8846 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8847 (match_operand:SI 2 "general_operand" "")))
8848 (clobber (reg:CC FLAGS_REG))]
8850 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8852 (define_insn "*iorsi_1"
8853 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8854 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8855 (match_operand:SI 2 "general_operand" "ri,rmi")))
8856 (clobber (reg:CC FLAGS_REG))]
8857 "ix86_binary_operator_ok (IOR, SImode, operands)"
8858 "or{l}\t{%2, %0|%0, %2}"
8859 [(set_attr "type" "alu")
8860 (set_attr "mode" "SI")])
8862 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8863 (define_insn "*iorsi_1_zext"
8864 [(set (match_operand:DI 0 "register_operand" "=rm")
8866 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8867 (match_operand:SI 2 "general_operand" "rim"))))
8868 (clobber (reg:CC FLAGS_REG))]
8869 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8870 "or{l}\t{%2, %k0|%k0, %2}"
8871 [(set_attr "type" "alu")
8872 (set_attr "mode" "SI")])
8874 (define_insn "*iorsi_1_zext_imm"
8875 [(set (match_operand:DI 0 "register_operand" "=rm")
8876 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8877 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8878 (clobber (reg:CC FLAGS_REG))]
8880 "or{l}\t{%2, %k0|%k0, %2}"
8881 [(set_attr "type" "alu")
8882 (set_attr "mode" "SI")])
8884 (define_insn "*iorsi_2"
8885 [(set (reg FLAGS_REG)
8886 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8887 (match_operand:SI 2 "general_operand" "rim,ri"))
8889 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8890 (ior:SI (match_dup 1) (match_dup 2)))]
8891 "ix86_match_ccmode (insn, CCNOmode)
8892 && ix86_binary_operator_ok (IOR, SImode, operands)"
8893 "or{l}\t{%2, %0|%0, %2}"
8894 [(set_attr "type" "alu")
8895 (set_attr "mode" "SI")])
8897 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8898 ;; ??? Special case for immediate operand is missing - it is tricky.
8899 (define_insn "*iorsi_2_zext"
8900 [(set (reg FLAGS_REG)
8901 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8902 (match_operand:SI 2 "general_operand" "rim"))
8904 (set (match_operand:DI 0 "register_operand" "=r")
8905 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8906 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8907 && ix86_binary_operator_ok (IOR, SImode, operands)"
8908 "or{l}\t{%2, %k0|%k0, %2}"
8909 [(set_attr "type" "alu")
8910 (set_attr "mode" "SI")])
8912 (define_insn "*iorsi_2_zext_imm"
8913 [(set (reg FLAGS_REG)
8914 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8915 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8917 (set (match_operand:DI 0 "register_operand" "=r")
8918 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8919 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8920 && ix86_binary_operator_ok (IOR, SImode, operands)"
8921 "or{l}\t{%2, %k0|%k0, %2}"
8922 [(set_attr "type" "alu")
8923 (set_attr "mode" "SI")])
8925 (define_insn "*iorsi_3"
8926 [(set (reg FLAGS_REG)
8927 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8928 (match_operand:SI 2 "general_operand" "rim"))
8930 (clobber (match_scratch:SI 0 "=r"))]
8931 "ix86_match_ccmode (insn, CCNOmode)
8932 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8933 "or{l}\t{%2, %0|%0, %2}"
8934 [(set_attr "type" "alu")
8935 (set_attr "mode" "SI")])
8937 (define_expand "iorhi3"
8938 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8939 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8940 (match_operand:HI 2 "general_operand" "")))
8941 (clobber (reg:CC FLAGS_REG))]
8942 "TARGET_HIMODE_MATH"
8943 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8945 (define_insn "*iorhi_1"
8946 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8947 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8948 (match_operand:HI 2 "general_operand" "rmi,ri")))
8949 (clobber (reg:CC FLAGS_REG))]
8950 "ix86_binary_operator_ok (IOR, HImode, operands)"
8951 "or{w}\t{%2, %0|%0, %2}"
8952 [(set_attr "type" "alu")
8953 (set_attr "mode" "HI")])
8955 (define_insn "*iorhi_2"
8956 [(set (reg FLAGS_REG)
8957 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8958 (match_operand:HI 2 "general_operand" "rim,ri"))
8960 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8961 (ior:HI (match_dup 1) (match_dup 2)))]
8962 "ix86_match_ccmode (insn, CCNOmode)
8963 && ix86_binary_operator_ok (IOR, HImode, operands)"
8964 "or{w}\t{%2, %0|%0, %2}"
8965 [(set_attr "type" "alu")
8966 (set_attr "mode" "HI")])
8968 (define_insn "*iorhi_3"
8969 [(set (reg FLAGS_REG)
8970 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8971 (match_operand:HI 2 "general_operand" "rim"))
8973 (clobber (match_scratch:HI 0 "=r"))]
8974 "ix86_match_ccmode (insn, CCNOmode)
8975 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8976 "or{w}\t{%2, %0|%0, %2}"
8977 [(set_attr "type" "alu")
8978 (set_attr "mode" "HI")])
8980 (define_expand "iorqi3"
8981 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8982 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8983 (match_operand:QI 2 "general_operand" "")))
8984 (clobber (reg:CC FLAGS_REG))]
8985 "TARGET_QIMODE_MATH"
8986 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8988 ;; %%% Potential partial reg stall on alternative 2. What to do?
8989 (define_insn "*iorqi_1"
8990 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8991 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8992 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8993 (clobber (reg:CC FLAGS_REG))]
8994 "ix86_binary_operator_ok (IOR, QImode, operands)"
8996 or{b}\t{%2, %0|%0, %2}
8997 or{b}\t{%2, %0|%0, %2}
8998 or{l}\t{%k2, %k0|%k0, %k2}"
8999 [(set_attr "type" "alu")
9000 (set_attr "mode" "QI,QI,SI")])
9002 (define_insn "*iorqi_1_slp"
9003 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9004 (ior:QI (match_dup 0)
9005 (match_operand:QI 1 "general_operand" "qmi,qi")))
9006 (clobber (reg:CC FLAGS_REG))]
9007 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9008 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9009 "or{b}\t{%1, %0|%0, %1}"
9010 [(set_attr "type" "alu1")
9011 (set_attr "mode" "QI")])
9013 (define_insn "*iorqi_2"
9014 [(set (reg FLAGS_REG)
9015 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9016 (match_operand:QI 2 "general_operand" "qim,qi"))
9018 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9019 (ior:QI (match_dup 1) (match_dup 2)))]
9020 "ix86_match_ccmode (insn, CCNOmode)
9021 && ix86_binary_operator_ok (IOR, QImode, operands)"
9022 "or{b}\t{%2, %0|%0, %2}"
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "QI")])
9026 (define_insn "*iorqi_2_slp"
9027 [(set (reg FLAGS_REG)
9028 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9029 (match_operand:QI 1 "general_operand" "qim,qi"))
9031 (set (strict_low_part (match_dup 0))
9032 (ior:QI (match_dup 0) (match_dup 1)))]
9033 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9034 && ix86_match_ccmode (insn, CCNOmode)
9035 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9036 "or{b}\t{%1, %0|%0, %1}"
9037 [(set_attr "type" "alu1")
9038 (set_attr "mode" "QI")])
9040 (define_insn "*iorqi_3"
9041 [(set (reg FLAGS_REG)
9042 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9043 (match_operand:QI 2 "general_operand" "qim"))
9045 (clobber (match_scratch:QI 0 "=q"))]
9046 "ix86_match_ccmode (insn, CCNOmode)
9047 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9048 "or{b}\t{%2, %0|%0, %2}"
9049 [(set_attr "type" "alu")
9050 (set_attr "mode" "QI")])
9052 (define_insn "iorqi_ext_0"
9053 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9058 (match_operand 1 "ext_register_operand" "0")
9061 (match_operand 2 "const_int_operand" "n")))
9062 (clobber (reg:CC FLAGS_REG))]
9063 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9064 "or{b}\t{%2, %h0|%h0, %2}"
9065 [(set_attr "type" "alu")
9066 (set_attr "length_immediate" "1")
9067 (set_attr "mode" "QI")])
9069 (define_insn "*iorqi_ext_1"
9070 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9075 (match_operand 1 "ext_register_operand" "0")
9079 (match_operand:QI 2 "general_operand" "Qm"))))
9080 (clobber (reg:CC FLAGS_REG))]
9082 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9083 "or{b}\t{%2, %h0|%h0, %2}"
9084 [(set_attr "type" "alu")
9085 (set_attr "length_immediate" "0")
9086 (set_attr "mode" "QI")])
9088 (define_insn "*iorqi_ext_1_rex64"
9089 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9094 (match_operand 1 "ext_register_operand" "0")
9098 (match_operand 2 "ext_register_operand" "Q"))))
9099 (clobber (reg:CC FLAGS_REG))]
9101 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9102 "or{b}\t{%2, %h0|%h0, %2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "length_immediate" "0")
9105 (set_attr "mode" "QI")])
9107 (define_insn "*iorqi_ext_2"
9108 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9112 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9115 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9118 (clobber (reg:CC FLAGS_REG))]
9119 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9120 "ior{b}\t{%h2, %h0|%h0, %h2}"
9121 [(set_attr "type" "alu")
9122 (set_attr "length_immediate" "0")
9123 (set_attr "mode" "QI")])
9126 [(set (match_operand 0 "register_operand" "")
9127 (ior (match_operand 1 "register_operand" "")
9128 (match_operand 2 "const_int_operand" "")))
9129 (clobber (reg:CC FLAGS_REG))]
9131 && QI_REG_P (operands[0])
9132 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9133 && !(INTVAL (operands[2]) & ~(255 << 8))
9134 && GET_MODE (operands[0]) != QImode"
9135 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9136 (ior:SI (zero_extract:SI (match_dup 1)
9137 (const_int 8) (const_int 8))
9139 (clobber (reg:CC FLAGS_REG))])]
9140 "operands[0] = gen_lowpart (SImode, operands[0]);
9141 operands[1] = gen_lowpart (SImode, operands[1]);
9142 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9144 ;; Since OR can be encoded with sign extended immediate, this is only
9145 ;; profitable when 7th bit is set.
9147 [(set (match_operand 0 "register_operand" "")
9148 (ior (match_operand 1 "general_operand" "")
9149 (match_operand 2 "const_int_operand" "")))
9150 (clobber (reg:CC FLAGS_REG))]
9152 && ANY_QI_REG_P (operands[0])
9153 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9154 && !(INTVAL (operands[2]) & ~255)
9155 && (INTVAL (operands[2]) & 128)
9156 && GET_MODE (operands[0]) != QImode"
9157 [(parallel [(set (strict_low_part (match_dup 0))
9158 (ior:QI (match_dup 1)
9160 (clobber (reg:CC FLAGS_REG))])]
9161 "operands[0] = gen_lowpart (QImode, operands[0]);
9162 operands[1] = gen_lowpart (QImode, operands[1]);
9163 operands[2] = gen_lowpart (QImode, operands[2]);")
9165 ;; Logical XOR instructions
9167 ;; %%% This used to optimize known byte-wide and operations to memory.
9168 ;; If this is considered useful, it should be done with splitters.
9170 (define_expand "xordi3"
9171 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9172 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9173 (match_operand:DI 2 "x86_64_general_operand" "")))
9174 (clobber (reg:CC FLAGS_REG))]
9176 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9178 (define_insn "*xordi_1_rex64"
9179 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9180 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9181 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9182 (clobber (reg:CC FLAGS_REG))]
9184 && ix86_binary_operator_ok (XOR, DImode, operands)"
9186 xor{q}\t{%2, %0|%0, %2}
9187 xor{q}\t{%2, %0|%0, %2}"
9188 [(set_attr "type" "alu")
9189 (set_attr "mode" "DI,DI")])
9191 (define_insn "*xordi_2_rex64"
9192 [(set (reg FLAGS_REG)
9193 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9194 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9196 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9197 (xor:DI (match_dup 1) (match_dup 2)))]
9199 && ix86_match_ccmode (insn, CCNOmode)
9200 && ix86_binary_operator_ok (XOR, DImode, operands)"
9202 xor{q}\t{%2, %0|%0, %2}
9203 xor{q}\t{%2, %0|%0, %2}"
9204 [(set_attr "type" "alu")
9205 (set_attr "mode" "DI,DI")])
9207 (define_insn "*xordi_3_rex64"
9208 [(set (reg FLAGS_REG)
9209 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9210 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9212 (clobber (match_scratch:DI 0 "=r"))]
9214 && ix86_match_ccmode (insn, CCNOmode)
9215 && ix86_binary_operator_ok (XOR, DImode, operands)"
9216 "xor{q}\t{%2, %0|%0, %2}"
9217 [(set_attr "type" "alu")
9218 (set_attr "mode" "DI")])
9220 (define_expand "xorsi3"
9221 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9222 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9223 (match_operand:SI 2 "general_operand" "")))
9224 (clobber (reg:CC FLAGS_REG))]
9226 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9228 (define_insn "*xorsi_1"
9229 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9230 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9231 (match_operand:SI 2 "general_operand" "ri,rm")))
9232 (clobber (reg:CC FLAGS_REG))]
9233 "ix86_binary_operator_ok (XOR, SImode, operands)"
9234 "xor{l}\t{%2, %0|%0, %2}"
9235 [(set_attr "type" "alu")
9236 (set_attr "mode" "SI")])
9238 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9239 ;; Add speccase for immediates
9240 (define_insn "*xorsi_1_zext"
9241 [(set (match_operand:DI 0 "register_operand" "=r")
9243 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9244 (match_operand:SI 2 "general_operand" "rim"))))
9245 (clobber (reg:CC FLAGS_REG))]
9246 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9247 "xor{l}\t{%2, %k0|%k0, %2}"
9248 [(set_attr "type" "alu")
9249 (set_attr "mode" "SI")])
9251 (define_insn "*xorsi_1_zext_imm"
9252 [(set (match_operand:DI 0 "register_operand" "=r")
9253 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9254 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9255 (clobber (reg:CC FLAGS_REG))]
9256 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9257 "xor{l}\t{%2, %k0|%k0, %2}"
9258 [(set_attr "type" "alu")
9259 (set_attr "mode" "SI")])
9261 (define_insn "*xorsi_2"
9262 [(set (reg FLAGS_REG)
9263 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9264 (match_operand:SI 2 "general_operand" "rim,ri"))
9266 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9267 (xor:SI (match_dup 1) (match_dup 2)))]
9268 "ix86_match_ccmode (insn, CCNOmode)
9269 && ix86_binary_operator_ok (XOR, SImode, operands)"
9270 "xor{l}\t{%2, %0|%0, %2}"
9271 [(set_attr "type" "alu")
9272 (set_attr "mode" "SI")])
9274 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9275 ;; ??? Special case for immediate operand is missing - it is tricky.
9276 (define_insn "*xorsi_2_zext"
9277 [(set (reg FLAGS_REG)
9278 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9279 (match_operand:SI 2 "general_operand" "rim"))
9281 (set (match_operand:DI 0 "register_operand" "=r")
9282 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9283 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9284 && ix86_binary_operator_ok (XOR, SImode, operands)"
9285 "xor{l}\t{%2, %k0|%k0, %2}"
9286 [(set_attr "type" "alu")
9287 (set_attr "mode" "SI")])
9289 (define_insn "*xorsi_2_zext_imm"
9290 [(set (reg FLAGS_REG)
9291 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9292 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9294 (set (match_operand:DI 0 "register_operand" "=r")
9295 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9296 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9297 && ix86_binary_operator_ok (XOR, SImode, operands)"
9298 "xor{l}\t{%2, %k0|%k0, %2}"
9299 [(set_attr "type" "alu")
9300 (set_attr "mode" "SI")])
9302 (define_insn "*xorsi_3"
9303 [(set (reg FLAGS_REG)
9304 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9305 (match_operand:SI 2 "general_operand" "rim"))
9307 (clobber (match_scratch:SI 0 "=r"))]
9308 "ix86_match_ccmode (insn, CCNOmode)
9309 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9310 "xor{l}\t{%2, %0|%0, %2}"
9311 [(set_attr "type" "alu")
9312 (set_attr "mode" "SI")])
9314 (define_expand "xorhi3"
9315 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9316 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9317 (match_operand:HI 2 "general_operand" "")))
9318 (clobber (reg:CC FLAGS_REG))]
9319 "TARGET_HIMODE_MATH"
9320 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9322 (define_insn "*xorhi_1"
9323 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9324 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9325 (match_operand:HI 2 "general_operand" "rmi,ri")))
9326 (clobber (reg:CC FLAGS_REG))]
9327 "ix86_binary_operator_ok (XOR, HImode, operands)"
9328 "xor{w}\t{%2, %0|%0, %2}"
9329 [(set_attr "type" "alu")
9330 (set_attr "mode" "HI")])
9332 (define_insn "*xorhi_2"
9333 [(set (reg FLAGS_REG)
9334 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9335 (match_operand:HI 2 "general_operand" "rim,ri"))
9337 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9338 (xor:HI (match_dup 1) (match_dup 2)))]
9339 "ix86_match_ccmode (insn, CCNOmode)
9340 && ix86_binary_operator_ok (XOR, HImode, operands)"
9341 "xor{w}\t{%2, %0|%0, %2}"
9342 [(set_attr "type" "alu")
9343 (set_attr "mode" "HI")])
9345 (define_insn "*xorhi_3"
9346 [(set (reg FLAGS_REG)
9347 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9348 (match_operand:HI 2 "general_operand" "rim"))
9350 (clobber (match_scratch:HI 0 "=r"))]
9351 "ix86_match_ccmode (insn, CCNOmode)
9352 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9353 "xor{w}\t{%2, %0|%0, %2}"
9354 [(set_attr "type" "alu")
9355 (set_attr "mode" "HI")])
9357 (define_expand "xorqi3"
9358 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9359 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9360 (match_operand:QI 2 "general_operand" "")))
9361 (clobber (reg:CC FLAGS_REG))]
9362 "TARGET_QIMODE_MATH"
9363 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9365 ;; %%% Potential partial reg stall on alternative 2. What to do?
9366 (define_insn "*xorqi_1"
9367 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9368 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9369 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9370 (clobber (reg:CC FLAGS_REG))]
9371 "ix86_binary_operator_ok (XOR, QImode, operands)"
9373 xor{b}\t{%2, %0|%0, %2}
9374 xor{b}\t{%2, %0|%0, %2}
9375 xor{l}\t{%k2, %k0|%k0, %k2}"
9376 [(set_attr "type" "alu")
9377 (set_attr "mode" "QI,QI,SI")])
9379 (define_insn "*xorqi_1_slp"
9380 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9381 (xor:QI (match_dup 0)
9382 (match_operand:QI 1 "general_operand" "qi,qmi")))
9383 (clobber (reg:CC FLAGS_REG))]
9384 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9385 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9386 "xor{b}\t{%1, %0|%0, %1}"
9387 [(set_attr "type" "alu1")
9388 (set_attr "mode" "QI")])
9390 (define_insn "xorqi_ext_0"
9391 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9396 (match_operand 1 "ext_register_operand" "0")
9399 (match_operand 2 "const_int_operand" "n")))
9400 (clobber (reg:CC FLAGS_REG))]
9401 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9402 "xor{b}\t{%2, %h0|%h0, %2}"
9403 [(set_attr "type" "alu")
9404 (set_attr "length_immediate" "1")
9405 (set_attr "mode" "QI")])
9407 (define_insn "*xorqi_ext_1"
9408 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9413 (match_operand 1 "ext_register_operand" "0")
9417 (match_operand:QI 2 "general_operand" "Qm"))))
9418 (clobber (reg:CC FLAGS_REG))]
9420 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9421 "xor{b}\t{%2, %h0|%h0, %2}"
9422 [(set_attr "type" "alu")
9423 (set_attr "length_immediate" "0")
9424 (set_attr "mode" "QI")])
9426 (define_insn "*xorqi_ext_1_rex64"
9427 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9432 (match_operand 1 "ext_register_operand" "0")
9436 (match_operand 2 "ext_register_operand" "Q"))))
9437 (clobber (reg:CC FLAGS_REG))]
9439 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9440 "xor{b}\t{%2, %h0|%h0, %2}"
9441 [(set_attr "type" "alu")
9442 (set_attr "length_immediate" "0")
9443 (set_attr "mode" "QI")])
9445 (define_insn "*xorqi_ext_2"
9446 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9450 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9453 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9456 (clobber (reg:CC FLAGS_REG))]
9457 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9458 "xor{b}\t{%h2, %h0|%h0, %h2}"
9459 [(set_attr "type" "alu")
9460 (set_attr "length_immediate" "0")
9461 (set_attr "mode" "QI")])
9463 (define_insn "*xorqi_cc_1"
9464 [(set (reg FLAGS_REG)
9466 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9467 (match_operand:QI 2 "general_operand" "qim,qi"))
9469 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9470 (xor:QI (match_dup 1) (match_dup 2)))]
9471 "ix86_match_ccmode (insn, CCNOmode)
9472 && ix86_binary_operator_ok (XOR, QImode, operands)"
9473 "xor{b}\t{%2, %0|%0, %2}"
9474 [(set_attr "type" "alu")
9475 (set_attr "mode" "QI")])
9477 (define_insn "*xorqi_2_slp"
9478 [(set (reg FLAGS_REG)
9479 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9480 (match_operand:QI 1 "general_operand" "qim,qi"))
9482 (set (strict_low_part (match_dup 0))
9483 (xor:QI (match_dup 0) (match_dup 1)))]
9484 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9485 && ix86_match_ccmode (insn, CCNOmode)
9486 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9487 "xor{b}\t{%1, %0|%0, %1}"
9488 [(set_attr "type" "alu1")
9489 (set_attr "mode" "QI")])
9491 (define_insn "*xorqi_cc_2"
9492 [(set (reg FLAGS_REG)
9494 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9495 (match_operand:QI 2 "general_operand" "qim"))
9497 (clobber (match_scratch:QI 0 "=q"))]
9498 "ix86_match_ccmode (insn, CCNOmode)
9499 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9500 "xor{b}\t{%2, %0|%0, %2}"
9501 [(set_attr "type" "alu")
9502 (set_attr "mode" "QI")])
9504 (define_insn "*xorqi_cc_ext_1"
9505 [(set (reg FLAGS_REG)
9509 (match_operand 1 "ext_register_operand" "0")
9512 (match_operand:QI 2 "general_operand" "qmn"))
9514 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9518 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9520 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9521 "xor{b}\t{%2, %h0|%h0, %2}"
9522 [(set_attr "type" "alu")
9523 (set_attr "mode" "QI")])
9525 (define_insn "*xorqi_cc_ext_1_rex64"
9526 [(set (reg FLAGS_REG)
9530 (match_operand 1 "ext_register_operand" "0")
9533 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9535 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9539 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9541 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9542 "xor{b}\t{%2, %h0|%h0, %2}"
9543 [(set_attr "type" "alu")
9544 (set_attr "mode" "QI")])
9546 (define_expand "xorqi_cc_ext_1"
9548 (set (reg:CCNO FLAGS_REG)
9552 (match_operand 1 "ext_register_operand" "")
9555 (match_operand:QI 2 "general_operand" ""))
9557 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9561 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9567 [(set (match_operand 0 "register_operand" "")
9568 (xor (match_operand 1 "register_operand" "")
9569 (match_operand 2 "const_int_operand" "")))
9570 (clobber (reg:CC FLAGS_REG))]
9572 && QI_REG_P (operands[0])
9573 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9574 && !(INTVAL (operands[2]) & ~(255 << 8))
9575 && GET_MODE (operands[0]) != QImode"
9576 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9577 (xor:SI (zero_extract:SI (match_dup 1)
9578 (const_int 8) (const_int 8))
9580 (clobber (reg:CC FLAGS_REG))])]
9581 "operands[0] = gen_lowpart (SImode, operands[0]);
9582 operands[1] = gen_lowpart (SImode, operands[1]);
9583 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9585 ;; Since XOR can be encoded with sign extended immediate, this is only
9586 ;; profitable when 7th bit is set.
9588 [(set (match_operand 0 "register_operand" "")
9589 (xor (match_operand 1 "general_operand" "")
9590 (match_operand 2 "const_int_operand" "")))
9591 (clobber (reg:CC FLAGS_REG))]
9593 && ANY_QI_REG_P (operands[0])
9594 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9595 && !(INTVAL (operands[2]) & ~255)
9596 && (INTVAL (operands[2]) & 128)
9597 && GET_MODE (operands[0]) != QImode"
9598 [(parallel [(set (strict_low_part (match_dup 0))
9599 (xor:QI (match_dup 1)
9601 (clobber (reg:CC FLAGS_REG))])]
9602 "operands[0] = gen_lowpart (QImode, operands[0]);
9603 operands[1] = gen_lowpart (QImode, operands[1]);
9604 operands[2] = gen_lowpart (QImode, operands[2]);")
9606 ;; Negation instructions
9608 (define_expand "negti2"
9609 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9610 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9611 (clobber (reg:CC FLAGS_REG))])]
9613 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9615 (define_insn "*negti2_1"
9616 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9617 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9618 (clobber (reg:CC FLAGS_REG))]
9620 && ix86_unary_operator_ok (NEG, TImode, operands)"
9624 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9625 (neg:TI (match_operand:TI 1 "general_operand" "")))
9626 (clobber (reg:CC FLAGS_REG))]
9627 "TARGET_64BIT && reload_completed"
9629 [(set (reg:CCZ FLAGS_REG)
9630 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9631 (set (match_dup 0) (neg:DI (match_dup 2)))])
9634 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9637 (clobber (reg:CC FLAGS_REG))])
9640 (neg:DI (match_dup 1)))
9641 (clobber (reg:CC FLAGS_REG))])]
9642 "split_ti (operands+1, 1, operands+2, operands+3);
9643 split_ti (operands+0, 1, operands+0, operands+1);")
9645 (define_expand "negdi2"
9646 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9647 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9648 (clobber (reg:CC FLAGS_REG))])]
9650 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9652 (define_insn "*negdi2_1"
9653 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9654 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9655 (clobber (reg:CC FLAGS_REG))]
9657 && ix86_unary_operator_ok (NEG, DImode, operands)"
9661 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9662 (neg:DI (match_operand:DI 1 "general_operand" "")))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "!TARGET_64BIT && reload_completed"
9666 [(set (reg:CCZ FLAGS_REG)
9667 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9668 (set (match_dup 0) (neg:SI (match_dup 2)))])
9671 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9674 (clobber (reg:CC FLAGS_REG))])
9677 (neg:SI (match_dup 1)))
9678 (clobber (reg:CC FLAGS_REG))])]
9679 "split_di (operands+1, 1, operands+2, operands+3);
9680 split_di (operands+0, 1, operands+0, operands+1);")
9682 (define_insn "*negdi2_1_rex64"
9683 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9684 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9685 (clobber (reg:CC FLAGS_REG))]
9686 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9688 [(set_attr "type" "negnot")
9689 (set_attr "mode" "DI")])
9691 ;; The problem with neg is that it does not perform (compare x 0),
9692 ;; it really performs (compare 0 x), which leaves us with the zero
9693 ;; flag being the only useful item.
9695 (define_insn "*negdi2_cmpz_rex64"
9696 [(set (reg:CCZ FLAGS_REG)
9697 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9699 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9700 (neg:DI (match_dup 1)))]
9701 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9703 [(set_attr "type" "negnot")
9704 (set_attr "mode" "DI")])
9707 (define_expand "negsi2"
9708 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9709 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9710 (clobber (reg:CC FLAGS_REG))])]
9712 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9714 (define_insn "*negsi2_1"
9715 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9716 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9717 (clobber (reg:CC FLAGS_REG))]
9718 "ix86_unary_operator_ok (NEG, SImode, operands)"
9720 [(set_attr "type" "negnot")
9721 (set_attr "mode" "SI")])
9723 ;; Combine is quite creative about this pattern.
9724 (define_insn "*negsi2_1_zext"
9725 [(set (match_operand:DI 0 "register_operand" "=r")
9726 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9729 (clobber (reg:CC FLAGS_REG))]
9730 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9732 [(set_attr "type" "negnot")
9733 (set_attr "mode" "SI")])
9735 ;; The problem with neg is that it does not perform (compare x 0),
9736 ;; it really performs (compare 0 x), which leaves us with the zero
9737 ;; flag being the only useful item.
9739 (define_insn "*negsi2_cmpz"
9740 [(set (reg:CCZ FLAGS_REG)
9741 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9743 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9744 (neg:SI (match_dup 1)))]
9745 "ix86_unary_operator_ok (NEG, SImode, operands)"
9747 [(set_attr "type" "negnot")
9748 (set_attr "mode" "SI")])
9750 (define_insn "*negsi2_cmpz_zext"
9751 [(set (reg:CCZ FLAGS_REG)
9752 (compare:CCZ (lshiftrt:DI
9754 (match_operand:DI 1 "register_operand" "0")
9758 (set (match_operand:DI 0 "register_operand" "=r")
9759 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9762 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9764 [(set_attr "type" "negnot")
9765 (set_attr "mode" "SI")])
9767 (define_expand "neghi2"
9768 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9769 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9770 (clobber (reg:CC FLAGS_REG))])]
9771 "TARGET_HIMODE_MATH"
9772 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9774 (define_insn "*neghi2_1"
9775 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9776 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9777 (clobber (reg:CC FLAGS_REG))]
9778 "ix86_unary_operator_ok (NEG, HImode, operands)"
9780 [(set_attr "type" "negnot")
9781 (set_attr "mode" "HI")])
9783 (define_insn "*neghi2_cmpz"
9784 [(set (reg:CCZ FLAGS_REG)
9785 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9787 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9788 (neg:HI (match_dup 1)))]
9789 "ix86_unary_operator_ok (NEG, HImode, operands)"
9791 [(set_attr "type" "negnot")
9792 (set_attr "mode" "HI")])
9794 (define_expand "negqi2"
9795 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9796 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9797 (clobber (reg:CC FLAGS_REG))])]
9798 "TARGET_QIMODE_MATH"
9799 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9801 (define_insn "*negqi2_1"
9802 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9803 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9804 (clobber (reg:CC FLAGS_REG))]
9805 "ix86_unary_operator_ok (NEG, QImode, operands)"
9807 [(set_attr "type" "negnot")
9808 (set_attr "mode" "QI")])
9810 (define_insn "*negqi2_cmpz"
9811 [(set (reg:CCZ FLAGS_REG)
9812 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9814 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9815 (neg:QI (match_dup 1)))]
9816 "ix86_unary_operator_ok (NEG, QImode, operands)"
9818 [(set_attr "type" "negnot")
9819 (set_attr "mode" "QI")])
9821 ;; Changing of sign for FP values is doable using integer unit too.
9823 (define_expand "negsf2"
9824 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9825 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9826 "TARGET_80387 || TARGET_SSE_MATH"
9827 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9829 (define_expand "abssf2"
9830 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9831 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9832 "TARGET_80387 || TARGET_SSE_MATH"
9833 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9835 (define_insn "*absnegsf2_mixed"
9836 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9837 (match_operator:SF 3 "absneg_operator"
9838 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9839 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9840 (clobber (reg:CC FLAGS_REG))]
9841 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9842 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9845 (define_insn "*absnegsf2_sse"
9846 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9847 (match_operator:SF 3 "absneg_operator"
9848 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9849 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9850 (clobber (reg:CC FLAGS_REG))]
9852 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9855 (define_insn "*absnegsf2_i387"
9856 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9857 (match_operator:SF 3 "absneg_operator"
9858 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9859 (use (match_operand 2 "" ""))
9860 (clobber (reg:CC FLAGS_REG))]
9861 "TARGET_80387 && !TARGET_SSE_MATH
9862 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9865 (define_expand "copysignsf3"
9866 [(match_operand:SF 0 "register_operand" "")
9867 (match_operand:SF 1 "nonmemory_operand" "")
9868 (match_operand:SF 2 "register_operand" "")]
9871 ix86_expand_copysign (operands);
9875 (define_insn_and_split "copysignsf3_const"
9876 [(set (match_operand:SF 0 "register_operand" "=x")
9878 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9879 (match_operand:SF 2 "register_operand" "0")
9880 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9884 "&& reload_completed"
9887 ix86_split_copysign_const (operands);
9891 (define_insn "copysignsf3_var"
9892 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9894 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9895 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9896 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9897 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9899 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9904 [(set (match_operand:SF 0 "register_operand" "")
9906 [(match_operand:SF 2 "register_operand" "")
9907 (match_operand:SF 3 "register_operand" "")
9908 (match_operand:V4SF 4 "" "")
9909 (match_operand:V4SF 5 "" "")]
9911 (clobber (match_scratch:V4SF 1 ""))]
9912 "TARGET_SSE_MATH && reload_completed"
9915 ix86_split_copysign_var (operands);
9919 (define_expand "negdf2"
9920 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9921 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9922 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9923 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9925 (define_expand "absdf2"
9926 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9927 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9928 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9929 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9931 (define_insn "*absnegdf2_mixed"
9932 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
9933 (match_operator:DF 3 "absneg_operator"
9934 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9935 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
9936 (clobber (reg:CC FLAGS_REG))]
9937 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9938 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9941 (define_insn "*absnegdf2_sse"
9942 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
9943 (match_operator:DF 3 "absneg_operator"
9944 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
9945 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
9946 (clobber (reg:CC FLAGS_REG))]
9947 "TARGET_SSE2 && TARGET_SSE_MATH
9948 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9951 (define_insn "*absnegdf2_i387"
9952 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9953 (match_operator:DF 3 "absneg_operator"
9954 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9955 (use (match_operand 2 "" ""))
9956 (clobber (reg:CC FLAGS_REG))]
9957 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9958 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9961 (define_expand "copysigndf3"
9962 [(match_operand:DF 0 "register_operand" "")
9963 (match_operand:DF 1 "nonmemory_operand" "")
9964 (match_operand:DF 2 "register_operand" "")]
9965 "TARGET_SSE2 && TARGET_SSE_MATH"
9967 ix86_expand_copysign (operands);
9971 (define_insn_and_split "copysigndf3_const"
9972 [(set (match_operand:DF 0 "register_operand" "=x")
9974 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9975 (match_operand:DF 2 "register_operand" "0")
9976 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9978 "TARGET_SSE2 && TARGET_SSE_MATH"
9980 "&& reload_completed"
9983 ix86_split_copysign_const (operands);
9987 (define_insn "copysigndf3_var"
9988 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9990 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9991 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9992 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9993 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9995 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9996 "TARGET_SSE2 && TARGET_SSE_MATH"
10000 [(set (match_operand:DF 0 "register_operand" "")
10002 [(match_operand:DF 2 "register_operand" "")
10003 (match_operand:DF 3 "register_operand" "")
10004 (match_operand:V2DF 4 "" "")
10005 (match_operand:V2DF 5 "" "")]
10007 (clobber (match_scratch:V2DF 1 ""))]
10008 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10011 ix86_split_copysign_var (operands);
10015 (define_expand "negxf2"
10016 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10017 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10019 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10021 (define_expand "absxf2"
10022 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10023 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10025 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10027 (define_insn "*absnegxf2_i387"
10028 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10029 (match_operator:XF 3 "absneg_operator"
10030 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10031 (use (match_operand 2 "" ""))
10032 (clobber (reg:CC FLAGS_REG))]
10034 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10037 ;; Splitters for fp abs and neg.
10040 [(set (match_operand 0 "fp_register_operand" "")
10041 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10042 (use (match_operand 2 "" ""))
10043 (clobber (reg:CC FLAGS_REG))]
10045 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10048 [(set (match_operand 0 "register_operand" "")
10049 (match_operator 3 "absneg_operator"
10050 [(match_operand 1 "register_operand" "")]))
10051 (use (match_operand 2 "nonimmediate_operand" ""))
10052 (clobber (reg:CC FLAGS_REG))]
10053 "reload_completed && SSE_REG_P (operands[0])"
10054 [(set (match_dup 0) (match_dup 3))]
10056 enum machine_mode mode = GET_MODE (operands[0]);
10057 enum machine_mode vmode = GET_MODE (operands[2]);
10060 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10061 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10062 if (operands_match_p (operands[0], operands[2]))
10065 operands[1] = operands[2];
10068 if (GET_CODE (operands[3]) == ABS)
10069 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10071 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10076 [(set (match_operand:SF 0 "register_operand" "")
10077 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10078 (use (match_operand:V4SF 2 "" ""))
10079 (clobber (reg:CC FLAGS_REG))]
10081 [(parallel [(set (match_dup 0) (match_dup 1))
10082 (clobber (reg:CC FLAGS_REG))])]
10085 operands[0] = gen_lowpart (SImode, operands[0]);
10086 if (GET_CODE (operands[1]) == ABS)
10088 tmp = gen_int_mode (0x7fffffff, SImode);
10089 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10093 tmp = gen_int_mode (0x80000000, SImode);
10094 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10100 [(set (match_operand:DF 0 "register_operand" "")
10101 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10102 (use (match_operand 2 "" ""))
10103 (clobber (reg:CC FLAGS_REG))]
10105 [(parallel [(set (match_dup 0) (match_dup 1))
10106 (clobber (reg:CC FLAGS_REG))])]
10111 tmp = gen_lowpart (DImode, operands[0]);
10112 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10115 if (GET_CODE (operands[1]) == ABS)
10118 tmp = gen_rtx_NOT (DImode, tmp);
10122 operands[0] = gen_highpart (SImode, operands[0]);
10123 if (GET_CODE (operands[1]) == ABS)
10125 tmp = gen_int_mode (0x7fffffff, SImode);
10126 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10130 tmp = gen_int_mode (0x80000000, SImode);
10131 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10138 [(set (match_operand:XF 0 "register_operand" "")
10139 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10140 (use (match_operand 2 "" ""))
10141 (clobber (reg:CC FLAGS_REG))]
10143 [(parallel [(set (match_dup 0) (match_dup 1))
10144 (clobber (reg:CC FLAGS_REG))])]
10147 operands[0] = gen_rtx_REG (SImode,
10148 true_regnum (operands[0])
10149 + (TARGET_64BIT ? 1 : 2));
10150 if (GET_CODE (operands[1]) == ABS)
10152 tmp = GEN_INT (0x7fff);
10153 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10157 tmp = GEN_INT (0x8000);
10158 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10164 [(set (match_operand 0 "memory_operand" "")
10165 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10166 (use (match_operand 2 "" ""))
10167 (clobber (reg:CC FLAGS_REG))]
10169 [(parallel [(set (match_dup 0) (match_dup 1))
10170 (clobber (reg:CC FLAGS_REG))])]
10172 enum machine_mode mode = GET_MODE (operands[0]);
10173 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10176 operands[0] = adjust_address (operands[0], QImode, size - 1);
10177 if (GET_CODE (operands[1]) == ABS)
10179 tmp = gen_int_mode (0x7f, QImode);
10180 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10184 tmp = gen_int_mode (0x80, QImode);
10185 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10190 ;; Conditionalize these after reload. If they match before reload, we
10191 ;; lose the clobber and ability to use integer instructions.
10193 (define_insn "*negsf2_1"
10194 [(set (match_operand:SF 0 "register_operand" "=f")
10195 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10196 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10198 [(set_attr "type" "fsgn")
10199 (set_attr "mode" "SF")])
10201 (define_insn "*negdf2_1"
10202 [(set (match_operand:DF 0 "register_operand" "=f")
10203 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10204 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10206 [(set_attr "type" "fsgn")
10207 (set_attr "mode" "DF")])
10209 (define_insn "*negxf2_1"
10210 [(set (match_operand:XF 0 "register_operand" "=f")
10211 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10214 [(set_attr "type" "fsgn")
10215 (set_attr "mode" "XF")])
10217 (define_insn "*abssf2_1"
10218 [(set (match_operand:SF 0 "register_operand" "=f")
10219 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10220 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10222 [(set_attr "type" "fsgn")
10223 (set_attr "mode" "SF")])
10225 (define_insn "*absdf2_1"
10226 [(set (match_operand:DF 0 "register_operand" "=f")
10227 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10228 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10230 [(set_attr "type" "fsgn")
10231 (set_attr "mode" "DF")])
10233 (define_insn "*absxf2_1"
10234 [(set (match_operand:XF 0 "register_operand" "=f")
10235 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10238 [(set_attr "type" "fsgn")
10239 (set_attr "mode" "DF")])
10241 (define_insn "*negextendsfdf2"
10242 [(set (match_operand:DF 0 "register_operand" "=f")
10243 (neg:DF (float_extend:DF
10244 (match_operand:SF 1 "register_operand" "0"))))]
10245 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10247 [(set_attr "type" "fsgn")
10248 (set_attr "mode" "DF")])
10250 (define_insn "*negextenddfxf2"
10251 [(set (match_operand:XF 0 "register_operand" "=f")
10252 (neg:XF (float_extend:XF
10253 (match_operand:DF 1 "register_operand" "0"))))]
10256 [(set_attr "type" "fsgn")
10257 (set_attr "mode" "XF")])
10259 (define_insn "*negextendsfxf2"
10260 [(set (match_operand:XF 0 "register_operand" "=f")
10261 (neg:XF (float_extend:XF
10262 (match_operand:SF 1 "register_operand" "0"))))]
10265 [(set_attr "type" "fsgn")
10266 (set_attr "mode" "XF")])
10268 (define_insn "*absextendsfdf2"
10269 [(set (match_operand:DF 0 "register_operand" "=f")
10270 (abs:DF (float_extend:DF
10271 (match_operand:SF 1 "register_operand" "0"))))]
10272 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10274 [(set_attr "type" "fsgn")
10275 (set_attr "mode" "DF")])
10277 (define_insn "*absextenddfxf2"
10278 [(set (match_operand:XF 0 "register_operand" "=f")
10279 (abs:XF (float_extend:XF
10280 (match_operand:DF 1 "register_operand" "0"))))]
10283 [(set_attr "type" "fsgn")
10284 (set_attr "mode" "XF")])
10286 (define_insn "*absextendsfxf2"
10287 [(set (match_operand:XF 0 "register_operand" "=f")
10288 (abs:XF (float_extend:XF
10289 (match_operand:SF 1 "register_operand" "0"))))]
10292 [(set_attr "type" "fsgn")
10293 (set_attr "mode" "XF")])
10295 ;; One complement instructions
10297 (define_expand "one_cmpldi2"
10298 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10299 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10301 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10303 (define_insn "*one_cmpldi2_1_rex64"
10304 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10305 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10306 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10308 [(set_attr "type" "negnot")
10309 (set_attr "mode" "DI")])
10311 (define_insn "*one_cmpldi2_2_rex64"
10312 [(set (reg FLAGS_REG)
10313 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10315 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10316 (not:DI (match_dup 1)))]
10317 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10318 && ix86_unary_operator_ok (NOT, DImode, operands)"
10320 [(set_attr "type" "alu1")
10321 (set_attr "mode" "DI")])
10324 [(set (match_operand 0 "flags_reg_operand" "")
10325 (match_operator 2 "compare_operator"
10326 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10328 (set (match_operand:DI 1 "nonimmediate_operand" "")
10329 (not:DI (match_dup 3)))]
10330 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10331 [(parallel [(set (match_dup 0)
10333 [(xor:DI (match_dup 3) (const_int -1))
10336 (xor:DI (match_dup 3) (const_int -1)))])]
10339 (define_expand "one_cmplsi2"
10340 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10341 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10343 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10345 (define_insn "*one_cmplsi2_1"
10346 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10347 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10348 "ix86_unary_operator_ok (NOT, SImode, operands)"
10350 [(set_attr "type" "negnot")
10351 (set_attr "mode" "SI")])
10353 ;; ??? Currently never generated - xor is used instead.
10354 (define_insn "*one_cmplsi2_1_zext"
10355 [(set (match_operand:DI 0 "register_operand" "=r")
10356 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10357 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10359 [(set_attr "type" "negnot")
10360 (set_attr "mode" "SI")])
10362 (define_insn "*one_cmplsi2_2"
10363 [(set (reg FLAGS_REG)
10364 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10366 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10367 (not:SI (match_dup 1)))]
10368 "ix86_match_ccmode (insn, CCNOmode)
10369 && ix86_unary_operator_ok (NOT, SImode, operands)"
10371 [(set_attr "type" "alu1")
10372 (set_attr "mode" "SI")])
10375 [(set (match_operand 0 "flags_reg_operand" "")
10376 (match_operator 2 "compare_operator"
10377 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10379 (set (match_operand:SI 1 "nonimmediate_operand" "")
10380 (not:SI (match_dup 3)))]
10381 "ix86_match_ccmode (insn, CCNOmode)"
10382 [(parallel [(set (match_dup 0)
10383 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10386 (xor:SI (match_dup 3) (const_int -1)))])]
10389 ;; ??? Currently never generated - xor is used instead.
10390 (define_insn "*one_cmplsi2_2_zext"
10391 [(set (reg FLAGS_REG)
10392 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10394 (set (match_operand:DI 0 "register_operand" "=r")
10395 (zero_extend:DI (not:SI (match_dup 1))))]
10396 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10397 && ix86_unary_operator_ok (NOT, SImode, operands)"
10399 [(set_attr "type" "alu1")
10400 (set_attr "mode" "SI")])
10403 [(set (match_operand 0 "flags_reg_operand" "")
10404 (match_operator 2 "compare_operator"
10405 [(not:SI (match_operand:SI 3 "register_operand" ""))
10407 (set (match_operand:DI 1 "register_operand" "")
10408 (zero_extend:DI (not:SI (match_dup 3))))]
10409 "ix86_match_ccmode (insn, CCNOmode)"
10410 [(parallel [(set (match_dup 0)
10411 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10414 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10417 (define_expand "one_cmplhi2"
10418 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10419 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10420 "TARGET_HIMODE_MATH"
10421 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10423 (define_insn "*one_cmplhi2_1"
10424 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10425 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10426 "ix86_unary_operator_ok (NOT, HImode, operands)"
10428 [(set_attr "type" "negnot")
10429 (set_attr "mode" "HI")])
10431 (define_insn "*one_cmplhi2_2"
10432 [(set (reg FLAGS_REG)
10433 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10435 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10436 (not:HI (match_dup 1)))]
10437 "ix86_match_ccmode (insn, CCNOmode)
10438 && ix86_unary_operator_ok (NEG, HImode, operands)"
10440 [(set_attr "type" "alu1")
10441 (set_attr "mode" "HI")])
10444 [(set (match_operand 0 "flags_reg_operand" "")
10445 (match_operator 2 "compare_operator"
10446 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10448 (set (match_operand:HI 1 "nonimmediate_operand" "")
10449 (not:HI (match_dup 3)))]
10450 "ix86_match_ccmode (insn, CCNOmode)"
10451 [(parallel [(set (match_dup 0)
10452 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10455 (xor:HI (match_dup 3) (const_int -1)))])]
10458 ;; %%% Potential partial reg stall on alternative 1. What to do?
10459 (define_expand "one_cmplqi2"
10460 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10461 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10462 "TARGET_QIMODE_MATH"
10463 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10465 (define_insn "*one_cmplqi2_1"
10466 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10467 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10468 "ix86_unary_operator_ok (NOT, QImode, operands)"
10472 [(set_attr "type" "negnot")
10473 (set_attr "mode" "QI,SI")])
10475 (define_insn "*one_cmplqi2_2"
10476 [(set (reg FLAGS_REG)
10477 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10479 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10480 (not:QI (match_dup 1)))]
10481 "ix86_match_ccmode (insn, CCNOmode)
10482 && ix86_unary_operator_ok (NOT, QImode, operands)"
10484 [(set_attr "type" "alu1")
10485 (set_attr "mode" "QI")])
10488 [(set (match_operand 0 "flags_reg_operand" "")
10489 (match_operator 2 "compare_operator"
10490 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10492 (set (match_operand:QI 1 "nonimmediate_operand" "")
10493 (not:QI (match_dup 3)))]
10494 "ix86_match_ccmode (insn, CCNOmode)"
10495 [(parallel [(set (match_dup 0)
10496 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10499 (xor:QI (match_dup 3) (const_int -1)))])]
10502 ;; Arithmetic shift instructions
10504 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10505 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10506 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10507 ;; from the assembler input.
10509 ;; This instruction shifts the target reg/mem as usual, but instead of
10510 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10511 ;; is a left shift double, bits are taken from the high order bits of
10512 ;; reg, else if the insn is a shift right double, bits are taken from the
10513 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10514 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10516 ;; Since sh[lr]d does not change the `reg' operand, that is done
10517 ;; separately, making all shifts emit pairs of shift double and normal
10518 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10519 ;; support a 63 bit shift, each shift where the count is in a reg expands
10520 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10522 ;; If the shift count is a constant, we need never emit more than one
10523 ;; shift pair, instead using moves and sign extension for counts greater
10526 (define_expand "ashlti3"
10527 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10528 (ashift:TI (match_operand:TI 1 "register_operand" "")
10529 (match_operand:QI 2 "nonmemory_operand" "")))
10530 (clobber (reg:CC FLAGS_REG))])]
10533 if (! immediate_operand (operands[2], QImode))
10535 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10538 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10542 (define_insn "ashlti3_1"
10543 [(set (match_operand:TI 0 "register_operand" "=r")
10544 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10545 (match_operand:QI 2 "register_operand" "c")))
10546 (clobber (match_scratch:DI 3 "=&r"))
10547 (clobber (reg:CC FLAGS_REG))]
10550 [(set_attr "type" "multi")])
10552 (define_insn "*ashlti3_2"
10553 [(set (match_operand:TI 0 "register_operand" "=r")
10554 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10555 (match_operand:QI 2 "immediate_operand" "O")))
10556 (clobber (reg:CC FLAGS_REG))]
10559 [(set_attr "type" "multi")])
10562 [(set (match_operand:TI 0 "register_operand" "")
10563 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10564 (match_operand:QI 2 "register_operand" "")))
10565 (clobber (match_scratch:DI 3 ""))
10566 (clobber (reg:CC FLAGS_REG))]
10567 "TARGET_64BIT && reload_completed"
10569 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10572 [(set (match_operand:TI 0 "register_operand" "")
10573 (ashift:TI (match_operand:TI 1 "register_operand" "")
10574 (match_operand:QI 2 "immediate_operand" "")))
10575 (clobber (reg:CC FLAGS_REG))]
10576 "TARGET_64BIT && reload_completed"
10578 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10580 (define_insn "x86_64_shld"
10581 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10582 (ior:DI (ashift:DI (match_dup 0)
10583 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10584 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10585 (minus:QI (const_int 64) (match_dup 2)))))
10586 (clobber (reg:CC FLAGS_REG))]
10589 shld{q}\t{%2, %1, %0|%0, %1, %2}
10590 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10591 [(set_attr "type" "ishift")
10592 (set_attr "prefix_0f" "1")
10593 (set_attr "mode" "DI")
10594 (set_attr "athlon_decode" "vector")
10595 (set_attr "amdfam10_decode" "vector")])
10597 (define_expand "x86_64_shift_adj"
10598 [(set (reg:CCZ FLAGS_REG)
10599 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10602 (set (match_operand:DI 0 "register_operand" "")
10603 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10604 (match_operand:DI 1 "register_operand" "")
10607 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10608 (match_operand:DI 3 "register_operand" "r")
10613 (define_expand "ashldi3"
10614 [(set (match_operand:DI 0 "shiftdi_operand" "")
10615 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10616 (match_operand:QI 2 "nonmemory_operand" "")))]
10618 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10620 (define_insn "*ashldi3_1_rex64"
10621 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10622 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10623 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10624 (clobber (reg:CC FLAGS_REG))]
10625 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10627 switch (get_attr_type (insn))
10630 gcc_assert (operands[2] == const1_rtx);
10631 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10632 return "add{q}\t{%0, %0|%0, %0}";
10635 gcc_assert (CONST_INT_P (operands[2]));
10636 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10637 operands[1] = gen_rtx_MULT (DImode, operands[1],
10638 GEN_INT (1 << INTVAL (operands[2])));
10639 return "lea{q}\t{%a1, %0|%0, %a1}";
10642 if (REG_P (operands[2]))
10643 return "sal{q}\t{%b2, %0|%0, %b2}";
10644 else if (operands[2] == const1_rtx
10645 && (TARGET_SHIFT1 || optimize_size))
10646 return "sal{q}\t%0";
10648 return "sal{q}\t{%2, %0|%0, %2}";
10651 [(set (attr "type")
10652 (cond [(eq_attr "alternative" "1")
10653 (const_string "lea")
10654 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10656 (match_operand 0 "register_operand" ""))
10657 (match_operand 2 "const1_operand" ""))
10658 (const_string "alu")
10660 (const_string "ishift")))
10661 (set_attr "mode" "DI")])
10663 ;; Convert lea to the lea pattern to avoid flags dependency.
10665 [(set (match_operand:DI 0 "register_operand" "")
10666 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10667 (match_operand:QI 2 "immediate_operand" "")))
10668 (clobber (reg:CC FLAGS_REG))]
10669 "TARGET_64BIT && reload_completed
10670 && true_regnum (operands[0]) != true_regnum (operands[1])"
10671 [(set (match_dup 0)
10672 (mult:DI (match_dup 1)
10674 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10676 ;; This pattern can't accept a variable shift count, since shifts by
10677 ;; zero don't affect the flags. We assume that shifts by constant
10678 ;; zero are optimized away.
10679 (define_insn "*ashldi3_cmp_rex64"
10680 [(set (reg FLAGS_REG)
10682 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10683 (match_operand:QI 2 "immediate_operand" "e"))
10685 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10686 (ashift:DI (match_dup 1) (match_dup 2)))]
10687 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10688 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10690 || !TARGET_PARTIAL_FLAG_REG_STALL
10691 || (operands[2] == const1_rtx
10693 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10695 switch (get_attr_type (insn))
10698 gcc_assert (operands[2] == const1_rtx);
10699 return "add{q}\t{%0, %0|%0, %0}";
10702 if (REG_P (operands[2]))
10703 return "sal{q}\t{%b2, %0|%0, %b2}";
10704 else if (operands[2] == const1_rtx
10705 && (TARGET_SHIFT1 || optimize_size))
10706 return "sal{q}\t%0";
10708 return "sal{q}\t{%2, %0|%0, %2}";
10711 [(set (attr "type")
10712 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10714 (match_operand 0 "register_operand" ""))
10715 (match_operand 2 "const1_operand" ""))
10716 (const_string "alu")
10718 (const_string "ishift")))
10719 (set_attr "mode" "DI")])
10721 (define_insn "*ashldi3_cconly_rex64"
10722 [(set (reg FLAGS_REG)
10724 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10725 (match_operand:QI 2 "immediate_operand" "e"))
10727 (clobber (match_scratch:DI 0 "=r"))]
10728 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10729 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10731 || !TARGET_PARTIAL_FLAG_REG_STALL
10732 || (operands[2] == const1_rtx
10734 || TARGET_DOUBLE_WITH_ADD)))"
10736 switch (get_attr_type (insn))
10739 gcc_assert (operands[2] == const1_rtx);
10740 return "add{q}\t{%0, %0|%0, %0}";
10743 if (REG_P (operands[2]))
10744 return "sal{q}\t{%b2, %0|%0, %b2}";
10745 else if (operands[2] == const1_rtx
10746 && (TARGET_SHIFT1 || optimize_size))
10747 return "sal{q}\t%0";
10749 return "sal{q}\t{%2, %0|%0, %2}";
10752 [(set (attr "type")
10753 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10755 (match_operand 0 "register_operand" ""))
10756 (match_operand 2 "const1_operand" ""))
10757 (const_string "alu")
10759 (const_string "ishift")))
10760 (set_attr "mode" "DI")])
10762 (define_insn "*ashldi3_1"
10763 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10764 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10765 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10766 (clobber (reg:CC FLAGS_REG))]
10769 [(set_attr "type" "multi")])
10771 ;; By default we don't ask for a scratch register, because when DImode
10772 ;; values are manipulated, registers are already at a premium. But if
10773 ;; we have one handy, we won't turn it away.
10775 [(match_scratch:SI 3 "r")
10776 (parallel [(set (match_operand:DI 0 "register_operand" "")
10777 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10778 (match_operand:QI 2 "nonmemory_operand" "")))
10779 (clobber (reg:CC FLAGS_REG))])
10781 "!TARGET_64BIT && TARGET_CMOVE"
10783 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10786 [(set (match_operand:DI 0 "register_operand" "")
10787 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10788 (match_operand:QI 2 "nonmemory_operand" "")))
10789 (clobber (reg:CC FLAGS_REG))]
10790 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10791 ? flow2_completed : reload_completed)"
10793 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10795 (define_insn "x86_shld_1"
10796 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10797 (ior:SI (ashift:SI (match_dup 0)
10798 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10799 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10800 (minus:QI (const_int 32) (match_dup 2)))))
10801 (clobber (reg:CC FLAGS_REG))]
10804 shld{l}\t{%2, %1, %0|%0, %1, %2}
10805 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10806 [(set_attr "type" "ishift")
10807 (set_attr "prefix_0f" "1")
10808 (set_attr "mode" "SI")
10809 (set_attr "pent_pair" "np")
10810 (set_attr "athlon_decode" "vector")
10811 (set_attr "amdfam10_decode" "vector")])
10813 (define_expand "x86_shift_adj_1"
10814 [(set (reg:CCZ FLAGS_REG)
10815 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10818 (set (match_operand:SI 0 "register_operand" "")
10819 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10820 (match_operand:SI 1 "register_operand" "")
10823 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10824 (match_operand:SI 3 "register_operand" "r")
10829 (define_expand "x86_shift_adj_2"
10830 [(use (match_operand:SI 0 "register_operand" ""))
10831 (use (match_operand:SI 1 "register_operand" ""))
10832 (use (match_operand:QI 2 "register_operand" ""))]
10835 rtx label = gen_label_rtx ();
10838 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10840 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10841 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10842 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10843 gen_rtx_LABEL_REF (VOIDmode, label),
10845 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10846 JUMP_LABEL (tmp) = label;
10848 emit_move_insn (operands[0], operands[1]);
10849 ix86_expand_clear (operands[1]);
10851 emit_label (label);
10852 LABEL_NUSES (label) = 1;
10857 (define_expand "ashlsi3"
10858 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10859 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10860 (match_operand:QI 2 "nonmemory_operand" "")))
10861 (clobber (reg:CC FLAGS_REG))]
10863 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10865 (define_insn "*ashlsi3_1"
10866 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10867 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10868 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10869 (clobber (reg:CC FLAGS_REG))]
10870 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10872 switch (get_attr_type (insn))
10875 gcc_assert (operands[2] == const1_rtx);
10876 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10877 return "add{l}\t{%0, %0|%0, %0}";
10883 if (REG_P (operands[2]))
10884 return "sal{l}\t{%b2, %0|%0, %b2}";
10885 else if (operands[2] == const1_rtx
10886 && (TARGET_SHIFT1 || optimize_size))
10887 return "sal{l}\t%0";
10889 return "sal{l}\t{%2, %0|%0, %2}";
10892 [(set (attr "type")
10893 (cond [(eq_attr "alternative" "1")
10894 (const_string "lea")
10895 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10897 (match_operand 0 "register_operand" ""))
10898 (match_operand 2 "const1_operand" ""))
10899 (const_string "alu")
10901 (const_string "ishift")))
10902 (set_attr "mode" "SI")])
10904 ;; Convert lea to the lea pattern to avoid flags dependency.
10906 [(set (match_operand 0 "register_operand" "")
10907 (ashift (match_operand 1 "index_register_operand" "")
10908 (match_operand:QI 2 "const_int_operand" "")))
10909 (clobber (reg:CC FLAGS_REG))]
10911 && true_regnum (operands[0]) != true_regnum (operands[1])
10912 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10916 enum machine_mode mode = GET_MODE (operands[0]);
10918 if (GET_MODE_SIZE (mode) < 4)
10919 operands[0] = gen_lowpart (SImode, operands[0]);
10921 operands[1] = gen_lowpart (Pmode, operands[1]);
10922 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10924 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10925 if (Pmode != SImode)
10926 pat = gen_rtx_SUBREG (SImode, pat, 0);
10927 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10931 ;; Rare case of shifting RSP is handled by generating move and shift
10933 [(set (match_operand 0 "register_operand" "")
10934 (ashift (match_operand 1 "register_operand" "")
10935 (match_operand:QI 2 "const_int_operand" "")))
10936 (clobber (reg:CC FLAGS_REG))]
10938 && true_regnum (operands[0]) != true_regnum (operands[1])"
10942 emit_move_insn (operands[0], operands[1]);
10943 pat = gen_rtx_SET (VOIDmode, operands[0],
10944 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10945 operands[0], operands[2]));
10946 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10947 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10951 (define_insn "*ashlsi3_1_zext"
10952 [(set (match_operand:DI 0 "register_operand" "=r,r")
10953 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10954 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10955 (clobber (reg:CC FLAGS_REG))]
10956 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10958 switch (get_attr_type (insn))
10961 gcc_assert (operands[2] == const1_rtx);
10962 return "add{l}\t{%k0, %k0|%k0, %k0}";
10968 if (REG_P (operands[2]))
10969 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10970 else if (operands[2] == const1_rtx
10971 && (TARGET_SHIFT1 || optimize_size))
10972 return "sal{l}\t%k0";
10974 return "sal{l}\t{%2, %k0|%k0, %2}";
10977 [(set (attr "type")
10978 (cond [(eq_attr "alternative" "1")
10979 (const_string "lea")
10980 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10982 (match_operand 2 "const1_operand" ""))
10983 (const_string "alu")
10985 (const_string "ishift")))
10986 (set_attr "mode" "SI")])
10988 ;; Convert lea to the lea pattern to avoid flags dependency.
10990 [(set (match_operand:DI 0 "register_operand" "")
10991 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10992 (match_operand:QI 2 "const_int_operand" ""))))
10993 (clobber (reg:CC FLAGS_REG))]
10994 "TARGET_64BIT && reload_completed
10995 && true_regnum (operands[0]) != true_regnum (operands[1])"
10996 [(set (match_dup 0) (zero_extend:DI
10997 (subreg:SI (mult:SI (match_dup 1)
10998 (match_dup 2)) 0)))]
11000 operands[1] = gen_lowpart (Pmode, operands[1]);
11001 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11004 ;; This pattern can't accept a variable shift count, since shifts by
11005 ;; zero don't affect the flags. We assume that shifts by constant
11006 ;; zero are optimized away.
11007 (define_insn "*ashlsi3_cmp"
11008 [(set (reg FLAGS_REG)
11010 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11011 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11013 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11014 (ashift:SI (match_dup 1) (match_dup 2)))]
11015 "ix86_match_ccmode (insn, CCGOCmode)
11016 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11018 || !TARGET_PARTIAL_FLAG_REG_STALL
11019 || (operands[2] == const1_rtx
11021 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11023 switch (get_attr_type (insn))
11026 gcc_assert (operands[2] == const1_rtx);
11027 return "add{l}\t{%0, %0|%0, %0}";
11030 if (REG_P (operands[2]))
11031 return "sal{l}\t{%b2, %0|%0, %b2}";
11032 else if (operands[2] == const1_rtx
11033 && (TARGET_SHIFT1 || optimize_size))
11034 return "sal{l}\t%0";
11036 return "sal{l}\t{%2, %0|%0, %2}";
11039 [(set (attr "type")
11040 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11042 (match_operand 0 "register_operand" ""))
11043 (match_operand 2 "const1_operand" ""))
11044 (const_string "alu")
11046 (const_string "ishift")))
11047 (set_attr "mode" "SI")])
11049 (define_insn "*ashlsi3_cconly"
11050 [(set (reg FLAGS_REG)
11052 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11053 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11055 (clobber (match_scratch:SI 0 "=r"))]
11056 "ix86_match_ccmode (insn, CCGOCmode)
11057 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11059 || !TARGET_PARTIAL_FLAG_REG_STALL
11060 || (operands[2] == const1_rtx
11062 || TARGET_DOUBLE_WITH_ADD)))"
11064 switch (get_attr_type (insn))
11067 gcc_assert (operands[2] == const1_rtx);
11068 return "add{l}\t{%0, %0|%0, %0}";
11071 if (REG_P (operands[2]))
11072 return "sal{l}\t{%b2, %0|%0, %b2}";
11073 else if (operands[2] == const1_rtx
11074 && (TARGET_SHIFT1 || optimize_size))
11075 return "sal{l}\t%0";
11077 return "sal{l}\t{%2, %0|%0, %2}";
11080 [(set (attr "type")
11081 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11083 (match_operand 0 "register_operand" ""))
11084 (match_operand 2 "const1_operand" ""))
11085 (const_string "alu")
11087 (const_string "ishift")))
11088 (set_attr "mode" "SI")])
11090 (define_insn "*ashlsi3_cmp_zext"
11091 [(set (reg FLAGS_REG)
11093 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11094 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11096 (set (match_operand:DI 0 "register_operand" "=r")
11097 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11098 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11099 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11101 || !TARGET_PARTIAL_FLAG_REG_STALL
11102 || (operands[2] == const1_rtx
11104 || TARGET_DOUBLE_WITH_ADD)))"
11106 switch (get_attr_type (insn))
11109 gcc_assert (operands[2] == const1_rtx);
11110 return "add{l}\t{%k0, %k0|%k0, %k0}";
11113 if (REG_P (operands[2]))
11114 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11115 else if (operands[2] == const1_rtx
11116 && (TARGET_SHIFT1 || optimize_size))
11117 return "sal{l}\t%k0";
11119 return "sal{l}\t{%2, %k0|%k0, %2}";
11122 [(set (attr "type")
11123 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11125 (match_operand 2 "const1_operand" ""))
11126 (const_string "alu")
11128 (const_string "ishift")))
11129 (set_attr "mode" "SI")])
11131 (define_expand "ashlhi3"
11132 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11133 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11134 (match_operand:QI 2 "nonmemory_operand" "")))
11135 (clobber (reg:CC FLAGS_REG))]
11136 "TARGET_HIMODE_MATH"
11137 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11139 (define_insn "*ashlhi3_1_lea"
11140 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11141 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11142 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11143 (clobber (reg:CC FLAGS_REG))]
11144 "!TARGET_PARTIAL_REG_STALL
11145 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11147 switch (get_attr_type (insn))
11152 gcc_assert (operands[2] == const1_rtx);
11153 return "add{w}\t{%0, %0|%0, %0}";
11156 if (REG_P (operands[2]))
11157 return "sal{w}\t{%b2, %0|%0, %b2}";
11158 else if (operands[2] == const1_rtx
11159 && (TARGET_SHIFT1 || optimize_size))
11160 return "sal{w}\t%0";
11162 return "sal{w}\t{%2, %0|%0, %2}";
11165 [(set (attr "type")
11166 (cond [(eq_attr "alternative" "1")
11167 (const_string "lea")
11168 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11170 (match_operand 0 "register_operand" ""))
11171 (match_operand 2 "const1_operand" ""))
11172 (const_string "alu")
11174 (const_string "ishift")))
11175 (set_attr "mode" "HI,SI")])
11177 (define_insn "*ashlhi3_1"
11178 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11179 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11180 (match_operand:QI 2 "nonmemory_operand" "cI")))
11181 (clobber (reg:CC FLAGS_REG))]
11182 "TARGET_PARTIAL_REG_STALL
11183 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11185 switch (get_attr_type (insn))
11188 gcc_assert (operands[2] == const1_rtx);
11189 return "add{w}\t{%0, %0|%0, %0}";
11192 if (REG_P (operands[2]))
11193 return "sal{w}\t{%b2, %0|%0, %b2}";
11194 else if (operands[2] == const1_rtx
11195 && (TARGET_SHIFT1 || optimize_size))
11196 return "sal{w}\t%0";
11198 return "sal{w}\t{%2, %0|%0, %2}";
11201 [(set (attr "type")
11202 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11204 (match_operand 0 "register_operand" ""))
11205 (match_operand 2 "const1_operand" ""))
11206 (const_string "alu")
11208 (const_string "ishift")))
11209 (set_attr "mode" "HI")])
11211 ;; This pattern can't accept a variable shift count, since shifts by
11212 ;; zero don't affect the flags. We assume that shifts by constant
11213 ;; zero are optimized away.
11214 (define_insn "*ashlhi3_cmp"
11215 [(set (reg FLAGS_REG)
11217 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11218 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11220 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11221 (ashift:HI (match_dup 1) (match_dup 2)))]
11222 "ix86_match_ccmode (insn, CCGOCmode)
11223 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11225 || !TARGET_PARTIAL_FLAG_REG_STALL
11226 || (operands[2] == const1_rtx
11228 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11230 switch (get_attr_type (insn))
11233 gcc_assert (operands[2] == const1_rtx);
11234 return "add{w}\t{%0, %0|%0, %0}";
11237 if (REG_P (operands[2]))
11238 return "sal{w}\t{%b2, %0|%0, %b2}";
11239 else if (operands[2] == const1_rtx
11240 && (TARGET_SHIFT1 || optimize_size))
11241 return "sal{w}\t%0";
11243 return "sal{w}\t{%2, %0|%0, %2}";
11246 [(set (attr "type")
11247 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11249 (match_operand 0 "register_operand" ""))
11250 (match_operand 2 "const1_operand" ""))
11251 (const_string "alu")
11253 (const_string "ishift")))
11254 (set_attr "mode" "HI")])
11256 (define_insn "*ashlhi3_cconly"
11257 [(set (reg FLAGS_REG)
11259 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11260 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11262 (clobber (match_scratch:HI 0 "=r"))]
11263 "ix86_match_ccmode (insn, CCGOCmode)
11264 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11266 || !TARGET_PARTIAL_FLAG_REG_STALL
11267 || (operands[2] == const1_rtx
11269 || TARGET_DOUBLE_WITH_ADD)))"
11271 switch (get_attr_type (insn))
11274 gcc_assert (operands[2] == const1_rtx);
11275 return "add{w}\t{%0, %0|%0, %0}";
11278 if (REG_P (operands[2]))
11279 return "sal{w}\t{%b2, %0|%0, %b2}";
11280 else if (operands[2] == const1_rtx
11281 && (TARGET_SHIFT1 || optimize_size))
11282 return "sal{w}\t%0";
11284 return "sal{w}\t{%2, %0|%0, %2}";
11287 [(set (attr "type")
11288 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11290 (match_operand 0 "register_operand" ""))
11291 (match_operand 2 "const1_operand" ""))
11292 (const_string "alu")
11294 (const_string "ishift")))
11295 (set_attr "mode" "HI")])
11297 (define_expand "ashlqi3"
11298 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11299 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11300 (match_operand:QI 2 "nonmemory_operand" "")))
11301 (clobber (reg:CC FLAGS_REG))]
11302 "TARGET_QIMODE_MATH"
11303 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11305 ;; %%% Potential partial reg stall on alternative 2. What to do?
11307 (define_insn "*ashlqi3_1_lea"
11308 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11309 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11310 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11311 (clobber (reg:CC FLAGS_REG))]
11312 "!TARGET_PARTIAL_REG_STALL
11313 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11315 switch (get_attr_type (insn))
11320 gcc_assert (operands[2] == const1_rtx);
11321 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11322 return "add{l}\t{%k0, %k0|%k0, %k0}";
11324 return "add{b}\t{%0, %0|%0, %0}";
11327 if (REG_P (operands[2]))
11329 if (get_attr_mode (insn) == MODE_SI)
11330 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11332 return "sal{b}\t{%b2, %0|%0, %b2}";
11334 else if (operands[2] == const1_rtx
11335 && (TARGET_SHIFT1 || optimize_size))
11337 if (get_attr_mode (insn) == MODE_SI)
11338 return "sal{l}\t%0";
11340 return "sal{b}\t%0";
11344 if (get_attr_mode (insn) == MODE_SI)
11345 return "sal{l}\t{%2, %k0|%k0, %2}";
11347 return "sal{b}\t{%2, %0|%0, %2}";
11351 [(set (attr "type")
11352 (cond [(eq_attr "alternative" "2")
11353 (const_string "lea")
11354 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11356 (match_operand 0 "register_operand" ""))
11357 (match_operand 2 "const1_operand" ""))
11358 (const_string "alu")
11360 (const_string "ishift")))
11361 (set_attr "mode" "QI,SI,SI")])
11363 (define_insn "*ashlqi3_1"
11364 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11365 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11366 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11367 (clobber (reg:CC FLAGS_REG))]
11368 "TARGET_PARTIAL_REG_STALL
11369 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11371 switch (get_attr_type (insn))
11374 gcc_assert (operands[2] == const1_rtx);
11375 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11376 return "add{l}\t{%k0, %k0|%k0, %k0}";
11378 return "add{b}\t{%0, %0|%0, %0}";
11381 if (REG_P (operands[2]))
11383 if (get_attr_mode (insn) == MODE_SI)
11384 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11386 return "sal{b}\t{%b2, %0|%0, %b2}";
11388 else if (operands[2] == const1_rtx
11389 && (TARGET_SHIFT1 || optimize_size))
11391 if (get_attr_mode (insn) == MODE_SI)
11392 return "sal{l}\t%0";
11394 return "sal{b}\t%0";
11398 if (get_attr_mode (insn) == MODE_SI)
11399 return "sal{l}\t{%2, %k0|%k0, %2}";
11401 return "sal{b}\t{%2, %0|%0, %2}";
11405 [(set (attr "type")
11406 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11408 (match_operand 0 "register_operand" ""))
11409 (match_operand 2 "const1_operand" ""))
11410 (const_string "alu")
11412 (const_string "ishift")))
11413 (set_attr "mode" "QI,SI")])
11415 ;; This pattern can't accept a variable shift count, since shifts by
11416 ;; zero don't affect the flags. We assume that shifts by constant
11417 ;; zero are optimized away.
11418 (define_insn "*ashlqi3_cmp"
11419 [(set (reg FLAGS_REG)
11421 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11422 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11424 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11425 (ashift:QI (match_dup 1) (match_dup 2)))]
11426 "ix86_match_ccmode (insn, CCGOCmode)
11427 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11429 || !TARGET_PARTIAL_FLAG_REG_STALL
11430 || (operands[2] == const1_rtx
11432 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11434 switch (get_attr_type (insn))
11437 gcc_assert (operands[2] == const1_rtx);
11438 return "add{b}\t{%0, %0|%0, %0}";
11441 if (REG_P (operands[2]))
11442 return "sal{b}\t{%b2, %0|%0, %b2}";
11443 else if (operands[2] == const1_rtx
11444 && (TARGET_SHIFT1 || optimize_size))
11445 return "sal{b}\t%0";
11447 return "sal{b}\t{%2, %0|%0, %2}";
11450 [(set (attr "type")
11451 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11453 (match_operand 0 "register_operand" ""))
11454 (match_operand 2 "const1_operand" ""))
11455 (const_string "alu")
11457 (const_string "ishift")))
11458 (set_attr "mode" "QI")])
11460 (define_insn "*ashlqi3_cconly"
11461 [(set (reg FLAGS_REG)
11463 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11464 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11466 (clobber (match_scratch:QI 0 "=q"))]
11467 "ix86_match_ccmode (insn, CCGOCmode)
11468 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11470 || !TARGET_PARTIAL_FLAG_REG_STALL
11471 || (operands[2] == const1_rtx
11473 || TARGET_DOUBLE_WITH_ADD)))"
11475 switch (get_attr_type (insn))
11478 gcc_assert (operands[2] == const1_rtx);
11479 return "add{b}\t{%0, %0|%0, %0}";
11482 if (REG_P (operands[2]))
11483 return "sal{b}\t{%b2, %0|%0, %b2}";
11484 else if (operands[2] == const1_rtx
11485 && (TARGET_SHIFT1 || optimize_size))
11486 return "sal{b}\t%0";
11488 return "sal{b}\t{%2, %0|%0, %2}";
11491 [(set (attr "type")
11492 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11494 (match_operand 0 "register_operand" ""))
11495 (match_operand 2 "const1_operand" ""))
11496 (const_string "alu")
11498 (const_string "ishift")))
11499 (set_attr "mode" "QI")])
11501 ;; See comment above `ashldi3' about how this works.
11503 (define_expand "ashrti3"
11504 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11505 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11506 (match_operand:QI 2 "nonmemory_operand" "")))
11507 (clobber (reg:CC FLAGS_REG))])]
11510 if (! immediate_operand (operands[2], QImode))
11512 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11515 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11519 (define_insn "ashrti3_1"
11520 [(set (match_operand:TI 0 "register_operand" "=r")
11521 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11522 (match_operand:QI 2 "register_operand" "c")))
11523 (clobber (match_scratch:DI 3 "=&r"))
11524 (clobber (reg:CC FLAGS_REG))]
11527 [(set_attr "type" "multi")])
11529 (define_insn "*ashrti3_2"
11530 [(set (match_operand:TI 0 "register_operand" "=r")
11531 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11532 (match_operand:QI 2 "immediate_operand" "O")))
11533 (clobber (reg:CC FLAGS_REG))]
11536 [(set_attr "type" "multi")])
11539 [(set (match_operand:TI 0 "register_operand" "")
11540 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11541 (match_operand:QI 2 "register_operand" "")))
11542 (clobber (match_scratch:DI 3 ""))
11543 (clobber (reg:CC FLAGS_REG))]
11544 "TARGET_64BIT && reload_completed"
11546 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11549 [(set (match_operand:TI 0 "register_operand" "")
11550 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11551 (match_operand:QI 2 "immediate_operand" "")))
11552 (clobber (reg:CC FLAGS_REG))]
11553 "TARGET_64BIT && reload_completed"
11555 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11557 (define_insn "x86_64_shrd"
11558 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11559 (ior:DI (ashiftrt:DI (match_dup 0)
11560 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11561 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11562 (minus:QI (const_int 64) (match_dup 2)))))
11563 (clobber (reg:CC FLAGS_REG))]
11566 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11567 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11568 [(set_attr "type" "ishift")
11569 (set_attr "prefix_0f" "1")
11570 (set_attr "mode" "DI")
11571 (set_attr "athlon_decode" "vector")
11572 (set_attr "amdfam10_decode" "vector")])
11574 (define_expand "ashrdi3"
11575 [(set (match_operand:DI 0 "shiftdi_operand" "")
11576 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11577 (match_operand:QI 2 "nonmemory_operand" "")))]
11579 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11581 (define_insn "*ashrdi3_63_rex64"
11582 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11583 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11584 (match_operand:DI 2 "const_int_operand" "i,i")))
11585 (clobber (reg:CC FLAGS_REG))]
11586 "TARGET_64BIT && INTVAL (operands[2]) == 63
11587 && (TARGET_USE_CLTD || optimize_size)
11588 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11591 sar{q}\t{%2, %0|%0, %2}"
11592 [(set_attr "type" "imovx,ishift")
11593 (set_attr "prefix_0f" "0,*")
11594 (set_attr "length_immediate" "0,*")
11595 (set_attr "modrm" "0,1")
11596 (set_attr "mode" "DI")])
11598 (define_insn "*ashrdi3_1_one_bit_rex64"
11599 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11600 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11601 (match_operand:QI 2 "const1_operand" "")))
11602 (clobber (reg:CC FLAGS_REG))]
11603 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11604 && (TARGET_SHIFT1 || optimize_size)"
11606 [(set_attr "type" "ishift")
11607 (set (attr "length")
11608 (if_then_else (match_operand:DI 0 "register_operand" "")
11610 (const_string "*")))])
11612 (define_insn "*ashrdi3_1_rex64"
11613 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11614 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11615 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11616 (clobber (reg:CC FLAGS_REG))]
11617 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11619 sar{q}\t{%2, %0|%0, %2}
11620 sar{q}\t{%b2, %0|%0, %b2}"
11621 [(set_attr "type" "ishift")
11622 (set_attr "mode" "DI")])
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags. We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11628 [(set (reg FLAGS_REG)
11630 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11631 (match_operand:QI 2 "const1_operand" ""))
11633 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11634 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11635 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11636 && (TARGET_SHIFT1 || optimize_size)
11637 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11639 [(set_attr "type" "ishift")
11640 (set (attr "length")
11641 (if_then_else (match_operand:DI 0 "register_operand" "")
11643 (const_string "*")))])
11645 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11646 [(set (reg FLAGS_REG)
11648 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11649 (match_operand:QI 2 "const1_operand" ""))
11651 (clobber (match_scratch:DI 0 "=r"))]
11652 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11653 && (TARGET_SHIFT1 || optimize_size)
11654 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11656 [(set_attr "type" "ishift")
11657 (set_attr "length" "2")])
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags. We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*ashrdi3_cmp_rex64"
11663 [(set (reg FLAGS_REG)
11665 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11666 (match_operand:QI 2 "const_int_operand" "n"))
11668 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11669 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11670 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11671 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11673 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11674 "sar{q}\t{%2, %0|%0, %2}"
11675 [(set_attr "type" "ishift")
11676 (set_attr "mode" "DI")])
11678 (define_insn "*ashrdi3_cconly_rex64"
11679 [(set (reg FLAGS_REG)
11681 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11682 (match_operand:QI 2 "const_int_operand" "n"))
11684 (clobber (match_scratch:DI 0 "=r"))]
11685 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11686 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11688 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11689 "sar{q}\t{%2, %0|%0, %2}"
11690 [(set_attr "type" "ishift")
11691 (set_attr "mode" "DI")])
11693 (define_insn "*ashrdi3_1"
11694 [(set (match_operand:DI 0 "register_operand" "=r")
11695 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11696 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11697 (clobber (reg:CC FLAGS_REG))]
11700 [(set_attr "type" "multi")])
11702 ;; By default we don't ask for a scratch register, because when DImode
11703 ;; values are manipulated, registers are already at a premium. But if
11704 ;; we have one handy, we won't turn it away.
11706 [(match_scratch:SI 3 "r")
11707 (parallel [(set (match_operand:DI 0 "register_operand" "")
11708 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11709 (match_operand:QI 2 "nonmemory_operand" "")))
11710 (clobber (reg:CC FLAGS_REG))])
11712 "!TARGET_64BIT && TARGET_CMOVE"
11714 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11717 [(set (match_operand:DI 0 "register_operand" "")
11718 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11719 (match_operand:QI 2 "nonmemory_operand" "")))
11720 (clobber (reg:CC FLAGS_REG))]
11721 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11722 ? flow2_completed : reload_completed)"
11724 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11726 (define_insn "x86_shrd_1"
11727 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11728 (ior:SI (ashiftrt:SI (match_dup 0)
11729 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11730 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11731 (minus:QI (const_int 32) (match_dup 2)))))
11732 (clobber (reg:CC FLAGS_REG))]
11735 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11736 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11737 [(set_attr "type" "ishift")
11738 (set_attr "prefix_0f" "1")
11739 (set_attr "pent_pair" "np")
11740 (set_attr "mode" "SI")])
11742 (define_expand "x86_shift_adj_3"
11743 [(use (match_operand:SI 0 "register_operand" ""))
11744 (use (match_operand:SI 1 "register_operand" ""))
11745 (use (match_operand:QI 2 "register_operand" ""))]
11748 rtx label = gen_label_rtx ();
11751 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11753 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11754 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11755 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11756 gen_rtx_LABEL_REF (VOIDmode, label),
11758 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11759 JUMP_LABEL (tmp) = label;
11761 emit_move_insn (operands[0], operands[1]);
11762 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11764 emit_label (label);
11765 LABEL_NUSES (label) = 1;
11770 (define_insn "ashrsi3_31"
11771 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11772 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11773 (match_operand:SI 2 "const_int_operand" "i,i")))
11774 (clobber (reg:CC FLAGS_REG))]
11775 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11776 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11779 sar{l}\t{%2, %0|%0, %2}"
11780 [(set_attr "type" "imovx,ishift")
11781 (set_attr "prefix_0f" "0,*")
11782 (set_attr "length_immediate" "0,*")
11783 (set_attr "modrm" "0,1")
11784 (set_attr "mode" "SI")])
11786 (define_insn "*ashrsi3_31_zext"
11787 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11788 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11789 (match_operand:SI 2 "const_int_operand" "i,i"))))
11790 (clobber (reg:CC FLAGS_REG))]
11791 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11792 && INTVAL (operands[2]) == 31
11793 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11796 sar{l}\t{%2, %k0|%k0, %2}"
11797 [(set_attr "type" "imovx,ishift")
11798 (set_attr "prefix_0f" "0,*")
11799 (set_attr "length_immediate" "0,*")
11800 (set_attr "modrm" "0,1")
11801 (set_attr "mode" "SI")])
11803 (define_expand "ashrsi3"
11804 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11805 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11806 (match_operand:QI 2 "nonmemory_operand" "")))
11807 (clobber (reg:CC FLAGS_REG))]
11809 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11811 (define_insn "*ashrsi3_1_one_bit"
11812 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11813 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11814 (match_operand:QI 2 "const1_operand" "")))
11815 (clobber (reg:CC FLAGS_REG))]
11816 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11817 && (TARGET_SHIFT1 || optimize_size)"
11819 [(set_attr "type" "ishift")
11820 (set (attr "length")
11821 (if_then_else (match_operand:SI 0 "register_operand" "")
11823 (const_string "*")))])
11825 (define_insn "*ashrsi3_1_one_bit_zext"
11826 [(set (match_operand:DI 0 "register_operand" "=r")
11827 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11828 (match_operand:QI 2 "const1_operand" ""))))
11829 (clobber (reg:CC FLAGS_REG))]
11830 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11831 && (TARGET_SHIFT1 || optimize_size)"
11833 [(set_attr "type" "ishift")
11834 (set_attr "length" "2")])
11836 (define_insn "*ashrsi3_1"
11837 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11838 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11839 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11840 (clobber (reg:CC FLAGS_REG))]
11841 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11843 sar{l}\t{%2, %0|%0, %2}
11844 sar{l}\t{%b2, %0|%0, %b2}"
11845 [(set_attr "type" "ishift")
11846 (set_attr "mode" "SI")])
11848 (define_insn "*ashrsi3_1_zext"
11849 [(set (match_operand:DI 0 "register_operand" "=r,r")
11850 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11851 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11852 (clobber (reg:CC FLAGS_REG))]
11853 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11855 sar{l}\t{%2, %k0|%k0, %2}
11856 sar{l}\t{%b2, %k0|%k0, %b2}"
11857 [(set_attr "type" "ishift")
11858 (set_attr "mode" "SI")])
11860 ;; This pattern can't accept a variable shift count, since shifts by
11861 ;; zero don't affect the flags. We assume that shifts by constant
11862 ;; zero are optimized away.
11863 (define_insn "*ashrsi3_one_bit_cmp"
11864 [(set (reg FLAGS_REG)
11866 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11867 (match_operand:QI 2 "const1_operand" ""))
11869 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11870 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11871 "ix86_match_ccmode (insn, CCGOCmode)
11872 && (TARGET_SHIFT1 || optimize_size)
11873 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11875 [(set_attr "type" "ishift")
11876 (set (attr "length")
11877 (if_then_else (match_operand:SI 0 "register_operand" "")
11879 (const_string "*")))])
11881 (define_insn "*ashrsi3_one_bit_cconly"
11882 [(set (reg FLAGS_REG)
11884 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11885 (match_operand:QI 2 "const1_operand" ""))
11887 (clobber (match_scratch:SI 0 "=r"))]
11888 "ix86_match_ccmode (insn, CCGOCmode)
11889 && (TARGET_SHIFT1 || optimize_size)
11890 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11892 [(set_attr "type" "ishift")
11893 (set_attr "length" "2")])
11895 (define_insn "*ashrsi3_one_bit_cmp_zext"
11896 [(set (reg FLAGS_REG)
11898 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11899 (match_operand:QI 2 "const1_operand" ""))
11901 (set (match_operand:DI 0 "register_operand" "=r")
11902 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11903 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11904 && (TARGET_SHIFT1 || optimize_size)
11905 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11907 [(set_attr "type" "ishift")
11908 (set_attr "length" "2")])
11910 ;; This pattern can't accept a variable shift count, since shifts by
11911 ;; zero don't affect the flags. We assume that shifts by constant
11912 ;; zero are optimized away.
11913 (define_insn "*ashrsi3_cmp"
11914 [(set (reg FLAGS_REG)
11916 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11917 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11919 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11920 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11921 "ix86_match_ccmode (insn, CCGOCmode)
11922 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11924 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11925 "sar{l}\t{%2, %0|%0, %2}"
11926 [(set_attr "type" "ishift")
11927 (set_attr "mode" "SI")])
11929 (define_insn "*ashrsi3_cconly"
11930 [(set (reg FLAGS_REG)
11932 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11933 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11935 (clobber (match_scratch:SI 0 "=r"))]
11936 "ix86_match_ccmode (insn, CCGOCmode)
11937 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11939 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11940 "sar{l}\t{%2, %0|%0, %2}"
11941 [(set_attr "type" "ishift")
11942 (set_attr "mode" "SI")])
11944 (define_insn "*ashrsi3_cmp_zext"
11945 [(set (reg FLAGS_REG)
11947 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11950 (set (match_operand:DI 0 "register_operand" "=r")
11951 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11952 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11953 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11955 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11956 "sar{l}\t{%2, %k0|%k0, %2}"
11957 [(set_attr "type" "ishift")
11958 (set_attr "mode" "SI")])
11960 (define_expand "ashrhi3"
11961 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11962 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11963 (match_operand:QI 2 "nonmemory_operand" "")))
11964 (clobber (reg:CC FLAGS_REG))]
11965 "TARGET_HIMODE_MATH"
11966 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11968 (define_insn "*ashrhi3_1_one_bit"
11969 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11970 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11971 (match_operand:QI 2 "const1_operand" "")))
11972 (clobber (reg:CC FLAGS_REG))]
11973 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11974 && (TARGET_SHIFT1 || optimize_size)"
11976 [(set_attr "type" "ishift")
11977 (set (attr "length")
11978 (if_then_else (match_operand 0 "register_operand" "")
11980 (const_string "*")))])
11982 (define_insn "*ashrhi3_1"
11983 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11984 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11985 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11986 (clobber (reg:CC FLAGS_REG))]
11987 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11989 sar{w}\t{%2, %0|%0, %2}
11990 sar{w}\t{%b2, %0|%0, %b2}"
11991 [(set_attr "type" "ishift")
11992 (set_attr "mode" "HI")])
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags. We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*ashrhi3_one_bit_cmp"
11998 [(set (reg FLAGS_REG)
12000 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12001 (match_operand:QI 2 "const1_operand" ""))
12003 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12004 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12005 "ix86_match_ccmode (insn, CCGOCmode)
12006 && (TARGET_SHIFT1 || optimize_size)
12007 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12009 [(set_attr "type" "ishift")
12010 (set (attr "length")
12011 (if_then_else (match_operand 0 "register_operand" "")
12013 (const_string "*")))])
12015 (define_insn "*ashrhi3_one_bit_cconly"
12016 [(set (reg FLAGS_REG)
12018 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12019 (match_operand:QI 2 "const1_operand" ""))
12021 (clobber (match_scratch:HI 0 "=r"))]
12022 "ix86_match_ccmode (insn, CCGOCmode)
12023 && (TARGET_SHIFT1 || optimize_size)
12024 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12026 [(set_attr "type" "ishift")
12027 (set_attr "length" "2")])
12029 ;; This pattern can't accept a variable shift count, since shifts by
12030 ;; zero don't affect the flags. We assume that shifts by constant
12031 ;; zero are optimized away.
12032 (define_insn "*ashrhi3_cmp"
12033 [(set (reg FLAGS_REG)
12035 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12036 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12038 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12039 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12040 "ix86_match_ccmode (insn, CCGOCmode)
12041 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12043 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12044 "sar{w}\t{%2, %0|%0, %2}"
12045 [(set_attr "type" "ishift")
12046 (set_attr "mode" "HI")])
12048 (define_insn "*ashrhi3_cconly"
12049 [(set (reg FLAGS_REG)
12051 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12052 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12054 (clobber (match_scratch:HI 0 "=r"))]
12055 "ix86_match_ccmode (insn, CCGOCmode)
12056 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12058 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12059 "sar{w}\t{%2, %0|%0, %2}"
12060 [(set_attr "type" "ishift")
12061 (set_attr "mode" "HI")])
12063 (define_expand "ashrqi3"
12064 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12065 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12066 (match_operand:QI 2 "nonmemory_operand" "")))
12067 (clobber (reg:CC FLAGS_REG))]
12068 "TARGET_QIMODE_MATH"
12069 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12071 (define_insn "*ashrqi3_1_one_bit"
12072 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12073 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12074 (match_operand:QI 2 "const1_operand" "")))
12075 (clobber (reg:CC FLAGS_REG))]
12076 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12077 && (TARGET_SHIFT1 || optimize_size)"
12079 [(set_attr "type" "ishift")
12080 (set (attr "length")
12081 (if_then_else (match_operand 0 "register_operand" "")
12083 (const_string "*")))])
12085 (define_insn "*ashrqi3_1_one_bit_slp"
12086 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12087 (ashiftrt:QI (match_dup 0)
12088 (match_operand:QI 1 "const1_operand" "")))
12089 (clobber (reg:CC FLAGS_REG))]
12090 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12091 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12092 && (TARGET_SHIFT1 || optimize_size)"
12094 [(set_attr "type" "ishift1")
12095 (set (attr "length")
12096 (if_then_else (match_operand 0 "register_operand" "")
12098 (const_string "*")))])
12100 (define_insn "*ashrqi3_1"
12101 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12102 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12103 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12104 (clobber (reg:CC FLAGS_REG))]
12105 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12107 sar{b}\t{%2, %0|%0, %2}
12108 sar{b}\t{%b2, %0|%0, %b2}"
12109 [(set_attr "type" "ishift")
12110 (set_attr "mode" "QI")])
12112 (define_insn "*ashrqi3_1_slp"
12113 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12114 (ashiftrt:QI (match_dup 0)
12115 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12116 (clobber (reg:CC FLAGS_REG))]
12117 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12118 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12120 sar{b}\t{%1, %0|%0, %1}
12121 sar{b}\t{%b1, %0|%0, %b1}"
12122 [(set_attr "type" "ishift1")
12123 (set_attr "mode" "QI")])
12125 ;; This pattern can't accept a variable shift count, since shifts by
12126 ;; zero don't affect the flags. We assume that shifts by constant
12127 ;; zero are optimized away.
12128 (define_insn "*ashrqi3_one_bit_cmp"
12129 [(set (reg FLAGS_REG)
12131 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12132 (match_operand:QI 2 "const1_operand" "I"))
12134 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12135 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12136 "ix86_match_ccmode (insn, CCGOCmode)
12137 && (TARGET_SHIFT1 || optimize_size)
12138 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12140 [(set_attr "type" "ishift")
12141 (set (attr "length")
12142 (if_then_else (match_operand 0 "register_operand" "")
12144 (const_string "*")))])
12146 (define_insn "*ashrqi3_one_bit_cconly"
12147 [(set (reg FLAGS_REG)
12149 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12150 (match_operand:QI 2 "const1_operand" "I"))
12152 (clobber (match_scratch:QI 0 "=q"))]
12153 "ix86_match_ccmode (insn, CCGOCmode)
12154 && (TARGET_SHIFT1 || optimize_size)
12155 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12157 [(set_attr "type" "ishift")
12158 (set_attr "length" "2")])
12160 ;; This pattern can't accept a variable shift count, since shifts by
12161 ;; zero don't affect the flags. We assume that shifts by constant
12162 ;; zero are optimized away.
12163 (define_insn "*ashrqi3_cmp"
12164 [(set (reg FLAGS_REG)
12166 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12167 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12169 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12170 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12171 "ix86_match_ccmode (insn, CCGOCmode)
12172 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12174 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12175 "sar{b}\t{%2, %0|%0, %2}"
12176 [(set_attr "type" "ishift")
12177 (set_attr "mode" "QI")])
12179 (define_insn "*ashrqi3_cconly"
12180 [(set (reg FLAGS_REG)
12182 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12183 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12185 (clobber (match_scratch:QI 0 "=q"))]
12186 "ix86_match_ccmode (insn, CCGOCmode)
12187 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12189 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12190 "sar{b}\t{%2, %0|%0, %2}"
12191 [(set_attr "type" "ishift")
12192 (set_attr "mode" "QI")])
12195 ;; Logical shift instructions
12197 ;; See comment above `ashldi3' about how this works.
12199 (define_expand "lshrti3"
12200 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12201 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12202 (match_operand:QI 2 "nonmemory_operand" "")))
12203 (clobber (reg:CC FLAGS_REG))])]
12206 if (! immediate_operand (operands[2], QImode))
12208 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12211 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12215 (define_insn "lshrti3_1"
12216 [(set (match_operand:TI 0 "register_operand" "=r")
12217 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12218 (match_operand:QI 2 "register_operand" "c")))
12219 (clobber (match_scratch:DI 3 "=&r"))
12220 (clobber (reg:CC FLAGS_REG))]
12223 [(set_attr "type" "multi")])
12225 (define_insn "*lshrti3_2"
12226 [(set (match_operand:TI 0 "register_operand" "=r")
12227 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12228 (match_operand:QI 2 "immediate_operand" "O")))
12229 (clobber (reg:CC FLAGS_REG))]
12232 [(set_attr "type" "multi")])
12235 [(set (match_operand:TI 0 "register_operand" "")
12236 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12237 (match_operand:QI 2 "register_operand" "")))
12238 (clobber (match_scratch:DI 3 ""))
12239 (clobber (reg:CC FLAGS_REG))]
12240 "TARGET_64BIT && reload_completed"
12242 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12245 [(set (match_operand:TI 0 "register_operand" "")
12246 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12247 (match_operand:QI 2 "immediate_operand" "")))
12248 (clobber (reg:CC FLAGS_REG))]
12249 "TARGET_64BIT && reload_completed"
12251 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12253 (define_expand "lshrdi3"
12254 [(set (match_operand:DI 0 "shiftdi_operand" "")
12255 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12256 (match_operand:QI 2 "nonmemory_operand" "")))]
12258 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12260 (define_insn "*lshrdi3_1_one_bit_rex64"
12261 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12262 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12263 (match_operand:QI 2 "const1_operand" "")))
12264 (clobber (reg:CC FLAGS_REG))]
12265 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12266 && (TARGET_SHIFT1 || optimize_size)"
12268 [(set_attr "type" "ishift")
12269 (set (attr "length")
12270 (if_then_else (match_operand:DI 0 "register_operand" "")
12272 (const_string "*")))])
12274 (define_insn "*lshrdi3_1_rex64"
12275 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12276 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12277 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12278 (clobber (reg:CC FLAGS_REG))]
12279 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12281 shr{q}\t{%2, %0|%0, %2}
12282 shr{q}\t{%b2, %0|%0, %b2}"
12283 [(set_attr "type" "ishift")
12284 (set_attr "mode" "DI")])
12286 ;; This pattern can't accept a variable shift count, since shifts by
12287 ;; zero don't affect the flags. We assume that shifts by constant
12288 ;; zero are optimized away.
12289 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12290 [(set (reg FLAGS_REG)
12292 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12293 (match_operand:QI 2 "const1_operand" ""))
12295 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12296 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12297 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12298 && (TARGET_SHIFT1 || optimize_size)
12299 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12301 [(set_attr "type" "ishift")
12302 (set (attr "length")
12303 (if_then_else (match_operand:DI 0 "register_operand" "")
12305 (const_string "*")))])
12307 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12308 [(set (reg FLAGS_REG)
12310 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12311 (match_operand:QI 2 "const1_operand" ""))
12313 (clobber (match_scratch:DI 0 "=r"))]
12314 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12315 && (TARGET_SHIFT1 || optimize_size)
12316 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12318 [(set_attr "type" "ishift")
12319 (set_attr "length" "2")])
12321 ;; This pattern can't accept a variable shift count, since shifts by
12322 ;; zero don't affect the flags. We assume that shifts by constant
12323 ;; zero are optimized away.
12324 (define_insn "*lshrdi3_cmp_rex64"
12325 [(set (reg FLAGS_REG)
12327 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12328 (match_operand:QI 2 "const_int_operand" "e"))
12330 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12331 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12332 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12333 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12335 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12336 "shr{q}\t{%2, %0|%0, %2}"
12337 [(set_attr "type" "ishift")
12338 (set_attr "mode" "DI")])
12340 (define_insn "*lshrdi3_cconly_rex64"
12341 [(set (reg FLAGS_REG)
12343 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12344 (match_operand:QI 2 "const_int_operand" "e"))
12346 (clobber (match_scratch:DI 0 "=r"))]
12347 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12348 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12350 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12351 "shr{q}\t{%2, %0|%0, %2}"
12352 [(set_attr "type" "ishift")
12353 (set_attr "mode" "DI")])
12355 (define_insn "*lshrdi3_1"
12356 [(set (match_operand:DI 0 "register_operand" "=r")
12357 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12358 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12359 (clobber (reg:CC FLAGS_REG))]
12362 [(set_attr "type" "multi")])
12364 ;; By default we don't ask for a scratch register, because when DImode
12365 ;; values are manipulated, registers are already at a premium. But if
12366 ;; we have one handy, we won't turn it away.
12368 [(match_scratch:SI 3 "r")
12369 (parallel [(set (match_operand:DI 0 "register_operand" "")
12370 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12371 (match_operand:QI 2 "nonmemory_operand" "")))
12372 (clobber (reg:CC FLAGS_REG))])
12374 "!TARGET_64BIT && TARGET_CMOVE"
12376 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12379 [(set (match_operand:DI 0 "register_operand" "")
12380 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12381 (match_operand:QI 2 "nonmemory_operand" "")))
12382 (clobber (reg:CC FLAGS_REG))]
12383 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12384 ? flow2_completed : reload_completed)"
12386 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12388 (define_expand "lshrsi3"
12389 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12390 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12391 (match_operand:QI 2 "nonmemory_operand" "")))
12392 (clobber (reg:CC FLAGS_REG))]
12394 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12396 (define_insn "*lshrsi3_1_one_bit"
12397 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12398 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12399 (match_operand:QI 2 "const1_operand" "")))
12400 (clobber (reg:CC FLAGS_REG))]
12401 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12402 && (TARGET_SHIFT1 || optimize_size)"
12404 [(set_attr "type" "ishift")
12405 (set (attr "length")
12406 (if_then_else (match_operand:SI 0 "register_operand" "")
12408 (const_string "*")))])
12410 (define_insn "*lshrsi3_1_one_bit_zext"
12411 [(set (match_operand:DI 0 "register_operand" "=r")
12412 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12413 (match_operand:QI 2 "const1_operand" "")))
12414 (clobber (reg:CC FLAGS_REG))]
12415 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12416 && (TARGET_SHIFT1 || optimize_size)"
12418 [(set_attr "type" "ishift")
12419 (set_attr "length" "2")])
12421 (define_insn "*lshrsi3_1"
12422 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12423 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12424 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12425 (clobber (reg:CC FLAGS_REG))]
12426 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12428 shr{l}\t{%2, %0|%0, %2}
12429 shr{l}\t{%b2, %0|%0, %b2}"
12430 [(set_attr "type" "ishift")
12431 (set_attr "mode" "SI")])
12433 (define_insn "*lshrsi3_1_zext"
12434 [(set (match_operand:DI 0 "register_operand" "=r,r")
12436 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12437 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12438 (clobber (reg:CC FLAGS_REG))]
12439 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12441 shr{l}\t{%2, %k0|%k0, %2}
12442 shr{l}\t{%b2, %k0|%k0, %b2}"
12443 [(set_attr "type" "ishift")
12444 (set_attr "mode" "SI")])
12446 ;; This pattern can't accept a variable shift count, since shifts by
12447 ;; zero don't affect the flags. We assume that shifts by constant
12448 ;; zero are optimized away.
12449 (define_insn "*lshrsi3_one_bit_cmp"
12450 [(set (reg FLAGS_REG)
12452 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12453 (match_operand:QI 2 "const1_operand" ""))
12455 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12456 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12457 "ix86_match_ccmode (insn, CCGOCmode)
12458 && (TARGET_SHIFT1 || optimize_size)
12459 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
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_one_bit_cconly"
12468 [(set (reg FLAGS_REG)
12470 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12471 (match_operand:QI 2 "const1_operand" ""))
12473 (clobber (match_scratch:SI 0 "=r"))]
12474 "ix86_match_ccmode (insn, CCGOCmode)
12475 && (TARGET_SHIFT1 || optimize_size)
12476 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12478 [(set_attr "type" "ishift")
12479 (set_attr "length" "2")])
12481 (define_insn "*lshrsi3_cmp_one_bit_zext"
12482 [(set (reg FLAGS_REG)
12484 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12485 (match_operand:QI 2 "const1_operand" ""))
12487 (set (match_operand:DI 0 "register_operand" "=r")
12488 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12489 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12490 && (TARGET_SHIFT1 || optimize_size)
12491 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12493 [(set_attr "type" "ishift")
12494 (set_attr "length" "2")])
12496 ;; This pattern can't accept a variable shift count, since shifts by
12497 ;; zero don't affect the flags. We assume that shifts by constant
12498 ;; zero are optimized away.
12499 (define_insn "*lshrsi3_cmp"
12500 [(set (reg FLAGS_REG)
12502 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12503 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12505 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12506 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12507 "ix86_match_ccmode (insn, CCGOCmode)
12508 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12510 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12511 "shr{l}\t{%2, %0|%0, %2}"
12512 [(set_attr "type" "ishift")
12513 (set_attr "mode" "SI")])
12515 (define_insn "*lshrsi3_cconly"
12516 [(set (reg FLAGS_REG)
12518 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12519 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12521 (clobber (match_scratch:SI 0 "=r"))]
12522 "ix86_match_ccmode (insn, CCGOCmode)
12523 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12525 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12526 "shr{l}\t{%2, %0|%0, %2}"
12527 [(set_attr "type" "ishift")
12528 (set_attr "mode" "SI")])
12530 (define_insn "*lshrsi3_cmp_zext"
12531 [(set (reg FLAGS_REG)
12533 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12534 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12536 (set (match_operand:DI 0 "register_operand" "=r")
12537 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12538 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12539 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12541 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12542 "shr{l}\t{%2, %k0|%k0, %2}"
12543 [(set_attr "type" "ishift")
12544 (set_attr "mode" "SI")])
12546 (define_expand "lshrhi3"
12547 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12548 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12549 (match_operand:QI 2 "nonmemory_operand" "")))
12550 (clobber (reg:CC FLAGS_REG))]
12551 "TARGET_HIMODE_MATH"
12552 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12554 (define_insn "*lshrhi3_1_one_bit"
12555 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12556 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12557 (match_operand:QI 2 "const1_operand" "")))
12558 (clobber (reg:CC FLAGS_REG))]
12559 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12560 && (TARGET_SHIFT1 || optimize_size)"
12562 [(set_attr "type" "ishift")
12563 (set (attr "length")
12564 (if_then_else (match_operand 0 "register_operand" "")
12566 (const_string "*")))])
12568 (define_insn "*lshrhi3_1"
12569 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12570 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12571 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12572 (clobber (reg:CC FLAGS_REG))]
12573 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12575 shr{w}\t{%2, %0|%0, %2}
12576 shr{w}\t{%b2, %0|%0, %b2}"
12577 [(set_attr "type" "ishift")
12578 (set_attr "mode" "HI")])
12580 ;; This pattern can't accept a variable shift count, since shifts by
12581 ;; zero don't affect the flags. We assume that shifts by constant
12582 ;; zero are optimized away.
12583 (define_insn "*lshrhi3_one_bit_cmp"
12584 [(set (reg FLAGS_REG)
12586 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12587 (match_operand:QI 2 "const1_operand" ""))
12589 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12590 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12591 "ix86_match_ccmode (insn, CCGOCmode)
12592 && (TARGET_SHIFT1 || optimize_size)
12593 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12595 [(set_attr "type" "ishift")
12596 (set (attr "length")
12597 (if_then_else (match_operand:SI 0 "register_operand" "")
12599 (const_string "*")))])
12601 (define_insn "*lshrhi3_one_bit_cconly"
12602 [(set (reg FLAGS_REG)
12604 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12605 (match_operand:QI 2 "const1_operand" ""))
12607 (clobber (match_scratch:HI 0 "=r"))]
12608 "ix86_match_ccmode (insn, CCGOCmode)
12609 && (TARGET_SHIFT1 || optimize_size)
12610 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12612 [(set_attr "type" "ishift")
12613 (set_attr "length" "2")])
12615 ;; This pattern can't accept a variable shift count, since shifts by
12616 ;; zero don't affect the flags. We assume that shifts by constant
12617 ;; zero are optimized away.
12618 (define_insn "*lshrhi3_cmp"
12619 [(set (reg FLAGS_REG)
12621 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12622 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12624 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12625 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12626 "ix86_match_ccmode (insn, CCGOCmode)
12627 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12629 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12630 "shr{w}\t{%2, %0|%0, %2}"
12631 [(set_attr "type" "ishift")
12632 (set_attr "mode" "HI")])
12634 (define_insn "*lshrhi3_cconly"
12635 [(set (reg FLAGS_REG)
12637 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12638 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12640 (clobber (match_scratch:HI 0 "=r"))]
12641 "ix86_match_ccmode (insn, CCGOCmode)
12642 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12644 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12645 "shr{w}\t{%2, %0|%0, %2}"
12646 [(set_attr "type" "ishift")
12647 (set_attr "mode" "HI")])
12649 (define_expand "lshrqi3"
12650 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12651 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12652 (match_operand:QI 2 "nonmemory_operand" "")))
12653 (clobber (reg:CC FLAGS_REG))]
12654 "TARGET_QIMODE_MATH"
12655 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12657 (define_insn "*lshrqi3_1_one_bit"
12658 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12659 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12660 (match_operand:QI 2 "const1_operand" "")))
12661 (clobber (reg:CC FLAGS_REG))]
12662 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12663 && (TARGET_SHIFT1 || optimize_size)"
12665 [(set_attr "type" "ishift")
12666 (set (attr "length")
12667 (if_then_else (match_operand 0 "register_operand" "")
12669 (const_string "*")))])
12671 (define_insn "*lshrqi3_1_one_bit_slp"
12672 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12673 (lshiftrt:QI (match_dup 0)
12674 (match_operand:QI 1 "const1_operand" "")))
12675 (clobber (reg:CC FLAGS_REG))]
12676 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12677 && (TARGET_SHIFT1 || optimize_size)"
12679 [(set_attr "type" "ishift1")
12680 (set (attr "length")
12681 (if_then_else (match_operand 0 "register_operand" "")
12683 (const_string "*")))])
12685 (define_insn "*lshrqi3_1"
12686 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12687 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12688 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12689 (clobber (reg:CC FLAGS_REG))]
12690 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12692 shr{b}\t{%2, %0|%0, %2}
12693 shr{b}\t{%b2, %0|%0, %b2}"
12694 [(set_attr "type" "ishift")
12695 (set_attr "mode" "QI")])
12697 (define_insn "*lshrqi3_1_slp"
12698 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12699 (lshiftrt:QI (match_dup 0)
12700 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12701 (clobber (reg:CC FLAGS_REG))]
12702 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12703 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12705 shr{b}\t{%1, %0|%0, %1}
12706 shr{b}\t{%b1, %0|%0, %b1}"
12707 [(set_attr "type" "ishift1")
12708 (set_attr "mode" "QI")])
12710 ;; This pattern can't accept a variable shift count, since shifts by
12711 ;; zero don't affect the flags. We assume that shifts by constant
12712 ;; zero are optimized away.
12713 (define_insn "*lshrqi2_one_bit_cmp"
12714 [(set (reg FLAGS_REG)
12716 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12717 (match_operand:QI 2 "const1_operand" ""))
12719 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12720 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12721 "ix86_match_ccmode (insn, CCGOCmode)
12722 && (TARGET_SHIFT1 || optimize_size)
12723 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12725 [(set_attr "type" "ishift")
12726 (set (attr "length")
12727 (if_then_else (match_operand:SI 0 "register_operand" "")
12729 (const_string "*")))])
12731 (define_insn "*lshrqi2_one_bit_cconly"
12732 [(set (reg FLAGS_REG)
12734 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12735 (match_operand:QI 2 "const1_operand" ""))
12737 (clobber (match_scratch:QI 0 "=q"))]
12738 "ix86_match_ccmode (insn, CCGOCmode)
12739 && (TARGET_SHIFT1 || optimize_size)
12740 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12742 [(set_attr "type" "ishift")
12743 (set_attr "length" "2")])
12745 ;; This pattern can't accept a variable shift count, since shifts by
12746 ;; zero don't affect the flags. We assume that shifts by constant
12747 ;; zero are optimized away.
12748 (define_insn "*lshrqi2_cmp"
12749 [(set (reg FLAGS_REG)
12751 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12752 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12754 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12755 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12756 "ix86_match_ccmode (insn, CCGOCmode)
12757 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12759 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12760 "shr{b}\t{%2, %0|%0, %2}"
12761 [(set_attr "type" "ishift")
12762 (set_attr "mode" "QI")])
12764 (define_insn "*lshrqi2_cconly"
12765 [(set (reg FLAGS_REG)
12767 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12768 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12770 (clobber (match_scratch:QI 0 "=q"))]
12771 "ix86_match_ccmode (insn, CCGOCmode)
12772 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12774 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12775 "shr{b}\t{%2, %0|%0, %2}"
12776 [(set_attr "type" "ishift")
12777 (set_attr "mode" "QI")])
12779 ;; Rotate instructions
12781 (define_expand "rotldi3"
12782 [(set (match_operand:DI 0 "shiftdi_operand" "")
12783 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12784 (match_operand:QI 2 "nonmemory_operand" "")))
12785 (clobber (reg:CC FLAGS_REG))]
12790 ix86_expand_binary_operator (ROTATE, DImode, operands);
12793 if (!const_1_to_31_operand (operands[2], VOIDmode))
12795 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12799 ;; Implement rotation using two double-precision shift instructions
12800 ;; and a scratch register.
12801 (define_insn_and_split "ix86_rotldi3"
12802 [(set (match_operand:DI 0 "register_operand" "=r")
12803 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12804 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12805 (clobber (reg:CC FLAGS_REG))
12806 (clobber (match_scratch:SI 3 "=&r"))]
12809 "&& reload_completed"
12810 [(set (match_dup 3) (match_dup 4))
12812 [(set (match_dup 4)
12813 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12814 (lshiftrt:SI (match_dup 5)
12815 (minus:QI (const_int 32) (match_dup 2)))))
12816 (clobber (reg:CC FLAGS_REG))])
12818 [(set (match_dup 5)
12819 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12820 (lshiftrt:SI (match_dup 3)
12821 (minus:QI (const_int 32) (match_dup 2)))))
12822 (clobber (reg:CC FLAGS_REG))])]
12823 "split_di (operands, 1, operands + 4, operands + 5);")
12825 (define_insn "*rotlsi3_1_one_bit_rex64"
12826 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12827 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12828 (match_operand:QI 2 "const1_operand" "")))
12829 (clobber (reg:CC FLAGS_REG))]
12830 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12831 && (TARGET_SHIFT1 || optimize_size)"
12833 [(set_attr "type" "rotate")
12834 (set (attr "length")
12835 (if_then_else (match_operand:DI 0 "register_operand" "")
12837 (const_string "*")))])
12839 (define_insn "*rotldi3_1_rex64"
12840 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12841 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12842 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12843 (clobber (reg:CC FLAGS_REG))]
12844 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12846 rol{q}\t{%2, %0|%0, %2}
12847 rol{q}\t{%b2, %0|%0, %b2}"
12848 [(set_attr "type" "rotate")
12849 (set_attr "mode" "DI")])
12851 (define_expand "rotlsi3"
12852 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12853 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12854 (match_operand:QI 2 "nonmemory_operand" "")))
12855 (clobber (reg:CC FLAGS_REG))]
12857 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12859 (define_insn "*rotlsi3_1_one_bit"
12860 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12861 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12862 (match_operand:QI 2 "const1_operand" "")))
12863 (clobber (reg:CC FLAGS_REG))]
12864 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12865 && (TARGET_SHIFT1 || optimize_size)"
12867 [(set_attr "type" "rotate")
12868 (set (attr "length")
12869 (if_then_else (match_operand:SI 0 "register_operand" "")
12871 (const_string "*")))])
12873 (define_insn "*rotlsi3_1_one_bit_zext"
12874 [(set (match_operand:DI 0 "register_operand" "=r")
12876 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12877 (match_operand:QI 2 "const1_operand" ""))))
12878 (clobber (reg:CC FLAGS_REG))]
12879 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12880 && (TARGET_SHIFT1 || optimize_size)"
12882 [(set_attr "type" "rotate")
12883 (set_attr "length" "2")])
12885 (define_insn "*rotlsi3_1"
12886 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12887 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12888 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12889 (clobber (reg:CC FLAGS_REG))]
12890 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12892 rol{l}\t{%2, %0|%0, %2}
12893 rol{l}\t{%b2, %0|%0, %b2}"
12894 [(set_attr "type" "rotate")
12895 (set_attr "mode" "SI")])
12897 (define_insn "*rotlsi3_1_zext"
12898 [(set (match_operand:DI 0 "register_operand" "=r,r")
12900 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12901 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12902 (clobber (reg:CC FLAGS_REG))]
12903 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12905 rol{l}\t{%2, %k0|%k0, %2}
12906 rol{l}\t{%b2, %k0|%k0, %b2}"
12907 [(set_attr "type" "rotate")
12908 (set_attr "mode" "SI")])
12910 (define_expand "rotlhi3"
12911 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12912 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12913 (match_operand:QI 2 "nonmemory_operand" "")))
12914 (clobber (reg:CC FLAGS_REG))]
12915 "TARGET_HIMODE_MATH"
12916 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12918 (define_insn "*rotlhi3_1_one_bit"
12919 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12920 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12921 (match_operand:QI 2 "const1_operand" "")))
12922 (clobber (reg:CC FLAGS_REG))]
12923 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12924 && (TARGET_SHIFT1 || optimize_size)"
12926 [(set_attr "type" "rotate")
12927 (set (attr "length")
12928 (if_then_else (match_operand 0 "register_operand" "")
12930 (const_string "*")))])
12932 (define_insn "*rotlhi3_1"
12933 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12934 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12935 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12936 (clobber (reg:CC FLAGS_REG))]
12937 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12939 rol{w}\t{%2, %0|%0, %2}
12940 rol{w}\t{%b2, %0|%0, %b2}"
12941 [(set_attr "type" "rotate")
12942 (set_attr "mode" "HI")])
12944 (define_expand "rotlqi3"
12945 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12946 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12947 (match_operand:QI 2 "nonmemory_operand" "")))
12948 (clobber (reg:CC FLAGS_REG))]
12949 "TARGET_QIMODE_MATH"
12950 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12952 (define_insn "*rotlqi3_1_one_bit_slp"
12953 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12954 (rotate:QI (match_dup 0)
12955 (match_operand:QI 1 "const1_operand" "")))
12956 (clobber (reg:CC FLAGS_REG))]
12957 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12958 && (TARGET_SHIFT1 || optimize_size)"
12960 [(set_attr "type" "rotate1")
12961 (set (attr "length")
12962 (if_then_else (match_operand 0 "register_operand" "")
12964 (const_string "*")))])
12966 (define_insn "*rotlqi3_1_one_bit"
12967 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12968 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12969 (match_operand:QI 2 "const1_operand" "")))
12970 (clobber (reg:CC FLAGS_REG))]
12971 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12972 && (TARGET_SHIFT1 || optimize_size)"
12974 [(set_attr "type" "rotate")
12975 (set (attr "length")
12976 (if_then_else (match_operand 0 "register_operand" "")
12978 (const_string "*")))])
12980 (define_insn "*rotlqi3_1_slp"
12981 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12982 (rotate:QI (match_dup 0)
12983 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12984 (clobber (reg:CC FLAGS_REG))]
12985 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12986 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12988 rol{b}\t{%1, %0|%0, %1}
12989 rol{b}\t{%b1, %0|%0, %b1}"
12990 [(set_attr "type" "rotate1")
12991 (set_attr "mode" "QI")])
12993 (define_insn "*rotlqi3_1"
12994 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12995 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12996 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12997 (clobber (reg:CC FLAGS_REG))]
12998 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13000 rol{b}\t{%2, %0|%0, %2}
13001 rol{b}\t{%b2, %0|%0, %b2}"
13002 [(set_attr "type" "rotate")
13003 (set_attr "mode" "QI")])
13005 (define_expand "rotrdi3"
13006 [(set (match_operand:DI 0 "shiftdi_operand" "")
13007 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13008 (match_operand:QI 2 "nonmemory_operand" "")))
13009 (clobber (reg:CC FLAGS_REG))]
13014 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13017 if (!const_1_to_31_operand (operands[2], VOIDmode))
13019 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13023 ;; Implement rotation using two double-precision shift instructions
13024 ;; and a scratch register.
13025 (define_insn_and_split "ix86_rotrdi3"
13026 [(set (match_operand:DI 0 "register_operand" "=r")
13027 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13028 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13029 (clobber (reg:CC FLAGS_REG))
13030 (clobber (match_scratch:SI 3 "=&r"))]
13033 "&& reload_completed"
13034 [(set (match_dup 3) (match_dup 4))
13036 [(set (match_dup 4)
13037 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13038 (ashift:SI (match_dup 5)
13039 (minus:QI (const_int 32) (match_dup 2)))))
13040 (clobber (reg:CC FLAGS_REG))])
13042 [(set (match_dup 5)
13043 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13044 (ashift:SI (match_dup 3)
13045 (minus:QI (const_int 32) (match_dup 2)))))
13046 (clobber (reg:CC FLAGS_REG))])]
13047 "split_di (operands, 1, operands + 4, operands + 5);")
13049 (define_insn "*rotrdi3_1_one_bit_rex64"
13050 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13051 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13052 (match_operand:QI 2 "const1_operand" "")))
13053 (clobber (reg:CC FLAGS_REG))]
13054 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13055 && (TARGET_SHIFT1 || optimize_size)"
13057 [(set_attr "type" "rotate")
13058 (set (attr "length")
13059 (if_then_else (match_operand:DI 0 "register_operand" "")
13061 (const_string "*")))])
13063 (define_insn "*rotrdi3_1_rex64"
13064 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13065 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13066 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13067 (clobber (reg:CC FLAGS_REG))]
13068 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13070 ror{q}\t{%2, %0|%0, %2}
13071 ror{q}\t{%b2, %0|%0, %b2}"
13072 [(set_attr "type" "rotate")
13073 (set_attr "mode" "DI")])
13075 (define_expand "rotrsi3"
13076 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13077 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13078 (match_operand:QI 2 "nonmemory_operand" "")))
13079 (clobber (reg:CC FLAGS_REG))]
13081 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13083 (define_insn "*rotrsi3_1_one_bit"
13084 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13085 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13086 (match_operand:QI 2 "const1_operand" "")))
13087 (clobber (reg:CC FLAGS_REG))]
13088 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13089 && (TARGET_SHIFT1 || optimize_size)"
13091 [(set_attr "type" "rotate")
13092 (set (attr "length")
13093 (if_then_else (match_operand:SI 0 "register_operand" "")
13095 (const_string "*")))])
13097 (define_insn "*rotrsi3_1_one_bit_zext"
13098 [(set (match_operand:DI 0 "register_operand" "=r")
13100 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13101 (match_operand:QI 2 "const1_operand" ""))))
13102 (clobber (reg:CC FLAGS_REG))]
13103 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13104 && (TARGET_SHIFT1 || optimize_size)"
13106 [(set_attr "type" "rotate")
13107 (set (attr "length")
13108 (if_then_else (match_operand:SI 0 "register_operand" "")
13110 (const_string "*")))])
13112 (define_insn "*rotrsi3_1"
13113 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13114 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13115 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13116 (clobber (reg:CC FLAGS_REG))]
13117 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13119 ror{l}\t{%2, %0|%0, %2}
13120 ror{l}\t{%b2, %0|%0, %b2}"
13121 [(set_attr "type" "rotate")
13122 (set_attr "mode" "SI")])
13124 (define_insn "*rotrsi3_1_zext"
13125 [(set (match_operand:DI 0 "register_operand" "=r,r")
13127 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13128 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13129 (clobber (reg:CC FLAGS_REG))]
13130 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13132 ror{l}\t{%2, %k0|%k0, %2}
13133 ror{l}\t{%b2, %k0|%k0, %b2}"
13134 [(set_attr "type" "rotate")
13135 (set_attr "mode" "SI")])
13137 (define_expand "rotrhi3"
13138 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13139 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13140 (match_operand:QI 2 "nonmemory_operand" "")))
13141 (clobber (reg:CC FLAGS_REG))]
13142 "TARGET_HIMODE_MATH"
13143 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13145 (define_insn "*rotrhi3_one_bit"
13146 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13147 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13148 (match_operand:QI 2 "const1_operand" "")))
13149 (clobber (reg:CC FLAGS_REG))]
13150 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13151 && (TARGET_SHIFT1 || optimize_size)"
13153 [(set_attr "type" "rotate")
13154 (set (attr "length")
13155 (if_then_else (match_operand 0 "register_operand" "")
13157 (const_string "*")))])
13159 (define_insn "*rotrhi3"
13160 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13161 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13162 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13163 (clobber (reg:CC FLAGS_REG))]
13164 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13166 ror{w}\t{%2, %0|%0, %2}
13167 ror{w}\t{%b2, %0|%0, %b2}"
13168 [(set_attr "type" "rotate")
13169 (set_attr "mode" "HI")])
13171 (define_expand "rotrqi3"
13172 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13173 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13174 (match_operand:QI 2 "nonmemory_operand" "")))
13175 (clobber (reg:CC FLAGS_REG))]
13176 "TARGET_QIMODE_MATH"
13177 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13179 (define_insn "*rotrqi3_1_one_bit"
13180 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13181 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13182 (match_operand:QI 2 "const1_operand" "")))
13183 (clobber (reg:CC FLAGS_REG))]
13184 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13185 && (TARGET_SHIFT1 || optimize_size)"
13187 [(set_attr "type" "rotate")
13188 (set (attr "length")
13189 (if_then_else (match_operand 0 "register_operand" "")
13191 (const_string "*")))])
13193 (define_insn "*rotrqi3_1_one_bit_slp"
13194 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13195 (rotatert:QI (match_dup 0)
13196 (match_operand:QI 1 "const1_operand" "")))
13197 (clobber (reg:CC FLAGS_REG))]
13198 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13199 && (TARGET_SHIFT1 || optimize_size)"
13201 [(set_attr "type" "rotate1")
13202 (set (attr "length")
13203 (if_then_else (match_operand 0 "register_operand" "")
13205 (const_string "*")))])
13207 (define_insn "*rotrqi3_1"
13208 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13209 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13210 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13211 (clobber (reg:CC FLAGS_REG))]
13212 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13214 ror{b}\t{%2, %0|%0, %2}
13215 ror{b}\t{%b2, %0|%0, %b2}"
13216 [(set_attr "type" "rotate")
13217 (set_attr "mode" "QI")])
13219 (define_insn "*rotrqi3_1_slp"
13220 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13221 (rotatert:QI (match_dup 0)
13222 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13223 (clobber (reg:CC FLAGS_REG))]
13224 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13225 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13227 ror{b}\t{%1, %0|%0, %1}
13228 ror{b}\t{%b1, %0|%0, %b1}"
13229 [(set_attr "type" "rotate1")
13230 (set_attr "mode" "QI")])
13232 ;; Bit set / bit test instructions
13234 (define_expand "extv"
13235 [(set (match_operand:SI 0 "register_operand" "")
13236 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13237 (match_operand:SI 2 "const8_operand" "")
13238 (match_operand:SI 3 "const8_operand" "")))]
13241 /* Handle extractions from %ah et al. */
13242 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13245 /* From mips.md: extract_bit_field doesn't verify that our source
13246 matches the predicate, so check it again here. */
13247 if (! ext_register_operand (operands[1], VOIDmode))
13251 (define_expand "extzv"
13252 [(set (match_operand:SI 0 "register_operand" "")
13253 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13254 (match_operand:SI 2 "const8_operand" "")
13255 (match_operand:SI 3 "const8_operand" "")))]
13258 /* Handle extractions from %ah et al. */
13259 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13262 /* From mips.md: extract_bit_field doesn't verify that our source
13263 matches the predicate, so check it again here. */
13264 if (! ext_register_operand (operands[1], VOIDmode))
13268 (define_expand "insv"
13269 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13270 (match_operand 1 "const8_operand" "")
13271 (match_operand 2 "const8_operand" ""))
13272 (match_operand 3 "register_operand" ""))]
13275 /* Handle insertions to %ah et al. */
13276 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13279 /* From mips.md: insert_bit_field doesn't verify that our source
13280 matches the predicate, so check it again here. */
13281 if (! ext_register_operand (operands[0], VOIDmode))
13285 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13287 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13292 ;; %%% bts, btr, btc, bt.
13293 ;; In general these instructions are *slow* when applied to memory,
13294 ;; since they enforce atomic operation. When applied to registers,
13295 ;; it depends on the cpu implementation. They're never faster than
13296 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13297 ;; no point. But in 64-bit, we can't hold the relevant immediates
13298 ;; within the instruction itself, so operating on bits in the high
13299 ;; 32-bits of a register becomes easier.
13301 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13302 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13303 ;; negdf respectively, so they can never be disabled entirely.
13305 (define_insn "*btsq"
13306 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13308 (match_operand:DI 1 "const_0_to_63_operand" ""))
13310 (clobber (reg:CC FLAGS_REG))]
13311 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13313 [(set_attr "type" "alu1")])
13315 (define_insn "*btrq"
13316 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13318 (match_operand:DI 1 "const_0_to_63_operand" ""))
13320 (clobber (reg:CC FLAGS_REG))]
13321 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13323 [(set_attr "type" "alu1")])
13325 (define_insn "*btcq"
13326 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13328 (match_operand:DI 1 "const_0_to_63_operand" ""))
13329 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13330 (clobber (reg:CC FLAGS_REG))]
13331 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13333 [(set_attr "type" "alu1")])
13335 ;; Allow Nocona to avoid these instructions if a register is available.
13338 [(match_scratch:DI 2 "r")
13339 (parallel [(set (zero_extract:DI
13340 (match_operand:DI 0 "register_operand" "")
13342 (match_operand:DI 1 "const_0_to_63_operand" ""))
13344 (clobber (reg:CC FLAGS_REG))])]
13345 "TARGET_64BIT && !TARGET_USE_BT"
13348 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13351 if (HOST_BITS_PER_WIDE_INT >= 64)
13352 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13353 else if (i < HOST_BITS_PER_WIDE_INT)
13354 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13356 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13358 op1 = immed_double_const (lo, hi, DImode);
13361 emit_move_insn (operands[2], op1);
13365 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13370 [(match_scratch:DI 2 "r")
13371 (parallel [(set (zero_extract:DI
13372 (match_operand:DI 0 "register_operand" "")
13374 (match_operand:DI 1 "const_0_to_63_operand" ""))
13376 (clobber (reg:CC FLAGS_REG))])]
13377 "TARGET_64BIT && !TARGET_USE_BT"
13380 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13383 if (HOST_BITS_PER_WIDE_INT >= 64)
13384 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13385 else if (i < HOST_BITS_PER_WIDE_INT)
13386 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13388 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13390 op1 = immed_double_const (~lo, ~hi, DImode);
13393 emit_move_insn (operands[2], op1);
13397 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13402 [(match_scratch:DI 2 "r")
13403 (parallel [(set (zero_extract:DI
13404 (match_operand:DI 0 "register_operand" "")
13406 (match_operand:DI 1 "const_0_to_63_operand" ""))
13407 (not:DI (zero_extract:DI
13408 (match_dup 0) (const_int 1) (match_dup 1))))
13409 (clobber (reg:CC FLAGS_REG))])]
13410 "TARGET_64BIT && !TARGET_USE_BT"
13413 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13416 if (HOST_BITS_PER_WIDE_INT >= 64)
13417 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13418 else if (i < HOST_BITS_PER_WIDE_INT)
13419 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13421 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13423 op1 = immed_double_const (lo, hi, DImode);
13426 emit_move_insn (operands[2], op1);
13430 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13434 ;; Store-flag instructions.
13436 ;; For all sCOND expanders, also expand the compare or test insn that
13437 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13439 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13440 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13441 ;; way, which can later delete the movzx if only QImode is needed.
13443 (define_expand "seq"
13444 [(set (match_operand:QI 0 "register_operand" "")
13445 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13447 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13449 (define_expand "sne"
13450 [(set (match_operand:QI 0 "register_operand" "")
13451 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13453 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13455 (define_expand "sgt"
13456 [(set (match_operand:QI 0 "register_operand" "")
13457 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13459 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13461 (define_expand "sgtu"
13462 [(set (match_operand:QI 0 "register_operand" "")
13463 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13465 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13467 (define_expand "slt"
13468 [(set (match_operand:QI 0 "register_operand" "")
13469 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13471 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13473 (define_expand "sltu"
13474 [(set (match_operand:QI 0 "register_operand" "")
13475 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13477 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13479 (define_expand "sge"
13480 [(set (match_operand:QI 0 "register_operand" "")
13481 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13483 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13485 (define_expand "sgeu"
13486 [(set (match_operand:QI 0 "register_operand" "")
13487 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13489 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13491 (define_expand "sle"
13492 [(set (match_operand:QI 0 "register_operand" "")
13493 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13495 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13497 (define_expand "sleu"
13498 [(set (match_operand:QI 0 "register_operand" "")
13499 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13501 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13503 (define_expand "sunordered"
13504 [(set (match_operand:QI 0 "register_operand" "")
13505 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13506 "TARGET_80387 || TARGET_SSE"
13507 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13509 (define_expand "sordered"
13510 [(set (match_operand:QI 0 "register_operand" "")
13511 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13513 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13515 (define_expand "suneq"
13516 [(set (match_operand:QI 0 "register_operand" "")
13517 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13518 "TARGET_80387 || TARGET_SSE"
13519 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13521 (define_expand "sunge"
13522 [(set (match_operand:QI 0 "register_operand" "")
13523 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13524 "TARGET_80387 || TARGET_SSE"
13525 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13527 (define_expand "sungt"
13528 [(set (match_operand:QI 0 "register_operand" "")
13529 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13530 "TARGET_80387 || TARGET_SSE"
13531 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13533 (define_expand "sunle"
13534 [(set (match_operand:QI 0 "register_operand" "")
13535 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13536 "TARGET_80387 || TARGET_SSE"
13537 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13539 (define_expand "sunlt"
13540 [(set (match_operand:QI 0 "register_operand" "")
13541 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13542 "TARGET_80387 || TARGET_SSE"
13543 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13545 (define_expand "sltgt"
13546 [(set (match_operand:QI 0 "register_operand" "")
13547 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13548 "TARGET_80387 || TARGET_SSE"
13549 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13551 (define_insn "*setcc_1"
13552 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13553 (match_operator:QI 1 "ix86_comparison_operator"
13554 [(reg FLAGS_REG) (const_int 0)]))]
13557 [(set_attr "type" "setcc")
13558 (set_attr "mode" "QI")])
13560 (define_insn "*setcc_2"
13561 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13562 (match_operator:QI 1 "ix86_comparison_operator"
13563 [(reg FLAGS_REG) (const_int 0)]))]
13566 [(set_attr "type" "setcc")
13567 (set_attr "mode" "QI")])
13569 ;; In general it is not safe to assume too much about CCmode registers,
13570 ;; so simplify-rtx stops when it sees a second one. Under certain
13571 ;; conditions this is safe on x86, so help combine not create
13578 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13579 (ne:QI (match_operator 1 "ix86_comparison_operator"
13580 [(reg FLAGS_REG) (const_int 0)])
13583 [(set (match_dup 0) (match_dup 1))]
13585 PUT_MODE (operands[1], QImode);
13589 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13590 (ne:QI (match_operator 1 "ix86_comparison_operator"
13591 [(reg FLAGS_REG) (const_int 0)])
13594 [(set (match_dup 0) (match_dup 1))]
13596 PUT_MODE (operands[1], QImode);
13600 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13601 (eq:QI (match_operator 1 "ix86_comparison_operator"
13602 [(reg FLAGS_REG) (const_int 0)])
13605 [(set (match_dup 0) (match_dup 1))]
13607 rtx new_op1 = copy_rtx (operands[1]);
13608 operands[1] = new_op1;
13609 PUT_MODE (new_op1, QImode);
13610 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13611 GET_MODE (XEXP (new_op1, 0))));
13613 /* Make sure that (a) the CCmode we have for the flags is strong
13614 enough for the reversed compare or (b) we have a valid FP compare. */
13615 if (! ix86_comparison_operator (new_op1, VOIDmode))
13620 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13621 (eq:QI (match_operator 1 "ix86_comparison_operator"
13622 [(reg FLAGS_REG) (const_int 0)])
13625 [(set (match_dup 0) (match_dup 1))]
13627 rtx new_op1 = copy_rtx (operands[1]);
13628 operands[1] = new_op1;
13629 PUT_MODE (new_op1, QImode);
13630 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13631 GET_MODE (XEXP (new_op1, 0))));
13633 /* Make sure that (a) the CCmode we have for the flags is strong
13634 enough for the reversed compare or (b) we have a valid FP compare. */
13635 if (! ix86_comparison_operator (new_op1, VOIDmode))
13639 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13640 ;; subsequent logical operations are used to imitate conditional moves.
13641 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13644 (define_insn "*sse_setccsf"
13645 [(set (match_operand:SF 0 "register_operand" "=x")
13646 (match_operator:SF 1 "sse_comparison_operator"
13647 [(match_operand:SF 2 "register_operand" "0")
13648 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13650 "cmp%D1ss\t{%3, %0|%0, %3}"
13651 [(set_attr "type" "ssecmp")
13652 (set_attr "mode" "SF")])
13654 (define_insn "*sse_setccdf"
13655 [(set (match_operand:DF 0 "register_operand" "=x")
13656 (match_operator:DF 1 "sse_comparison_operator"
13657 [(match_operand:DF 2 "register_operand" "0")
13658 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13660 "cmp%D1sd\t{%3, %0|%0, %3}"
13661 [(set_attr "type" "ssecmp")
13662 (set_attr "mode" "DF")])
13664 ;; Basic conditional jump instructions.
13665 ;; We ignore the overflow flag for signed branch instructions.
13667 ;; For all bCOND expanders, also expand the compare or test insn that
13668 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13670 (define_expand "beq"
13672 (if_then_else (match_dup 1)
13673 (label_ref (match_operand 0 "" ""))
13676 "ix86_expand_branch (EQ, operands[0]); DONE;")
13678 (define_expand "bne"
13680 (if_then_else (match_dup 1)
13681 (label_ref (match_operand 0 "" ""))
13684 "ix86_expand_branch (NE, operands[0]); DONE;")
13686 (define_expand "bgt"
13688 (if_then_else (match_dup 1)
13689 (label_ref (match_operand 0 "" ""))
13692 "ix86_expand_branch (GT, operands[0]); DONE;")
13694 (define_expand "bgtu"
13696 (if_then_else (match_dup 1)
13697 (label_ref (match_operand 0 "" ""))
13700 "ix86_expand_branch (GTU, operands[0]); DONE;")
13702 (define_expand "blt"
13704 (if_then_else (match_dup 1)
13705 (label_ref (match_operand 0 "" ""))
13708 "ix86_expand_branch (LT, operands[0]); DONE;")
13710 (define_expand "bltu"
13712 (if_then_else (match_dup 1)
13713 (label_ref (match_operand 0 "" ""))
13716 "ix86_expand_branch (LTU, operands[0]); DONE;")
13718 (define_expand "bge"
13720 (if_then_else (match_dup 1)
13721 (label_ref (match_operand 0 "" ""))
13724 "ix86_expand_branch (GE, operands[0]); DONE;")
13726 (define_expand "bgeu"
13728 (if_then_else (match_dup 1)
13729 (label_ref (match_operand 0 "" ""))
13732 "ix86_expand_branch (GEU, operands[0]); DONE;")
13734 (define_expand "ble"
13736 (if_then_else (match_dup 1)
13737 (label_ref (match_operand 0 "" ""))
13740 "ix86_expand_branch (LE, operands[0]); DONE;")
13742 (define_expand "bleu"
13744 (if_then_else (match_dup 1)
13745 (label_ref (match_operand 0 "" ""))
13748 "ix86_expand_branch (LEU, operands[0]); DONE;")
13750 (define_expand "bunordered"
13752 (if_then_else (match_dup 1)
13753 (label_ref (match_operand 0 "" ""))
13755 "TARGET_80387 || TARGET_SSE_MATH"
13756 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13758 (define_expand "bordered"
13760 (if_then_else (match_dup 1)
13761 (label_ref (match_operand 0 "" ""))
13763 "TARGET_80387 || TARGET_SSE_MATH"
13764 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13766 (define_expand "buneq"
13768 (if_then_else (match_dup 1)
13769 (label_ref (match_operand 0 "" ""))
13771 "TARGET_80387 || TARGET_SSE_MATH"
13772 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13774 (define_expand "bunge"
13776 (if_then_else (match_dup 1)
13777 (label_ref (match_operand 0 "" ""))
13779 "TARGET_80387 || TARGET_SSE_MATH"
13780 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13782 (define_expand "bungt"
13784 (if_then_else (match_dup 1)
13785 (label_ref (match_operand 0 "" ""))
13787 "TARGET_80387 || TARGET_SSE_MATH"
13788 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13790 (define_expand "bunle"
13792 (if_then_else (match_dup 1)
13793 (label_ref (match_operand 0 "" ""))
13795 "TARGET_80387 || TARGET_SSE_MATH"
13796 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13798 (define_expand "bunlt"
13800 (if_then_else (match_dup 1)
13801 (label_ref (match_operand 0 "" ""))
13803 "TARGET_80387 || TARGET_SSE_MATH"
13804 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13806 (define_expand "bltgt"
13808 (if_then_else (match_dup 1)
13809 (label_ref (match_operand 0 "" ""))
13811 "TARGET_80387 || TARGET_SSE_MATH"
13812 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13814 (define_insn "*jcc_1"
13816 (if_then_else (match_operator 1 "ix86_comparison_operator"
13817 [(reg FLAGS_REG) (const_int 0)])
13818 (label_ref (match_operand 0 "" ""))
13822 [(set_attr "type" "ibr")
13823 (set_attr "modrm" "0")
13824 (set (attr "length")
13825 (if_then_else (and (ge (minus (match_dup 0) (pc))
13827 (lt (minus (match_dup 0) (pc))
13832 (define_insn "*jcc_2"
13834 (if_then_else (match_operator 1 "ix86_comparison_operator"
13835 [(reg FLAGS_REG) (const_int 0)])
13837 (label_ref (match_operand 0 "" ""))))]
13840 [(set_attr "type" "ibr")
13841 (set_attr "modrm" "0")
13842 (set (attr "length")
13843 (if_then_else (and (ge (minus (match_dup 0) (pc))
13845 (lt (minus (match_dup 0) (pc))
13850 ;; In general it is not safe to assume too much about CCmode registers,
13851 ;; so simplify-rtx stops when it sees a second one. Under certain
13852 ;; conditions this is safe on x86, so help combine not create
13860 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13861 [(reg FLAGS_REG) (const_int 0)])
13863 (label_ref (match_operand 1 "" ""))
13867 (if_then_else (match_dup 0)
13868 (label_ref (match_dup 1))
13871 PUT_MODE (operands[0], VOIDmode);
13876 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13877 [(reg FLAGS_REG) (const_int 0)])
13879 (label_ref (match_operand 1 "" ""))
13883 (if_then_else (match_dup 0)
13884 (label_ref (match_dup 1))
13887 rtx new_op0 = copy_rtx (operands[0]);
13888 operands[0] = new_op0;
13889 PUT_MODE (new_op0, VOIDmode);
13890 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13891 GET_MODE (XEXP (new_op0, 0))));
13893 /* Make sure that (a) the CCmode we have for the flags is strong
13894 enough for the reversed compare or (b) we have a valid FP compare. */
13895 if (! ix86_comparison_operator (new_op0, VOIDmode))
13899 ;; Define combination compare-and-branch fp compare instructions to use
13900 ;; during early optimization. Splitting the operation apart early makes
13901 ;; for bad code when we want to reverse the operation.
13903 (define_insn "*fp_jcc_1_mixed"
13905 (if_then_else (match_operator 0 "comparison_operator"
13906 [(match_operand 1 "register_operand" "f,x")
13907 (match_operand 2 "nonimmediate_operand" "f,xm")])
13908 (label_ref (match_operand 3 "" ""))
13910 (clobber (reg:CCFP FPSR_REG))
13911 (clobber (reg:CCFP FLAGS_REG))]
13912 "TARGET_MIX_SSE_I387
13913 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13914 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13915 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13918 (define_insn "*fp_jcc_1_sse"
13920 (if_then_else (match_operator 0 "comparison_operator"
13921 [(match_operand 1 "register_operand" "x")
13922 (match_operand 2 "nonimmediate_operand" "xm")])
13923 (label_ref (match_operand 3 "" ""))
13925 (clobber (reg:CCFP FPSR_REG))
13926 (clobber (reg:CCFP FLAGS_REG))]
13928 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13929 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13930 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13933 (define_insn "*fp_jcc_1_387"
13935 (if_then_else (match_operator 0 "comparison_operator"
13936 [(match_operand 1 "register_operand" "f")
13937 (match_operand 2 "register_operand" "f")])
13938 (label_ref (match_operand 3 "" ""))
13940 (clobber (reg:CCFP FPSR_REG))
13941 (clobber (reg:CCFP FLAGS_REG))]
13942 "TARGET_CMOVE && TARGET_80387
13943 && FLOAT_MODE_P (GET_MODE (operands[1]))
13944 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13945 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13948 (define_insn "*fp_jcc_2_mixed"
13950 (if_then_else (match_operator 0 "comparison_operator"
13951 [(match_operand 1 "register_operand" "f,x")
13952 (match_operand 2 "nonimmediate_operand" "f,xm")])
13954 (label_ref (match_operand 3 "" ""))))
13955 (clobber (reg:CCFP FPSR_REG))
13956 (clobber (reg:CCFP FLAGS_REG))]
13957 "TARGET_MIX_SSE_I387
13958 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13959 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13960 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13963 (define_insn "*fp_jcc_2_sse"
13965 (if_then_else (match_operator 0 "comparison_operator"
13966 [(match_operand 1 "register_operand" "x")
13967 (match_operand 2 "nonimmediate_operand" "xm")])
13969 (label_ref (match_operand 3 "" ""))))
13970 (clobber (reg:CCFP FPSR_REG))
13971 (clobber (reg:CCFP FLAGS_REG))]
13973 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13974 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13975 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13978 (define_insn "*fp_jcc_2_387"
13980 (if_then_else (match_operator 0 "comparison_operator"
13981 [(match_operand 1 "register_operand" "f")
13982 (match_operand 2 "register_operand" "f")])
13984 (label_ref (match_operand 3 "" ""))))
13985 (clobber (reg:CCFP FPSR_REG))
13986 (clobber (reg:CCFP FLAGS_REG))]
13987 "TARGET_CMOVE && TARGET_80387
13988 && FLOAT_MODE_P (GET_MODE (operands[1]))
13989 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13990 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13993 (define_insn "*fp_jcc_3_387"
13995 (if_then_else (match_operator 0 "comparison_operator"
13996 [(match_operand 1 "register_operand" "f")
13997 (match_operand 2 "nonimmediate_operand" "fm")])
13998 (label_ref (match_operand 3 "" ""))
14000 (clobber (reg:CCFP FPSR_REG))
14001 (clobber (reg:CCFP FLAGS_REG))
14002 (clobber (match_scratch:HI 4 "=a"))]
14004 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14005 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14006 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14007 && SELECT_CC_MODE (GET_CODE (operands[0]),
14008 operands[1], operands[2]) == CCFPmode
14009 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14012 (define_insn "*fp_jcc_4_387"
14014 (if_then_else (match_operator 0 "comparison_operator"
14015 [(match_operand 1 "register_operand" "f")
14016 (match_operand 2 "nonimmediate_operand" "fm")])
14018 (label_ref (match_operand 3 "" ""))))
14019 (clobber (reg:CCFP FPSR_REG))
14020 (clobber (reg:CCFP FLAGS_REG))
14021 (clobber (match_scratch:HI 4 "=a"))]
14023 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14024 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14025 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14026 && SELECT_CC_MODE (GET_CODE (operands[0]),
14027 operands[1], operands[2]) == CCFPmode
14028 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14031 (define_insn "*fp_jcc_5_387"
14033 (if_then_else (match_operator 0 "comparison_operator"
14034 [(match_operand 1 "register_operand" "f")
14035 (match_operand 2 "register_operand" "f")])
14036 (label_ref (match_operand 3 "" ""))
14038 (clobber (reg:CCFP FPSR_REG))
14039 (clobber (reg:CCFP FLAGS_REG))
14040 (clobber (match_scratch:HI 4 "=a"))]
14042 && FLOAT_MODE_P (GET_MODE (operands[1]))
14043 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14044 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14047 (define_insn "*fp_jcc_6_387"
14049 (if_then_else (match_operator 0 "comparison_operator"
14050 [(match_operand 1 "register_operand" "f")
14051 (match_operand 2 "register_operand" "f")])
14053 (label_ref (match_operand 3 "" ""))))
14054 (clobber (reg:CCFP FPSR_REG))
14055 (clobber (reg:CCFP FLAGS_REG))
14056 (clobber (match_scratch:HI 4 "=a"))]
14058 && FLOAT_MODE_P (GET_MODE (operands[1]))
14059 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14060 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14063 (define_insn "*fp_jcc_7_387"
14065 (if_then_else (match_operator 0 "comparison_operator"
14066 [(match_operand 1 "register_operand" "f")
14067 (match_operand 2 "const0_operand" "X")])
14068 (label_ref (match_operand 3 "" ""))
14070 (clobber (reg:CCFP FPSR_REG))
14071 (clobber (reg:CCFP FLAGS_REG))
14072 (clobber (match_scratch:HI 4 "=a"))]
14074 && FLOAT_MODE_P (GET_MODE (operands[1]))
14075 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14076 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14077 && SELECT_CC_MODE (GET_CODE (operands[0]),
14078 operands[1], operands[2]) == CCFPmode
14079 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14082 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14083 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14084 ;; with a precedence over other operators and is always put in the first
14085 ;; place. Swap condition and operands to match ficom instruction.
14087 (define_insn "*fp_jcc_8<mode>_387"
14089 (if_then_else (match_operator 0 "comparison_operator"
14090 [(match_operator 1 "float_operator"
14091 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14092 (match_operand 3 "register_operand" "f,f")])
14093 (label_ref (match_operand 4 "" ""))
14095 (clobber (reg:CCFP FPSR_REG))
14096 (clobber (reg:CCFP FLAGS_REG))
14097 (clobber (match_scratch:HI 5 "=a,a"))]
14098 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14099 && FLOAT_MODE_P (GET_MODE (operands[3]))
14100 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14101 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14102 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14103 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14108 (if_then_else (match_operator 0 "comparison_operator"
14109 [(match_operand 1 "register_operand" "")
14110 (match_operand 2 "nonimmediate_operand" "")])
14111 (match_operand 3 "" "")
14112 (match_operand 4 "" "")))
14113 (clobber (reg:CCFP FPSR_REG))
14114 (clobber (reg:CCFP FLAGS_REG))]
14118 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14119 operands[3], operands[4], NULL_RTX, NULL_RTX);
14125 (if_then_else (match_operator 0 "comparison_operator"
14126 [(match_operand 1 "register_operand" "")
14127 (match_operand 2 "general_operand" "")])
14128 (match_operand 3 "" "")
14129 (match_operand 4 "" "")))
14130 (clobber (reg:CCFP FPSR_REG))
14131 (clobber (reg:CCFP FLAGS_REG))
14132 (clobber (match_scratch:HI 5 "=a"))]
14136 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14137 operands[3], operands[4], operands[5], NULL_RTX);
14143 (if_then_else (match_operator 0 "comparison_operator"
14144 [(match_operator 1 "float_operator"
14145 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14146 (match_operand 3 "register_operand" "")])
14147 (match_operand 4 "" "")
14148 (match_operand 5 "" "")))
14149 (clobber (reg:CCFP FPSR_REG))
14150 (clobber (reg:CCFP FLAGS_REG))
14151 (clobber (match_scratch:HI 6 "=a"))]
14155 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14156 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14157 operands[3], operands[7],
14158 operands[4], operands[5], operands[6], NULL_RTX);
14162 ;; %%% Kill this when reload knows how to do it.
14165 (if_then_else (match_operator 0 "comparison_operator"
14166 [(match_operator 1 "float_operator"
14167 [(match_operand:X87MODEI12 2 "register_operand" "")])
14168 (match_operand 3 "register_operand" "")])
14169 (match_operand 4 "" "")
14170 (match_operand 5 "" "")))
14171 (clobber (reg:CCFP FPSR_REG))
14172 (clobber (reg:CCFP FLAGS_REG))
14173 (clobber (match_scratch:HI 6 "=a"))]
14177 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14178 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14179 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14180 operands[3], operands[7],
14181 operands[4], operands[5], operands[6], operands[2]);
14185 ;; Unconditional and other jump instructions
14187 (define_insn "jump"
14189 (label_ref (match_operand 0 "" "")))]
14192 [(set_attr "type" "ibr")
14193 (set (attr "length")
14194 (if_then_else (and (ge (minus (match_dup 0) (pc))
14196 (lt (minus (match_dup 0) (pc))
14200 (set_attr "modrm" "0")])
14202 (define_expand "indirect_jump"
14203 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14207 (define_insn "*indirect_jump"
14208 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14211 [(set_attr "type" "ibr")
14212 (set_attr "length_immediate" "0")])
14214 (define_insn "*indirect_jump_rtx64"
14215 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14218 [(set_attr "type" "ibr")
14219 (set_attr "length_immediate" "0")])
14221 (define_expand "tablejump"
14222 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14223 (use (label_ref (match_operand 1 "" "")))])]
14226 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14227 relative. Convert the relative address to an absolute address. */
14231 enum rtx_code code;
14237 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14239 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14243 op1 = pic_offset_table_rtx;
14248 op0 = pic_offset_table_rtx;
14252 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14257 (define_insn "*tablejump_1"
14258 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14259 (use (label_ref (match_operand 1 "" "")))]
14262 [(set_attr "type" "ibr")
14263 (set_attr "length_immediate" "0")])
14265 (define_insn "*tablejump_1_rtx64"
14266 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14267 (use (label_ref (match_operand 1 "" "")))]
14270 [(set_attr "type" "ibr")
14271 (set_attr "length_immediate" "0")])
14273 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14276 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14277 (set (match_operand:QI 1 "register_operand" "")
14278 (match_operator:QI 2 "ix86_comparison_operator"
14279 [(reg FLAGS_REG) (const_int 0)]))
14280 (set (match_operand 3 "q_regs_operand" "")
14281 (zero_extend (match_dup 1)))]
14282 "(peep2_reg_dead_p (3, operands[1])
14283 || operands_match_p (operands[1], operands[3]))
14284 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14285 [(set (match_dup 4) (match_dup 0))
14286 (set (strict_low_part (match_dup 5))
14289 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14290 operands[5] = gen_lowpart (QImode, operands[3]);
14291 ix86_expand_clear (operands[3]);
14294 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14297 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14298 (set (match_operand:QI 1 "register_operand" "")
14299 (match_operator:QI 2 "ix86_comparison_operator"
14300 [(reg FLAGS_REG) (const_int 0)]))
14301 (parallel [(set (match_operand 3 "q_regs_operand" "")
14302 (zero_extend (match_dup 1)))
14303 (clobber (reg:CC FLAGS_REG))])]
14304 "(peep2_reg_dead_p (3, operands[1])
14305 || operands_match_p (operands[1], operands[3]))
14306 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14307 [(set (match_dup 4) (match_dup 0))
14308 (set (strict_low_part (match_dup 5))
14311 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14312 operands[5] = gen_lowpart (QImode, operands[3]);
14313 ix86_expand_clear (operands[3]);
14316 ;; Call instructions.
14318 ;; The predicates normally associated with named expanders are not properly
14319 ;; checked for calls. This is a bug in the generic code, but it isn't that
14320 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14322 ;; Call subroutine returning no value.
14324 (define_expand "call_pop"
14325 [(parallel [(call (match_operand:QI 0 "" "")
14326 (match_operand:SI 1 "" ""))
14327 (set (reg:SI SP_REG)
14328 (plus:SI (reg:SI SP_REG)
14329 (match_operand:SI 3 "" "")))])]
14332 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14336 (define_insn "*call_pop_0"
14337 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14338 (match_operand:SI 1 "" ""))
14339 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14340 (match_operand:SI 2 "immediate_operand" "")))]
14343 if (SIBLING_CALL_P (insn))
14346 return "call\t%P0";
14348 [(set_attr "type" "call")])
14350 (define_insn "*call_pop_1"
14351 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14352 (match_operand:SI 1 "" ""))
14353 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14354 (match_operand:SI 2 "immediate_operand" "i")))]
14357 if (constant_call_address_operand (operands[0], Pmode))
14359 if (SIBLING_CALL_P (insn))
14362 return "call\t%P0";
14364 if (SIBLING_CALL_P (insn))
14367 return "call\t%A0";
14369 [(set_attr "type" "call")])
14371 (define_expand "call"
14372 [(call (match_operand:QI 0 "" "")
14373 (match_operand 1 "" ""))
14374 (use (match_operand 2 "" ""))]
14377 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14381 (define_expand "sibcall"
14382 [(call (match_operand:QI 0 "" "")
14383 (match_operand 1 "" ""))
14384 (use (match_operand 2 "" ""))]
14387 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14391 (define_insn "*call_0"
14392 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14393 (match_operand 1 "" ""))]
14396 if (SIBLING_CALL_P (insn))
14399 return "call\t%P0";
14401 [(set_attr "type" "call")])
14403 (define_insn "*call_1"
14404 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14405 (match_operand 1 "" ""))]
14406 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14408 if (constant_call_address_operand (operands[0], Pmode))
14409 return "call\t%P0";
14410 return "call\t%A0";
14412 [(set_attr "type" "call")])
14414 (define_insn "*sibcall_1"
14415 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14416 (match_operand 1 "" ""))]
14417 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14419 if (constant_call_address_operand (operands[0], Pmode))
14423 [(set_attr "type" "call")])
14425 (define_insn "*call_1_rex64"
14426 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14427 (match_operand 1 "" ""))]
14428 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14430 if (constant_call_address_operand (operands[0], Pmode))
14431 return "call\t%P0";
14432 return "call\t%A0";
14434 [(set_attr "type" "call")])
14436 (define_insn "*sibcall_1_rex64"
14437 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14438 (match_operand 1 "" ""))]
14439 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14441 [(set_attr "type" "call")])
14443 (define_insn "*sibcall_1_rex64_v"
14444 [(call (mem:QI (reg:DI R11_REG))
14445 (match_operand 0 "" ""))]
14446 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14448 [(set_attr "type" "call")])
14451 ;; Call subroutine, returning value in operand 0
14453 (define_expand "call_value_pop"
14454 [(parallel [(set (match_operand 0 "" "")
14455 (call (match_operand:QI 1 "" "")
14456 (match_operand:SI 2 "" "")))
14457 (set (reg:SI SP_REG)
14458 (plus:SI (reg:SI SP_REG)
14459 (match_operand:SI 4 "" "")))])]
14462 ix86_expand_call (operands[0], operands[1], operands[2],
14463 operands[3], operands[4], 0);
14467 (define_expand "call_value"
14468 [(set (match_operand 0 "" "")
14469 (call (match_operand:QI 1 "" "")
14470 (match_operand:SI 2 "" "")))
14471 (use (match_operand:SI 3 "" ""))]
14472 ;; Operand 2 not used on the i386.
14475 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14479 (define_expand "sibcall_value"
14480 [(set (match_operand 0 "" "")
14481 (call (match_operand:QI 1 "" "")
14482 (match_operand:SI 2 "" "")))
14483 (use (match_operand:SI 3 "" ""))]
14484 ;; Operand 2 not used on the i386.
14487 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14491 ;; Call subroutine returning any type.
14493 (define_expand "untyped_call"
14494 [(parallel [(call (match_operand 0 "" "")
14496 (match_operand 1 "" "")
14497 (match_operand 2 "" "")])]
14502 /* In order to give reg-stack an easier job in validating two
14503 coprocessor registers as containing a possible return value,
14504 simply pretend the untyped call returns a complex long double
14507 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14508 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14509 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14512 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14514 rtx set = XVECEXP (operands[2], 0, i);
14515 emit_move_insn (SET_DEST (set), SET_SRC (set));
14518 /* The optimizer does not know that the call sets the function value
14519 registers we stored in the result block. We avoid problems by
14520 claiming that all hard registers are used and clobbered at this
14522 emit_insn (gen_blockage (const0_rtx));
14527 ;; Prologue and epilogue instructions
14529 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14530 ;; all of memory. This blocks insns from being moved across this point.
14532 (define_insn "blockage"
14533 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14536 [(set_attr "length" "0")])
14538 ;; Insn emitted into the body of a function to return from a function.
14539 ;; This is only done if the function's epilogue is known to be simple.
14540 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14542 (define_expand "return"
14544 "ix86_can_use_return_insn_p ()"
14546 if (current_function_pops_args)
14548 rtx popc = GEN_INT (current_function_pops_args);
14549 emit_jump_insn (gen_return_pop_internal (popc));
14554 (define_insn "return_internal"
14558 [(set_attr "length" "1")
14559 (set_attr "length_immediate" "0")
14560 (set_attr "modrm" "0")])
14562 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14563 ;; instruction Athlon and K8 have.
14565 (define_insn "return_internal_long"
14567 (unspec [(const_int 0)] UNSPEC_REP)]
14570 [(set_attr "length" "1")
14571 (set_attr "length_immediate" "0")
14572 (set_attr "prefix_rep" "1")
14573 (set_attr "modrm" "0")])
14575 (define_insn "return_pop_internal"
14577 (use (match_operand:SI 0 "const_int_operand" ""))]
14580 [(set_attr "length" "3")
14581 (set_attr "length_immediate" "2")
14582 (set_attr "modrm" "0")])
14584 (define_insn "return_indirect_internal"
14586 (use (match_operand:SI 0 "register_operand" "r"))]
14589 [(set_attr "type" "ibr")
14590 (set_attr "length_immediate" "0")])
14596 [(set_attr "length" "1")
14597 (set_attr "length_immediate" "0")
14598 (set_attr "modrm" "0")])
14600 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14601 ;; branch prediction penalty for the third jump in a 16-byte
14604 (define_insn "align"
14605 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14608 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14609 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14611 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14612 The align insn is used to avoid 3 jump instructions in the row to improve
14613 branch prediction and the benefits hardly outweigh the cost of extra 8
14614 nops on the average inserted by full alignment pseudo operation. */
14618 [(set_attr "length" "16")])
14620 (define_expand "prologue"
14623 "ix86_expand_prologue (); DONE;")
14625 (define_insn "set_got"
14626 [(set (match_operand:SI 0 "register_operand" "=r")
14627 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14628 (clobber (reg:CC FLAGS_REG))]
14630 { return output_set_got (operands[0], NULL_RTX); }
14631 [(set_attr "type" "multi")
14632 (set_attr "length" "12")])
14634 (define_insn "set_got_labelled"
14635 [(set (match_operand:SI 0 "register_operand" "=r")
14636 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14638 (clobber (reg:CC FLAGS_REG))]
14640 { return output_set_got (operands[0], operands[1]); }
14641 [(set_attr "type" "multi")
14642 (set_attr "length" "12")])
14644 (define_insn "set_got_rex64"
14645 [(set (match_operand:DI 0 "register_operand" "=r")
14646 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14648 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14649 [(set_attr "type" "lea")
14650 (set_attr "length" "6")])
14652 (define_expand "epilogue"
14655 "ix86_expand_epilogue (1); DONE;")
14657 (define_expand "sibcall_epilogue"
14660 "ix86_expand_epilogue (0); DONE;")
14662 (define_expand "eh_return"
14663 [(use (match_operand 0 "register_operand" ""))]
14666 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14668 /* Tricky bit: we write the address of the handler to which we will
14669 be returning into someone else's stack frame, one word below the
14670 stack address we wish to restore. */
14671 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14672 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14673 tmp = gen_rtx_MEM (Pmode, tmp);
14674 emit_move_insn (tmp, ra);
14676 if (Pmode == SImode)
14677 emit_jump_insn (gen_eh_return_si (sa));
14679 emit_jump_insn (gen_eh_return_di (sa));
14684 (define_insn_and_split "eh_return_si"
14686 (unspec [(match_operand:SI 0 "register_operand" "c")]
14687 UNSPEC_EH_RETURN))]
14692 "ix86_expand_epilogue (2); DONE;")
14694 (define_insn_and_split "eh_return_di"
14696 (unspec [(match_operand:DI 0 "register_operand" "c")]
14697 UNSPEC_EH_RETURN))]
14702 "ix86_expand_epilogue (2); DONE;")
14704 (define_insn "leave"
14705 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14706 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14707 (clobber (mem:BLK (scratch)))]
14710 [(set_attr "type" "leave")])
14712 (define_insn "leave_rex64"
14713 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14714 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14715 (clobber (mem:BLK (scratch)))]
14718 [(set_attr "type" "leave")])
14720 (define_expand "ffssi2"
14722 [(set (match_operand:SI 0 "register_operand" "")
14723 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14724 (clobber (match_scratch:SI 2 ""))
14725 (clobber (reg:CC FLAGS_REG))])]
14729 (define_insn_and_split "*ffs_cmove"
14730 [(set (match_operand:SI 0 "register_operand" "=r")
14731 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14732 (clobber (match_scratch:SI 2 "=&r"))
14733 (clobber (reg:CC FLAGS_REG))]
14736 "&& reload_completed"
14737 [(set (match_dup 2) (const_int -1))
14738 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14739 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14740 (set (match_dup 0) (if_then_else:SI
14741 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14744 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14745 (clobber (reg:CC FLAGS_REG))])]
14748 (define_insn_and_split "*ffs_no_cmove"
14749 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14750 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14751 (clobber (match_scratch:SI 2 "=&q"))
14752 (clobber (reg:CC FLAGS_REG))]
14756 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14757 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14758 (set (strict_low_part (match_dup 3))
14759 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14760 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14761 (clobber (reg:CC FLAGS_REG))])
14762 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14763 (clobber (reg:CC FLAGS_REG))])
14764 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14765 (clobber (reg:CC FLAGS_REG))])]
14767 operands[3] = gen_lowpart (QImode, operands[2]);
14768 ix86_expand_clear (operands[2]);
14771 (define_insn "*ffssi_1"
14772 [(set (reg:CCZ FLAGS_REG)
14773 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14775 (set (match_operand:SI 0 "register_operand" "=r")
14776 (ctz:SI (match_dup 1)))]
14778 "bsf{l}\t{%1, %0|%0, %1}"
14779 [(set_attr "prefix_0f" "1")])
14781 (define_expand "ffsdi2"
14783 [(set (match_operand:DI 0 "register_operand" "")
14784 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14785 (clobber (match_scratch:DI 2 ""))
14786 (clobber (reg:CC FLAGS_REG))])]
14787 "TARGET_64BIT && TARGET_CMOVE"
14790 (define_insn_and_split "*ffs_rex64"
14791 [(set (match_operand:DI 0 "register_operand" "=r")
14792 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14793 (clobber (match_scratch:DI 2 "=&r"))
14794 (clobber (reg:CC FLAGS_REG))]
14795 "TARGET_64BIT && TARGET_CMOVE"
14797 "&& reload_completed"
14798 [(set (match_dup 2) (const_int -1))
14799 (parallel [(set (reg:CCZ FLAGS_REG)
14800 (compare:CCZ (match_dup 1) (const_int 0)))
14801 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14802 (set (match_dup 0) (if_then_else:DI
14803 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14806 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14807 (clobber (reg:CC FLAGS_REG))])]
14810 (define_insn "*ffsdi_1"
14811 [(set (reg:CCZ FLAGS_REG)
14812 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14814 (set (match_operand:DI 0 "register_operand" "=r")
14815 (ctz:DI (match_dup 1)))]
14817 "bsf{q}\t{%1, %0|%0, %1}"
14818 [(set_attr "prefix_0f" "1")])
14820 (define_insn "ctzsi2"
14821 [(set (match_operand:SI 0 "register_operand" "=r")
14822 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14823 (clobber (reg:CC FLAGS_REG))]
14825 "bsf{l}\t{%1, %0|%0, %1}"
14826 [(set_attr "prefix_0f" "1")])
14828 (define_insn "ctzdi2"
14829 [(set (match_operand:DI 0 "register_operand" "=r")
14830 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14831 (clobber (reg:CC FLAGS_REG))]
14833 "bsf{q}\t{%1, %0|%0, %1}"
14834 [(set_attr "prefix_0f" "1")])
14836 (define_expand "clzsi2"
14838 [(set (match_operand:SI 0 "register_operand" "")
14839 (minus:SI (const_int 31)
14840 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14841 (clobber (reg:CC FLAGS_REG))])
14843 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14844 (clobber (reg:CC FLAGS_REG))])]
14849 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14854 (define_insn "clzsi2_abm"
14855 [(set (match_operand:SI 0 "register_operand" "=r")
14856 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14857 (clobber (reg:CC FLAGS_REG))]
14859 "lzcnt{l}\t{%1, %0|%0, %1}"
14860 [(set_attr "prefix_rep" "1")
14861 (set_attr "type" "bitmanip")
14862 (set_attr "mode" "SI")])
14864 (define_insn "*bsr"
14865 [(set (match_operand:SI 0 "register_operand" "=r")
14866 (minus:SI (const_int 31)
14867 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14868 (clobber (reg:CC FLAGS_REG))]
14870 "bsr{l}\t{%1, %0|%0, %1}"
14871 [(set_attr "prefix_0f" "1")
14872 (set_attr "mode" "SI")])
14874 (define_insn "popcountsi2"
14875 [(set (match_operand:SI 0 "register_operand" "=r")
14876 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14877 (clobber (reg:CC FLAGS_REG))]
14879 "popcnt{l}\t{%1, %0|%0, %1}"
14880 [(set_attr "prefix_rep" "1")
14881 (set_attr "type" "bitmanip")
14882 (set_attr "mode" "SI")])
14884 (define_insn "*popcountsi2_cmp"
14885 [(set (reg FLAGS_REG)
14887 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14889 (set (match_operand:SI 0 "register_operand" "=r")
14890 (popcount:SI (match_dup 1)))]
14891 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14892 "popcnt{l}\t{%1, %0|%0, %1}"
14893 [(set_attr "prefix_rep" "1")
14894 (set_attr "type" "bitmanip")
14895 (set_attr "mode" "SI")])
14897 (define_insn "*popcountsi2_cmp_zext"
14898 [(set (reg FLAGS_REG)
14900 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14902 (set (match_operand:DI 0 "register_operand" "=r")
14903 (zero_extend:DI(popcount:SI (match_dup 1))))]
14904 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14905 "popcnt{l}\t{%1, %0|%0, %1}"
14906 [(set_attr "prefix_rep" "1")
14907 (set_attr "type" "bitmanip")
14908 (set_attr "mode" "SI")])
14910 (define_insn "bswapsi2"
14911 [(set (match_operand:SI 0 "register_operand" "=r")
14912 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14913 (clobber (reg:CC FLAGS_REG))]
14916 [(set_attr "prefix_0f" "1")
14917 (set_attr "length" "2")])
14919 (define_insn "bswapdi2"
14920 [(set (match_operand:DI 0 "register_operand" "=r")
14921 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14922 (clobber (reg:CC FLAGS_REG))]
14923 "TARGET_64BIT && TARGET_BSWAP"
14925 [(set_attr "prefix_0f" "1")
14926 (set_attr "length" "3")])
14928 (define_expand "clzdi2"
14930 [(set (match_operand:DI 0 "register_operand" "")
14931 (minus:DI (const_int 63)
14932 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14933 (clobber (reg:CC FLAGS_REG))])
14935 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14936 (clobber (reg:CC FLAGS_REG))])]
14941 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14946 (define_insn "clzdi2_abm"
14947 [(set (match_operand:DI 0 "register_operand" "=r")
14948 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14949 (clobber (reg:CC FLAGS_REG))]
14950 "TARGET_64BIT && TARGET_ABM"
14951 "lzcnt{q}\t{%1, %0|%0, %1}"
14952 [(set_attr "prefix_rep" "1")
14953 (set_attr "type" "bitmanip")
14954 (set_attr "mode" "DI")])
14956 (define_insn "*bsr_rex64"
14957 [(set (match_operand:DI 0 "register_operand" "=r")
14958 (minus:DI (const_int 63)
14959 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14960 (clobber (reg:CC FLAGS_REG))]
14962 "bsr{q}\t{%1, %0|%0, %1}"
14963 [(set_attr "prefix_0f" "1")
14964 (set_attr "mode" "DI")])
14966 (define_insn "popcountdi2"
14967 [(set (match_operand:DI 0 "register_operand" "=r")
14968 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14969 (clobber (reg:CC FLAGS_REG))]
14970 "TARGET_64BIT && TARGET_POPCNT"
14971 "popcnt{q}\t{%1, %0|%0, %1}"
14972 [(set_attr "prefix_rep" "1")
14973 (set_attr "type" "bitmanip")
14974 (set_attr "mode" "DI")])
14976 (define_insn "*popcountdi2_cmp"
14977 [(set (reg FLAGS_REG)
14979 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14981 (set (match_operand:DI 0 "register_operand" "=r")
14982 (popcount:DI (match_dup 1)))]
14983 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14984 "popcnt{q}\t{%1, %0|%0, %1}"
14985 [(set_attr "prefix_rep" "1")
14986 (set_attr "type" "bitmanip")
14987 (set_attr "mode" "DI")])
14989 (define_expand "clzhi2"
14991 [(set (match_operand:HI 0 "register_operand" "")
14992 (minus:HI (const_int 15)
14993 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14994 (clobber (reg:CC FLAGS_REG))])
14996 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14997 (clobber (reg:CC FLAGS_REG))])]
15002 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15007 (define_insn "clzhi2_abm"
15008 [(set (match_operand:HI 0 "register_operand" "=r")
15009 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15010 (clobber (reg:CC FLAGS_REG))]
15012 "lzcnt{w}\t{%1, %0|%0, %1}"
15013 [(set_attr "prefix_rep" "1")
15014 (set_attr "type" "bitmanip")
15015 (set_attr "mode" "HI")])
15017 (define_insn "*bsrhi"
15018 [(set (match_operand:HI 0 "register_operand" "=r")
15019 (minus:HI (const_int 15)
15020 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15021 (clobber (reg:CC FLAGS_REG))]
15023 "bsr{w}\t{%1, %0|%0, %1}"
15024 [(set_attr "prefix_0f" "1")
15025 (set_attr "mode" "HI")])
15027 (define_insn "popcounthi2"
15028 [(set (match_operand:HI 0 "register_operand" "=r")
15029 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15030 (clobber (reg:CC FLAGS_REG))]
15032 "popcnt{w}\t{%1, %0|%0, %1}"
15033 [(set_attr "prefix_rep" "1")
15034 (set_attr "type" "bitmanip")
15035 (set_attr "mode" "HI")])
15037 (define_insn "*popcounthi2_cmp"
15038 [(set (reg FLAGS_REG)
15040 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15042 (set (match_operand:HI 0 "register_operand" "=r")
15043 (popcount:HI (match_dup 1)))]
15044 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15045 "popcnt{w}\t{%1, %0|%0, %1}"
15046 [(set_attr "prefix_rep" "1")
15047 (set_attr "type" "bitmanip")
15048 (set_attr "mode" "HI")])
15050 ;; Thread-local storage patterns for ELF.
15052 ;; Note that these code sequences must appear exactly as shown
15053 ;; in order to allow linker relaxation.
15055 (define_insn "*tls_global_dynamic_32_gnu"
15056 [(set (match_operand:SI 0 "register_operand" "=a")
15057 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15058 (match_operand:SI 2 "tls_symbolic_operand" "")
15059 (match_operand:SI 3 "call_insn_operand" "")]
15061 (clobber (match_scratch:SI 4 "=d"))
15062 (clobber (match_scratch:SI 5 "=c"))
15063 (clobber (reg:CC FLAGS_REG))]
15064 "!TARGET_64BIT && TARGET_GNU_TLS"
15065 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15066 [(set_attr "type" "multi")
15067 (set_attr "length" "12")])
15069 (define_insn "*tls_global_dynamic_32_sun"
15070 [(set (match_operand:SI 0 "register_operand" "=a")
15071 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15072 (match_operand:SI 2 "tls_symbolic_operand" "")
15073 (match_operand:SI 3 "call_insn_operand" "")]
15075 (clobber (match_scratch:SI 4 "=d"))
15076 (clobber (match_scratch:SI 5 "=c"))
15077 (clobber (reg:CC FLAGS_REG))]
15078 "!TARGET_64BIT && TARGET_SUN_TLS"
15079 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15080 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15081 [(set_attr "type" "multi")
15082 (set_attr "length" "14")])
15084 (define_expand "tls_global_dynamic_32"
15085 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15088 (match_operand:SI 1 "tls_symbolic_operand" "")
15091 (clobber (match_scratch:SI 4 ""))
15092 (clobber (match_scratch:SI 5 ""))
15093 (clobber (reg:CC FLAGS_REG))])]
15097 operands[2] = pic_offset_table_rtx;
15100 operands[2] = gen_reg_rtx (Pmode);
15101 emit_insn (gen_set_got (operands[2]));
15103 if (TARGET_GNU2_TLS)
15105 emit_insn (gen_tls_dynamic_gnu2_32
15106 (operands[0], operands[1], operands[2]));
15109 operands[3] = ix86_tls_get_addr ();
15112 (define_insn "*tls_global_dynamic_64"
15113 [(set (match_operand:DI 0 "register_operand" "=a")
15114 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15115 (match_operand:DI 3 "" "")))
15116 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15119 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15120 [(set_attr "type" "multi")
15121 (set_attr "length" "16")])
15123 (define_expand "tls_global_dynamic_64"
15124 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15125 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15126 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15130 if (TARGET_GNU2_TLS)
15132 emit_insn (gen_tls_dynamic_gnu2_64
15133 (operands[0], operands[1]));
15136 operands[2] = ix86_tls_get_addr ();
15139 (define_insn "*tls_local_dynamic_base_32_gnu"
15140 [(set (match_operand:SI 0 "register_operand" "=a")
15141 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15142 (match_operand:SI 2 "call_insn_operand" "")]
15143 UNSPEC_TLS_LD_BASE))
15144 (clobber (match_scratch:SI 3 "=d"))
15145 (clobber (match_scratch:SI 4 "=c"))
15146 (clobber (reg:CC FLAGS_REG))]
15147 "!TARGET_64BIT && TARGET_GNU_TLS"
15148 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15149 [(set_attr "type" "multi")
15150 (set_attr "length" "11")])
15152 (define_insn "*tls_local_dynamic_base_32_sun"
15153 [(set (match_operand:SI 0 "register_operand" "=a")
15154 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15155 (match_operand:SI 2 "call_insn_operand" "")]
15156 UNSPEC_TLS_LD_BASE))
15157 (clobber (match_scratch:SI 3 "=d"))
15158 (clobber (match_scratch:SI 4 "=c"))
15159 (clobber (reg:CC FLAGS_REG))]
15160 "!TARGET_64BIT && TARGET_SUN_TLS"
15161 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15162 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15163 [(set_attr "type" "multi")
15164 (set_attr "length" "13")])
15166 (define_expand "tls_local_dynamic_base_32"
15167 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15168 (unspec:SI [(match_dup 1) (match_dup 2)]
15169 UNSPEC_TLS_LD_BASE))
15170 (clobber (match_scratch:SI 3 ""))
15171 (clobber (match_scratch:SI 4 ""))
15172 (clobber (reg:CC FLAGS_REG))])]
15176 operands[1] = pic_offset_table_rtx;
15179 operands[1] = gen_reg_rtx (Pmode);
15180 emit_insn (gen_set_got (operands[1]));
15182 if (TARGET_GNU2_TLS)
15184 emit_insn (gen_tls_dynamic_gnu2_32
15185 (operands[0], ix86_tls_module_base (), operands[1]));
15188 operands[2] = ix86_tls_get_addr ();
15191 (define_insn "*tls_local_dynamic_base_64"
15192 [(set (match_operand:DI 0 "register_operand" "=a")
15193 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15194 (match_operand:DI 2 "" "")))
15195 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15197 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15198 [(set_attr "type" "multi")
15199 (set_attr "length" "12")])
15201 (define_expand "tls_local_dynamic_base_64"
15202 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15203 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15204 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15207 if (TARGET_GNU2_TLS)
15209 emit_insn (gen_tls_dynamic_gnu2_64
15210 (operands[0], ix86_tls_module_base ()));
15213 operands[1] = ix86_tls_get_addr ();
15216 ;; Local dynamic of a single variable is a lose. Show combine how
15217 ;; to convert that back to global dynamic.
15219 (define_insn_and_split "*tls_local_dynamic_32_once"
15220 [(set (match_operand:SI 0 "register_operand" "=a")
15221 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15222 (match_operand:SI 2 "call_insn_operand" "")]
15223 UNSPEC_TLS_LD_BASE)
15224 (const:SI (unspec:SI
15225 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15227 (clobber (match_scratch:SI 4 "=d"))
15228 (clobber (match_scratch:SI 5 "=c"))
15229 (clobber (reg:CC FLAGS_REG))]
15233 [(parallel [(set (match_dup 0)
15234 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15236 (clobber (match_dup 4))
15237 (clobber (match_dup 5))
15238 (clobber (reg:CC FLAGS_REG))])]
15241 ;; Load and add the thread base pointer from %gs:0.
15243 (define_insn "*load_tp_si"
15244 [(set (match_operand:SI 0 "register_operand" "=r")
15245 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15247 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15248 [(set_attr "type" "imov")
15249 (set_attr "modrm" "0")
15250 (set_attr "length" "7")
15251 (set_attr "memory" "load")
15252 (set_attr "imm_disp" "false")])
15254 (define_insn "*add_tp_si"
15255 [(set (match_operand:SI 0 "register_operand" "=r")
15256 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15257 (match_operand:SI 1 "register_operand" "0")))
15258 (clobber (reg:CC FLAGS_REG))]
15260 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15261 [(set_attr "type" "alu")
15262 (set_attr "modrm" "0")
15263 (set_attr "length" "7")
15264 (set_attr "memory" "load")
15265 (set_attr "imm_disp" "false")])
15267 (define_insn "*load_tp_di"
15268 [(set (match_operand:DI 0 "register_operand" "=r")
15269 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15271 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15272 [(set_attr "type" "imov")
15273 (set_attr "modrm" "0")
15274 (set_attr "length" "7")
15275 (set_attr "memory" "load")
15276 (set_attr "imm_disp" "false")])
15278 (define_insn "*add_tp_di"
15279 [(set (match_operand:DI 0 "register_operand" "=r")
15280 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15281 (match_operand:DI 1 "register_operand" "0")))
15282 (clobber (reg:CC FLAGS_REG))]
15284 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15285 [(set_attr "type" "alu")
15286 (set_attr "modrm" "0")
15287 (set_attr "length" "7")
15288 (set_attr "memory" "load")
15289 (set_attr "imm_disp" "false")])
15291 ;; GNU2 TLS patterns can be split.
15293 (define_expand "tls_dynamic_gnu2_32"
15294 [(set (match_dup 3)
15295 (plus:SI (match_operand:SI 2 "register_operand" "")
15297 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15300 [(set (match_operand:SI 0 "register_operand" "")
15301 (unspec:SI [(match_dup 1) (match_dup 3)
15302 (match_dup 2) (reg:SI SP_REG)]
15304 (clobber (reg:CC FLAGS_REG))])]
15305 "!TARGET_64BIT && TARGET_GNU2_TLS"
15307 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15308 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15311 (define_insn "*tls_dynamic_lea_32"
15312 [(set (match_operand:SI 0 "register_operand" "=r")
15313 (plus:SI (match_operand:SI 1 "register_operand" "b")
15315 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15316 UNSPEC_TLSDESC))))]
15317 "!TARGET_64BIT && TARGET_GNU2_TLS"
15318 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15319 [(set_attr "type" "lea")
15320 (set_attr "mode" "SI")
15321 (set_attr "length" "6")
15322 (set_attr "length_address" "4")])
15324 (define_insn "*tls_dynamic_call_32"
15325 [(set (match_operand:SI 0 "register_operand" "=a")
15326 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15327 (match_operand:SI 2 "register_operand" "0")
15328 ;; we have to make sure %ebx still points to the GOT
15329 (match_operand:SI 3 "register_operand" "b")
15332 (clobber (reg:CC FLAGS_REG))]
15333 "!TARGET_64BIT && TARGET_GNU2_TLS"
15334 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15335 [(set_attr "type" "call")
15336 (set_attr "length" "2")
15337 (set_attr "length_address" "0")])
15339 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15340 [(set (match_operand:SI 0 "register_operand" "=&a")
15342 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15343 (match_operand:SI 4 "" "")
15344 (match_operand:SI 2 "register_operand" "b")
15347 (const:SI (unspec:SI
15348 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15350 (clobber (reg:CC FLAGS_REG))]
15351 "!TARGET_64BIT && TARGET_GNU2_TLS"
15354 [(set (match_dup 0) (match_dup 5))]
15356 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15357 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15360 (define_expand "tls_dynamic_gnu2_64"
15361 [(set (match_dup 2)
15362 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15365 [(set (match_operand:DI 0 "register_operand" "")
15366 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15368 (clobber (reg:CC FLAGS_REG))])]
15369 "TARGET_64BIT && TARGET_GNU2_TLS"
15371 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15372 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15375 (define_insn "*tls_dynamic_lea_64"
15376 [(set (match_operand:DI 0 "register_operand" "=r")
15377 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15379 "TARGET_64BIT && TARGET_GNU2_TLS"
15380 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15381 [(set_attr "type" "lea")
15382 (set_attr "mode" "DI")
15383 (set_attr "length" "7")
15384 (set_attr "length_address" "4")])
15386 (define_insn "*tls_dynamic_call_64"
15387 [(set (match_operand:DI 0 "register_operand" "=a")
15388 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15389 (match_operand:DI 2 "register_operand" "0")
15392 (clobber (reg:CC FLAGS_REG))]
15393 "TARGET_64BIT && TARGET_GNU2_TLS"
15394 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15395 [(set_attr "type" "call")
15396 (set_attr "length" "2")
15397 (set_attr "length_address" "0")])
15399 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15400 [(set (match_operand:DI 0 "register_operand" "=&a")
15402 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15403 (match_operand:DI 3 "" "")
15406 (const:DI (unspec:DI
15407 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15409 (clobber (reg:CC FLAGS_REG))]
15410 "TARGET_64BIT && TARGET_GNU2_TLS"
15413 [(set (match_dup 0) (match_dup 4))]
15415 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15416 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15421 ;; These patterns match the binary 387 instructions for addM3, subM3,
15422 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15423 ;; SFmode. The first is the normal insn, the second the same insn but
15424 ;; with one operand a conversion, and the third the same insn but with
15425 ;; the other operand a conversion. The conversion may be SFmode or
15426 ;; SImode if the target mode DFmode, but only SImode if the target mode
15429 ;; Gcc is slightly more smart about handling normal two address instructions
15430 ;; so use special patterns for add and mull.
15432 (define_insn "*fop_sf_comm_mixed"
15433 [(set (match_operand:SF 0 "register_operand" "=f,x")
15434 (match_operator:SF 3 "binary_fp_operator"
15435 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15436 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15437 "TARGET_MIX_SSE_I387
15438 && COMMUTATIVE_ARITH_P (operands[3])
15439 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15440 "* return output_387_binary_op (insn, operands);"
15441 [(set (attr "type")
15442 (if_then_else (eq_attr "alternative" "1")
15443 (if_then_else (match_operand:SF 3 "mult_operator" "")
15444 (const_string "ssemul")
15445 (const_string "sseadd"))
15446 (if_then_else (match_operand:SF 3 "mult_operator" "")
15447 (const_string "fmul")
15448 (const_string "fop"))))
15449 (set_attr "mode" "SF")])
15451 (define_insn "*fop_sf_comm_sse"
15452 [(set (match_operand:SF 0 "register_operand" "=x")
15453 (match_operator:SF 3 "binary_fp_operator"
15454 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15455 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15457 && COMMUTATIVE_ARITH_P (operands[3])
15458 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15459 "* return output_387_binary_op (insn, operands);"
15460 [(set (attr "type")
15461 (if_then_else (match_operand:SF 3 "mult_operator" "")
15462 (const_string "ssemul")
15463 (const_string "sseadd")))
15464 (set_attr "mode" "SF")])
15466 (define_insn "*fop_sf_comm_i387"
15467 [(set (match_operand:SF 0 "register_operand" "=f")
15468 (match_operator:SF 3 "binary_fp_operator"
15469 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15470 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15472 && COMMUTATIVE_ARITH_P (operands[3])
15473 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15474 "* return output_387_binary_op (insn, operands);"
15475 [(set (attr "type")
15476 (if_then_else (match_operand:SF 3 "mult_operator" "")
15477 (const_string "fmul")
15478 (const_string "fop")))
15479 (set_attr "mode" "SF")])
15481 (define_insn "*fop_sf_1_mixed"
15482 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15483 (match_operator:SF 3 "binary_fp_operator"
15484 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15485 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15486 "TARGET_MIX_SSE_I387
15487 && !COMMUTATIVE_ARITH_P (operands[3])
15488 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15489 "* return output_387_binary_op (insn, operands);"
15490 [(set (attr "type")
15491 (cond [(and (eq_attr "alternative" "2")
15492 (match_operand:SF 3 "mult_operator" ""))
15493 (const_string "ssemul")
15494 (and (eq_attr "alternative" "2")
15495 (match_operand:SF 3 "div_operator" ""))
15496 (const_string "ssediv")
15497 (eq_attr "alternative" "2")
15498 (const_string "sseadd")
15499 (match_operand:SF 3 "mult_operator" "")
15500 (const_string "fmul")
15501 (match_operand:SF 3 "div_operator" "")
15502 (const_string "fdiv")
15504 (const_string "fop")))
15505 (set_attr "mode" "SF")])
15507 (define_insn "*fop_sf_1_sse"
15508 [(set (match_operand:SF 0 "register_operand" "=x")
15509 (match_operator:SF 3 "binary_fp_operator"
15510 [(match_operand:SF 1 "register_operand" "0")
15511 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15513 && !COMMUTATIVE_ARITH_P (operands[3])"
15514 "* return output_387_binary_op (insn, operands);"
15515 [(set (attr "type")
15516 (cond [(match_operand:SF 3 "mult_operator" "")
15517 (const_string "ssemul")
15518 (match_operand:SF 3 "div_operator" "")
15519 (const_string "ssediv")
15521 (const_string "sseadd")))
15522 (set_attr "mode" "SF")])
15524 ;; This pattern is not fully shadowed by the pattern above.
15525 (define_insn "*fop_sf_1_i387"
15526 [(set (match_operand:SF 0 "register_operand" "=f,f")
15527 (match_operator:SF 3 "binary_fp_operator"
15528 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15529 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15530 "TARGET_80387 && !TARGET_SSE_MATH
15531 && !COMMUTATIVE_ARITH_P (operands[3])
15532 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15533 "* return output_387_binary_op (insn, operands);"
15534 [(set (attr "type")
15535 (cond [(match_operand:SF 3 "mult_operator" "")
15536 (const_string "fmul")
15537 (match_operand:SF 3 "div_operator" "")
15538 (const_string "fdiv")
15540 (const_string "fop")))
15541 (set_attr "mode" "SF")])
15543 ;; ??? Add SSE splitters for these!
15544 (define_insn "*fop_sf_2<mode>_i387"
15545 [(set (match_operand:SF 0 "register_operand" "=f,f")
15546 (match_operator:SF 3 "binary_fp_operator"
15547 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15548 (match_operand:SF 2 "register_operand" "0,0")]))]
15549 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15550 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15551 [(set (attr "type")
15552 (cond [(match_operand:SF 3 "mult_operator" "")
15553 (const_string "fmul")
15554 (match_operand:SF 3 "div_operator" "")
15555 (const_string "fdiv")
15557 (const_string "fop")))
15558 (set_attr "fp_int_src" "true")
15559 (set_attr "mode" "<MODE>")])
15561 (define_insn "*fop_sf_3<mode>_i387"
15562 [(set (match_operand:SF 0 "register_operand" "=f,f")
15563 (match_operator:SF 3 "binary_fp_operator"
15564 [(match_operand:SF 1 "register_operand" "0,0")
15565 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15566 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15567 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15568 [(set (attr "type")
15569 (cond [(match_operand:SF 3 "mult_operator" "")
15570 (const_string "fmul")
15571 (match_operand:SF 3 "div_operator" "")
15572 (const_string "fdiv")
15574 (const_string "fop")))
15575 (set_attr "fp_int_src" "true")
15576 (set_attr "mode" "<MODE>")])
15578 (define_insn "*fop_df_comm_mixed"
15579 [(set (match_operand:DF 0 "register_operand" "=f,x")
15580 (match_operator:DF 3 "binary_fp_operator"
15581 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15582 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15583 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15584 && COMMUTATIVE_ARITH_P (operands[3])
15585 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15586 "* return output_387_binary_op (insn, operands);"
15587 [(set (attr "type")
15588 (if_then_else (eq_attr "alternative" "1")
15589 (if_then_else (match_operand:DF 3 "mult_operator" "")
15590 (const_string "ssemul")
15591 (const_string "sseadd"))
15592 (if_then_else (match_operand:DF 3 "mult_operator" "")
15593 (const_string "fmul")
15594 (const_string "fop"))))
15595 (set_attr "mode" "DF")])
15597 (define_insn "*fop_df_comm_sse"
15598 [(set (match_operand:DF 0 "register_operand" "=x")
15599 (match_operator:DF 3 "binary_fp_operator"
15600 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15601 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15602 "TARGET_SSE2 && TARGET_SSE_MATH
15603 && COMMUTATIVE_ARITH_P (operands[3])
15604 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15605 "* return output_387_binary_op (insn, operands);"
15606 [(set (attr "type")
15607 (if_then_else (match_operand:DF 3 "mult_operator" "")
15608 (const_string "ssemul")
15609 (const_string "sseadd")))
15610 (set_attr "mode" "DF")])
15612 (define_insn "*fop_df_comm_i387"
15613 [(set (match_operand:DF 0 "register_operand" "=f")
15614 (match_operator:DF 3 "binary_fp_operator"
15615 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15616 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15618 && COMMUTATIVE_ARITH_P (operands[3])
15619 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15620 "* return output_387_binary_op (insn, operands);"
15621 [(set (attr "type")
15622 (if_then_else (match_operand:DF 3 "mult_operator" "")
15623 (const_string "fmul")
15624 (const_string "fop")))
15625 (set_attr "mode" "DF")])
15627 (define_insn "*fop_df_1_mixed"
15628 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15629 (match_operator:DF 3 "binary_fp_operator"
15630 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15631 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15632 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15633 && !COMMUTATIVE_ARITH_P (operands[3])
15634 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15635 "* return output_387_binary_op (insn, operands);"
15636 [(set (attr "type")
15637 (cond [(and (eq_attr "alternative" "2")
15638 (match_operand:DF 3 "mult_operator" ""))
15639 (const_string "ssemul")
15640 (and (eq_attr "alternative" "2")
15641 (match_operand:DF 3 "div_operator" ""))
15642 (const_string "ssediv")
15643 (eq_attr "alternative" "2")
15644 (const_string "sseadd")
15645 (match_operand:DF 3 "mult_operator" "")
15646 (const_string "fmul")
15647 (match_operand:DF 3 "div_operator" "")
15648 (const_string "fdiv")
15650 (const_string "fop")))
15651 (set_attr "mode" "DF")])
15653 (define_insn "*fop_df_1_sse"
15654 [(set (match_operand:DF 0 "register_operand" "=x")
15655 (match_operator:DF 3 "binary_fp_operator"
15656 [(match_operand:DF 1 "register_operand" "0")
15657 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15658 "TARGET_SSE2 && TARGET_SSE_MATH
15659 && !COMMUTATIVE_ARITH_P (operands[3])"
15660 "* return output_387_binary_op (insn, operands);"
15661 [(set_attr "mode" "DF")
15663 (cond [(match_operand:DF 3 "mult_operator" "")
15664 (const_string "ssemul")
15665 (match_operand:DF 3 "div_operator" "")
15666 (const_string "ssediv")
15668 (const_string "sseadd")))])
15670 ;; This pattern is not fully shadowed by the pattern above.
15671 (define_insn "*fop_df_1_i387"
15672 [(set (match_operand:DF 0 "register_operand" "=f,f")
15673 (match_operator:DF 3 "binary_fp_operator"
15674 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15675 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15676 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15677 && !COMMUTATIVE_ARITH_P (operands[3])
15678 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15679 "* return output_387_binary_op (insn, operands);"
15680 [(set (attr "type")
15681 (cond [(match_operand:DF 3 "mult_operator" "")
15682 (const_string "fmul")
15683 (match_operand:DF 3 "div_operator" "")
15684 (const_string "fdiv")
15686 (const_string "fop")))
15687 (set_attr "mode" "DF")])
15689 ;; ??? Add SSE splitters for these!
15690 (define_insn "*fop_df_2<mode>_i387"
15691 [(set (match_operand:DF 0 "register_operand" "=f,f")
15692 (match_operator:DF 3 "binary_fp_operator"
15693 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15694 (match_operand:DF 2 "register_operand" "0,0")]))]
15695 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15696 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15697 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15698 [(set (attr "type")
15699 (cond [(match_operand:DF 3 "mult_operator" "")
15700 (const_string "fmul")
15701 (match_operand:DF 3 "div_operator" "")
15702 (const_string "fdiv")
15704 (const_string "fop")))
15705 (set_attr "fp_int_src" "true")
15706 (set_attr "mode" "<MODE>")])
15708 (define_insn "*fop_df_3<mode>_i387"
15709 [(set (match_operand:DF 0 "register_operand" "=f,f")
15710 (match_operator:DF 3 "binary_fp_operator"
15711 [(match_operand:DF 1 "register_operand" "0,0")
15712 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15713 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15714 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15715 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15716 [(set (attr "type")
15717 (cond [(match_operand:DF 3 "mult_operator" "")
15718 (const_string "fmul")
15719 (match_operand:DF 3 "div_operator" "")
15720 (const_string "fdiv")
15722 (const_string "fop")))
15723 (set_attr "fp_int_src" "true")
15724 (set_attr "mode" "<MODE>")])
15726 (define_insn "*fop_df_4_i387"
15727 [(set (match_operand:DF 0 "register_operand" "=f,f")
15728 (match_operator:DF 3 "binary_fp_operator"
15729 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15730 (match_operand:DF 2 "register_operand" "0,f")]))]
15731 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15732 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15733 "* return output_387_binary_op (insn, operands);"
15734 [(set (attr "type")
15735 (cond [(match_operand:DF 3 "mult_operator" "")
15736 (const_string "fmul")
15737 (match_operand:DF 3 "div_operator" "")
15738 (const_string "fdiv")
15740 (const_string "fop")))
15741 (set_attr "mode" "SF")])
15743 (define_insn "*fop_df_5_i387"
15744 [(set (match_operand:DF 0 "register_operand" "=f,f")
15745 (match_operator:DF 3 "binary_fp_operator"
15746 [(match_operand:DF 1 "register_operand" "0,f")
15748 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15749 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15750 "* return output_387_binary_op (insn, operands);"
15751 [(set (attr "type")
15752 (cond [(match_operand:DF 3 "mult_operator" "")
15753 (const_string "fmul")
15754 (match_operand:DF 3 "div_operator" "")
15755 (const_string "fdiv")
15757 (const_string "fop")))
15758 (set_attr "mode" "SF")])
15760 (define_insn "*fop_df_6_i387"
15761 [(set (match_operand:DF 0 "register_operand" "=f,f")
15762 (match_operator:DF 3 "binary_fp_operator"
15764 (match_operand:SF 1 "register_operand" "0,f"))
15766 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15767 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15768 "* return output_387_binary_op (insn, operands);"
15769 [(set (attr "type")
15770 (cond [(match_operand:DF 3 "mult_operator" "")
15771 (const_string "fmul")
15772 (match_operand:DF 3 "div_operator" "")
15773 (const_string "fdiv")
15775 (const_string "fop")))
15776 (set_attr "mode" "SF")])
15778 (define_insn "*fop_xf_comm_i387"
15779 [(set (match_operand:XF 0 "register_operand" "=f")
15780 (match_operator:XF 3 "binary_fp_operator"
15781 [(match_operand:XF 1 "register_operand" "%0")
15782 (match_operand:XF 2 "register_operand" "f")]))]
15784 && COMMUTATIVE_ARITH_P (operands[3])"
15785 "* return output_387_binary_op (insn, operands);"
15786 [(set (attr "type")
15787 (if_then_else (match_operand:XF 3 "mult_operator" "")
15788 (const_string "fmul")
15789 (const_string "fop")))
15790 (set_attr "mode" "XF")])
15792 (define_insn "*fop_xf_1_i387"
15793 [(set (match_operand:XF 0 "register_operand" "=f,f")
15794 (match_operator:XF 3 "binary_fp_operator"
15795 [(match_operand:XF 1 "register_operand" "0,f")
15796 (match_operand:XF 2 "register_operand" "f,0")]))]
15798 && !COMMUTATIVE_ARITH_P (operands[3])"
15799 "* return output_387_binary_op (insn, operands);"
15800 [(set (attr "type")
15801 (cond [(match_operand:XF 3 "mult_operator" "")
15802 (const_string "fmul")
15803 (match_operand:XF 3 "div_operator" "")
15804 (const_string "fdiv")
15806 (const_string "fop")))
15807 (set_attr "mode" "XF")])
15809 (define_insn "*fop_xf_2<mode>_i387"
15810 [(set (match_operand:XF 0 "register_operand" "=f,f")
15811 (match_operator:XF 3 "binary_fp_operator"
15812 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15813 (match_operand:XF 2 "register_operand" "0,0")]))]
15814 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15815 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15816 [(set (attr "type")
15817 (cond [(match_operand:XF 3 "mult_operator" "")
15818 (const_string "fmul")
15819 (match_operand:XF 3 "div_operator" "")
15820 (const_string "fdiv")
15822 (const_string "fop")))
15823 (set_attr "fp_int_src" "true")
15824 (set_attr "mode" "<MODE>")])
15826 (define_insn "*fop_xf_3<mode>_i387"
15827 [(set (match_operand:XF 0 "register_operand" "=f,f")
15828 (match_operator:XF 3 "binary_fp_operator"
15829 [(match_operand:XF 1 "register_operand" "0,0")
15830 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15831 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15832 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15833 [(set (attr "type")
15834 (cond [(match_operand:XF 3 "mult_operator" "")
15835 (const_string "fmul")
15836 (match_operand:XF 3 "div_operator" "")
15837 (const_string "fdiv")
15839 (const_string "fop")))
15840 (set_attr "fp_int_src" "true")
15841 (set_attr "mode" "<MODE>")])
15843 (define_insn "*fop_xf_4_i387"
15844 [(set (match_operand:XF 0 "register_operand" "=f,f")
15845 (match_operator:XF 3 "binary_fp_operator"
15847 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15848 (match_operand:XF 2 "register_operand" "0,f")]))]
15850 "* return output_387_binary_op (insn, operands);"
15851 [(set (attr "type")
15852 (cond [(match_operand:XF 3 "mult_operator" "")
15853 (const_string "fmul")
15854 (match_operand:XF 3 "div_operator" "")
15855 (const_string "fdiv")
15857 (const_string "fop")))
15858 (set_attr "mode" "SF")])
15860 (define_insn "*fop_xf_5_i387"
15861 [(set (match_operand:XF 0 "register_operand" "=f,f")
15862 (match_operator:XF 3 "binary_fp_operator"
15863 [(match_operand:XF 1 "register_operand" "0,f")
15865 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15867 "* return output_387_binary_op (insn, operands);"
15868 [(set (attr "type")
15869 (cond [(match_operand:XF 3 "mult_operator" "")
15870 (const_string "fmul")
15871 (match_operand:XF 3 "div_operator" "")
15872 (const_string "fdiv")
15874 (const_string "fop")))
15875 (set_attr "mode" "SF")])
15877 (define_insn "*fop_xf_6_i387"
15878 [(set (match_operand:XF 0 "register_operand" "=f,f")
15879 (match_operator:XF 3 "binary_fp_operator"
15881 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15883 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15885 "* return output_387_binary_op (insn, operands);"
15886 [(set (attr "type")
15887 (cond [(match_operand:XF 3 "mult_operator" "")
15888 (const_string "fmul")
15889 (match_operand:XF 3 "div_operator" "")
15890 (const_string "fdiv")
15892 (const_string "fop")))
15893 (set_attr "mode" "SF")])
15896 [(set (match_operand 0 "register_operand" "")
15897 (match_operator 3 "binary_fp_operator"
15898 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15899 (match_operand 2 "register_operand" "")]))]
15900 "TARGET_80387 && reload_completed
15901 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15904 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15905 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15906 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15907 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15908 GET_MODE (operands[3]),
15911 ix86_free_from_memory (GET_MODE (operands[1]));
15916 [(set (match_operand 0 "register_operand" "")
15917 (match_operator 3 "binary_fp_operator"
15918 [(match_operand 1 "register_operand" "")
15919 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15920 "TARGET_80387 && reload_completed
15921 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15924 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15925 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15926 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15927 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15928 GET_MODE (operands[3]),
15931 ix86_free_from_memory (GET_MODE (operands[2]));
15935 ;; FPU special functions.
15937 ;; This pattern implements a no-op XFmode truncation for
15938 ;; all fancy i386 XFmode math functions.
15940 (define_insn "truncxf<mode>2_i387_noop_unspec"
15941 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15942 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15943 UNSPEC_TRUNC_NOOP))]
15944 "TARGET_USE_FANCY_MATH_387"
15945 "* return output_387_reg_move (insn, operands);"
15946 [(set_attr "type" "fmov")
15947 (set_attr "mode" "<MODE>")])
15949 (define_insn "sqrtxf2"
15950 [(set (match_operand:XF 0 "register_operand" "=f")
15951 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15952 "TARGET_USE_FANCY_MATH_387"
15954 [(set_attr "type" "fpspc")
15955 (set_attr "mode" "XF")
15956 (set_attr "athlon_decode" "direct")
15957 (set_attr "amdfam10_decode" "direct")])
15959 (define_insn "sqrt_extend<mode>xf2_i387"
15960 [(set (match_operand:XF 0 "register_operand" "=f")
15963 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15964 "TARGET_USE_FANCY_MATH_387"
15966 [(set_attr "type" "fpspc")
15967 (set_attr "mode" "XF")
15968 (set_attr "athlon_decode" "direct")
15969 (set_attr "amdfam10_decode" "direct")])
15971 (define_insn "*sqrt<mode>2_sse"
15972 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15974 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15975 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15976 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15977 [(set_attr "type" "sse")
15978 (set_attr "mode" "<MODE>")
15979 (set_attr "athlon_decode" "*")
15980 (set_attr "amdfam10_decode" "*")])
15982 (define_expand "sqrt<mode>2"
15983 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15985 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15986 "TARGET_USE_FANCY_MATH_387
15987 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15989 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15991 rtx op0 = gen_reg_rtx (XFmode);
15992 rtx op1 = force_reg (<MODE>mode, operands[1]);
15994 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15995 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16000 (define_insn "fpremxf4_i387"
16001 [(set (match_operand:XF 0 "register_operand" "=f")
16002 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16003 (match_operand:XF 3 "register_operand" "1")]
16005 (set (match_operand:XF 1 "register_operand" "=u")
16006 (unspec:XF [(match_dup 2) (match_dup 3)]
16008 (set (reg:CCFP FPSR_REG)
16009 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16010 "TARGET_USE_FANCY_MATH_387"
16012 [(set_attr "type" "fpspc")
16013 (set_attr "mode" "XF")])
16015 (define_expand "fmodxf3"
16016 [(use (match_operand:XF 0 "register_operand" ""))
16017 (use (match_operand:XF 1 "register_operand" ""))
16018 (use (match_operand:XF 2 "register_operand" ""))]
16019 "TARGET_USE_FANCY_MATH_387"
16021 rtx label = gen_label_rtx ();
16023 emit_label (label);
16025 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16026 operands[1], operands[2]));
16027 ix86_emit_fp_unordered_jump (label);
16029 emit_move_insn (operands[0], operands[1]);
16033 (define_expand "fmod<mode>3"
16034 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16035 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16036 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16037 "TARGET_USE_FANCY_MATH_387"
16039 rtx label = gen_label_rtx ();
16041 rtx op1 = gen_reg_rtx (XFmode);
16042 rtx op2 = gen_reg_rtx (XFmode);
16044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16045 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16047 emit_label (label);
16048 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16049 ix86_emit_fp_unordered_jump (label);
16051 /* Truncate the result properly for strict SSE math. */
16052 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16053 && !TARGET_MIX_SSE_I387)
16054 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16056 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16061 (define_insn "fprem1xf4_i387"
16062 [(set (match_operand:XF 0 "register_operand" "=f")
16063 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16064 (match_operand:XF 3 "register_operand" "1")]
16066 (set (match_operand:XF 1 "register_operand" "=u")
16067 (unspec:XF [(match_dup 2) (match_dup 3)]
16069 (set (reg:CCFP FPSR_REG)
16070 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16071 "TARGET_USE_FANCY_MATH_387"
16073 [(set_attr "type" "fpspc")
16074 (set_attr "mode" "XF")])
16076 (define_expand "remainderxf3"
16077 [(use (match_operand:XF 0 "register_operand" ""))
16078 (use (match_operand:XF 1 "register_operand" ""))
16079 (use (match_operand:XF 2 "register_operand" ""))]
16080 "TARGET_USE_FANCY_MATH_387"
16082 rtx label = gen_label_rtx ();
16084 emit_label (label);
16086 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16087 operands[1], operands[2]));
16088 ix86_emit_fp_unordered_jump (label);
16090 emit_move_insn (operands[0], operands[1]);
16094 (define_expand "remainder<mode>3"
16095 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16096 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16097 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16098 "TARGET_USE_FANCY_MATH_387"
16100 rtx label = gen_label_rtx ();
16102 rtx op1 = gen_reg_rtx (XFmode);
16103 rtx op2 = gen_reg_rtx (XFmode);
16105 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16106 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16108 emit_label (label);
16110 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16111 ix86_emit_fp_unordered_jump (label);
16113 /* Truncate the result properly for strict SSE math. */
16114 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16115 && !TARGET_MIX_SSE_I387)
16116 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16118 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16123 (define_insn "*sinxf2_i387"
16124 [(set (match_operand:XF 0 "register_operand" "=f")
16125 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16126 "TARGET_USE_FANCY_MATH_387
16127 && flag_unsafe_math_optimizations"
16129 [(set_attr "type" "fpspc")
16130 (set_attr "mode" "XF")])
16132 (define_insn "*sin_extend<mode>xf2_i387"
16133 [(set (match_operand:XF 0 "register_operand" "=f")
16134 (unspec:XF [(float_extend:XF
16135 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16137 "TARGET_USE_FANCY_MATH_387
16138 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16139 || TARGET_MIX_SSE_I387)
16140 && flag_unsafe_math_optimizations"
16142 [(set_attr "type" "fpspc")
16143 (set_attr "mode" "XF")])
16145 (define_insn "*cosxf2_i387"
16146 [(set (match_operand:XF 0 "register_operand" "=f")
16147 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16148 "TARGET_USE_FANCY_MATH_387
16149 && flag_unsafe_math_optimizations"
16151 [(set_attr "type" "fpspc")
16152 (set_attr "mode" "XF")])
16154 (define_insn "*cos_extend<mode>xf2_i387"
16155 [(set (match_operand:XF 0 "register_operand" "=f")
16156 (unspec:XF [(float_extend:XF
16157 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16159 "TARGET_USE_FANCY_MATH_387
16160 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16161 || TARGET_MIX_SSE_I387)
16162 && flag_unsafe_math_optimizations"
16164 [(set_attr "type" "fpspc")
16165 (set_attr "mode" "XF")])
16167 ;; When sincos pattern is defined, sin and cos builtin functions will be
16168 ;; expanded to sincos pattern with one of its outputs left unused.
16169 ;; CSE pass will figure out if two sincos patterns can be combined,
16170 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16171 ;; depending on the unused output.
16173 (define_insn "sincosxf3"
16174 [(set (match_operand:XF 0 "register_operand" "=f")
16175 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16176 UNSPEC_SINCOS_COS))
16177 (set (match_operand:XF 1 "register_operand" "=u")
16178 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16179 "TARGET_USE_FANCY_MATH_387
16180 && flag_unsafe_math_optimizations"
16182 [(set_attr "type" "fpspc")
16183 (set_attr "mode" "XF")])
16186 [(set (match_operand:XF 0 "register_operand" "")
16187 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16188 UNSPEC_SINCOS_COS))
16189 (set (match_operand:XF 1 "register_operand" "")
16190 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16191 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16192 && !reload_completed && !reload_in_progress"
16193 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16197 [(set (match_operand:XF 0 "register_operand" "")
16198 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16199 UNSPEC_SINCOS_COS))
16200 (set (match_operand:XF 1 "register_operand" "")
16201 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16202 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16203 && !reload_completed && !reload_in_progress"
16204 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16207 (define_insn "sincos_extend<mode>xf3_i387"
16208 [(set (match_operand:XF 0 "register_operand" "=f")
16209 (unspec:XF [(float_extend:XF
16210 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16211 UNSPEC_SINCOS_COS))
16212 (set (match_operand:XF 1 "register_operand" "=u")
16213 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16214 "TARGET_USE_FANCY_MATH_387
16215 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16216 || TARGET_MIX_SSE_I387)
16217 && flag_unsafe_math_optimizations"
16219 [(set_attr "type" "fpspc")
16220 (set_attr "mode" "XF")])
16223 [(set (match_operand:XF 0 "register_operand" "")
16224 (unspec:XF [(float_extend:XF
16225 (match_operand:X87MODEF12 2 "register_operand" ""))]
16226 UNSPEC_SINCOS_COS))
16227 (set (match_operand:XF 1 "register_operand" "")
16228 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16229 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16230 && !reload_completed && !reload_in_progress"
16231 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16235 [(set (match_operand:XF 0 "register_operand" "")
16236 (unspec:XF [(float_extend:XF
16237 (match_operand:X87MODEF12 2 "register_operand" ""))]
16238 UNSPEC_SINCOS_COS))
16239 (set (match_operand:XF 1 "register_operand" "")
16240 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16241 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16242 && !reload_completed && !reload_in_progress"
16243 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16246 (define_expand "sincos<mode>3"
16247 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16248 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16249 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16250 "TARGET_USE_FANCY_MATH_387
16251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16252 || TARGET_MIX_SSE_I387)
16253 && flag_unsafe_math_optimizations"
16255 rtx op0 = gen_reg_rtx (XFmode);
16256 rtx op1 = gen_reg_rtx (XFmode);
16258 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16259 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16260 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16264 (define_insn "fptanxf4_i387"
16265 [(set (match_operand:XF 0 "register_operand" "=f")
16266 (match_operand:XF 3 "const_double_operand" "F"))
16267 (set (match_operand:XF 1 "register_operand" "=u")
16268 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16270 "TARGET_USE_FANCY_MATH_387
16271 && flag_unsafe_math_optimizations
16272 && standard_80387_constant_p (operands[3]) == 2"
16274 [(set_attr "type" "fpspc")
16275 (set_attr "mode" "XF")])
16277 (define_insn "fptan_extend<mode>xf4_i387"
16278 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16279 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16280 (set (match_operand:XF 1 "register_operand" "=u")
16281 (unspec:XF [(float_extend:XF
16282 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16284 "TARGET_USE_FANCY_MATH_387
16285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16286 || TARGET_MIX_SSE_I387)
16287 && flag_unsafe_math_optimizations
16288 && standard_80387_constant_p (operands[3]) == 2"
16290 [(set_attr "type" "fpspc")
16291 (set_attr "mode" "XF")])
16293 (define_expand "tanxf2"
16294 [(use (match_operand:XF 0 "register_operand" ""))
16295 (use (match_operand:XF 1 "register_operand" ""))]
16296 "TARGET_USE_FANCY_MATH_387
16297 && flag_unsafe_math_optimizations"
16299 rtx one = gen_reg_rtx (XFmode);
16300 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16302 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16306 (define_expand "tan<mode>2"
16307 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16308 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16309 "TARGET_USE_FANCY_MATH_387
16310 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16311 || TARGET_MIX_SSE_I387)
16312 && flag_unsafe_math_optimizations"
16314 rtx op0 = gen_reg_rtx (XFmode);
16316 rtx one = gen_reg_rtx (<MODE>mode);
16317 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16319 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16320 operands[1], op2));
16321 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16325 (define_insn "*fpatanxf3_i387"
16326 [(set (match_operand:XF 0 "register_operand" "=f")
16327 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16328 (match_operand:XF 2 "register_operand" "u")]
16330 (clobber (match_scratch:XF 3 "=2"))]
16331 "TARGET_USE_FANCY_MATH_387
16332 && flag_unsafe_math_optimizations"
16334 [(set_attr "type" "fpspc")
16335 (set_attr "mode" "XF")])
16337 (define_insn "fpatan_extend<mode>xf3_i387"
16338 [(set (match_operand:XF 0 "register_operand" "=f")
16339 (unspec:XF [(float_extend:XF
16340 (match_operand:X87MODEF12 1 "register_operand" "0"))
16342 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16344 (clobber (match_scratch:XF 3 "=2"))]
16345 "TARGET_USE_FANCY_MATH_387
16346 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16347 || TARGET_MIX_SSE_I387)
16348 && flag_unsafe_math_optimizations"
16350 [(set_attr "type" "fpspc")
16351 (set_attr "mode" "XF")])
16353 (define_expand "atan2xf3"
16354 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16355 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16356 (match_operand:XF 1 "register_operand" "")]
16358 (clobber (match_scratch:XF 3 ""))])]
16359 "TARGET_USE_FANCY_MATH_387
16360 && flag_unsafe_math_optimizations"
16363 (define_expand "atan2<mode>3"
16364 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16365 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16366 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16367 "TARGET_USE_FANCY_MATH_387
16368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16369 || TARGET_MIX_SSE_I387)
16370 && flag_unsafe_math_optimizations"
16372 rtx op0 = gen_reg_rtx (XFmode);
16374 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16375 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16379 (define_expand "atanxf2"
16380 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16381 (unspec:XF [(match_dup 2)
16382 (match_operand:XF 1 "register_operand" "")]
16384 (clobber (match_scratch:XF 3 ""))])]
16385 "TARGET_USE_FANCY_MATH_387
16386 && flag_unsafe_math_optimizations"
16388 operands[2] = gen_reg_rtx (XFmode);
16389 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16392 (define_expand "atan<mode>2"
16393 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16394 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16395 "TARGET_USE_FANCY_MATH_387
16396 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16397 || TARGET_MIX_SSE_I387)
16398 && flag_unsafe_math_optimizations"
16400 rtx op0 = gen_reg_rtx (XFmode);
16402 rtx op2 = gen_reg_rtx (<MODE>mode);
16403 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16405 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16406 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16410 (define_expand "asinxf2"
16411 [(set (match_dup 2)
16412 (mult:XF (match_operand:XF 1 "register_operand" "")
16414 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16415 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16416 (parallel [(set (match_operand:XF 0 "register_operand" "")
16417 (unspec:XF [(match_dup 5) (match_dup 1)]
16419 (clobber (match_scratch:XF 6 ""))])]
16420 "TARGET_USE_FANCY_MATH_387
16421 && flag_unsafe_math_optimizations && !optimize_size"
16425 for (i = 2; i < 6; i++)
16426 operands[i] = gen_reg_rtx (XFmode);
16428 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16431 (define_expand "asin<mode>2"
16432 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16433 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16434 "TARGET_USE_FANCY_MATH_387
16435 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16436 || TARGET_MIX_SSE_I387)
16437 && flag_unsafe_math_optimizations && !optimize_size"
16439 rtx op0 = gen_reg_rtx (XFmode);
16440 rtx op1 = gen_reg_rtx (XFmode);
16442 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16443 emit_insn (gen_asinxf2 (op0, op1));
16444 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16448 (define_expand "acosxf2"
16449 [(set (match_dup 2)
16450 (mult:XF (match_operand:XF 1 "register_operand" "")
16452 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16453 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16454 (parallel [(set (match_operand:XF 0 "register_operand" "")
16455 (unspec:XF [(match_dup 1) (match_dup 5)]
16457 (clobber (match_scratch:XF 6 ""))])]
16458 "TARGET_USE_FANCY_MATH_387
16459 && flag_unsafe_math_optimizations && !optimize_size"
16463 for (i = 2; i < 6; i++)
16464 operands[i] = gen_reg_rtx (XFmode);
16466 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16469 (define_expand "acos<mode>2"
16470 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16471 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16472 "TARGET_USE_FANCY_MATH_387
16473 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16474 || TARGET_MIX_SSE_I387)
16475 && flag_unsafe_math_optimizations && !optimize_size"
16477 rtx op0 = gen_reg_rtx (XFmode);
16478 rtx op1 = gen_reg_rtx (XFmode);
16480 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16481 emit_insn (gen_acosxf2 (op0, op1));
16482 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16486 (define_insn "fyl2xxf3_i387"
16487 [(set (match_operand:XF 0 "register_operand" "=f")
16488 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16489 (match_operand:XF 2 "register_operand" "u")]
16491 (clobber (match_scratch:XF 3 "=2"))]
16492 "TARGET_USE_FANCY_MATH_387
16493 && flag_unsafe_math_optimizations"
16495 [(set_attr "type" "fpspc")
16496 (set_attr "mode" "XF")])
16498 (define_insn "fyl2x_extend<mode>xf3_i387"
16499 [(set (match_operand:XF 0 "register_operand" "=f")
16500 (unspec:XF [(float_extend:XF
16501 (match_operand:X87MODEF12 1 "register_operand" "0"))
16502 (match_operand:XF 2 "register_operand" "u")]
16504 (clobber (match_scratch:XF 3 "=2"))]
16505 "TARGET_USE_FANCY_MATH_387
16506 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16507 || TARGET_MIX_SSE_I387)
16508 && flag_unsafe_math_optimizations"
16510 [(set_attr "type" "fpspc")
16511 (set_attr "mode" "XF")])
16513 (define_expand "logxf2"
16514 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16515 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16516 (match_dup 2)] UNSPEC_FYL2X))
16517 (clobber (match_scratch:XF 3 ""))])]
16518 "TARGET_USE_FANCY_MATH_387
16519 && flag_unsafe_math_optimizations"
16521 operands[2] = gen_reg_rtx (XFmode);
16522 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16525 (define_expand "log<mode>2"
16526 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16527 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16528 "TARGET_USE_FANCY_MATH_387
16529 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16530 || TARGET_MIX_SSE_I387)
16531 && flag_unsafe_math_optimizations"
16533 rtx op0 = gen_reg_rtx (XFmode);
16535 rtx op2 = gen_reg_rtx (XFmode);
16536 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16538 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16539 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16543 (define_expand "log10xf2"
16544 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16545 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16546 (match_dup 2)] UNSPEC_FYL2X))
16547 (clobber (match_scratch:XF 3 ""))])]
16548 "TARGET_USE_FANCY_MATH_387
16549 && flag_unsafe_math_optimizations"
16551 operands[2] = gen_reg_rtx (XFmode);
16552 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16555 (define_expand "log10<mode>2"
16556 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16557 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16558 "TARGET_USE_FANCY_MATH_387
16559 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16560 || TARGET_MIX_SSE_I387)
16561 && flag_unsafe_math_optimizations"
16563 rtx op0 = gen_reg_rtx (XFmode);
16565 rtx op2 = gen_reg_rtx (XFmode);
16566 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16568 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16569 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16573 (define_expand "log2xf2"
16574 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16575 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16576 (match_dup 2)] UNSPEC_FYL2X))
16577 (clobber (match_scratch:XF 3 ""))])]
16578 "TARGET_USE_FANCY_MATH_387
16579 && flag_unsafe_math_optimizations"
16581 operands[2] = gen_reg_rtx (XFmode);
16582 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16585 (define_expand "log2<mode>2"
16586 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16587 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16588 "TARGET_USE_FANCY_MATH_387
16589 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16590 || TARGET_MIX_SSE_I387)
16591 && flag_unsafe_math_optimizations"
16593 rtx op0 = gen_reg_rtx (XFmode);
16595 rtx op2 = gen_reg_rtx (XFmode);
16596 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16598 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16599 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16603 (define_insn "fyl2xp1xf3_i387"
16604 [(set (match_operand:XF 0 "register_operand" "=f")
16605 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16606 (match_operand:XF 2 "register_operand" "u")]
16608 (clobber (match_scratch:XF 3 "=2"))]
16609 "TARGET_USE_FANCY_MATH_387
16610 && flag_unsafe_math_optimizations"
16612 [(set_attr "type" "fpspc")
16613 (set_attr "mode" "XF")])
16615 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16616 [(set (match_operand:XF 0 "register_operand" "=f")
16617 (unspec:XF [(float_extend:XF
16618 (match_operand:X87MODEF12 1 "register_operand" "0"))
16619 (match_operand:XF 2 "register_operand" "u")]
16621 (clobber (match_scratch:XF 3 "=2"))]
16622 "TARGET_USE_FANCY_MATH_387
16623 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16624 || TARGET_MIX_SSE_I387)
16625 && flag_unsafe_math_optimizations"
16627 [(set_attr "type" "fpspc")
16628 (set_attr "mode" "XF")])
16630 (define_expand "log1pxf2"
16631 [(use (match_operand:XF 0 "register_operand" ""))
16632 (use (match_operand:XF 1 "register_operand" ""))]
16633 "TARGET_USE_FANCY_MATH_387
16634 && flag_unsafe_math_optimizations && !optimize_size"
16636 ix86_emit_i387_log1p (operands[0], operands[1]);
16640 (define_expand "log1p<mode>2"
16641 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16642 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16643 "TARGET_USE_FANCY_MATH_387
16644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16645 || TARGET_MIX_SSE_I387)
16646 && flag_unsafe_math_optimizations && !optimize_size"
16648 rtx op0 = gen_reg_rtx (XFmode);
16650 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16652 ix86_emit_i387_log1p (op0, operands[1]);
16653 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16657 (define_insn "fxtractxf3_i387"
16658 [(set (match_operand:XF 0 "register_operand" "=f")
16659 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16660 UNSPEC_XTRACT_FRACT))
16661 (set (match_operand:XF 1 "register_operand" "=u")
16662 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16663 "TARGET_USE_FANCY_MATH_387
16664 && flag_unsafe_math_optimizations"
16666 [(set_attr "type" "fpspc")
16667 (set_attr "mode" "XF")])
16669 (define_insn "fxtract_extend<mode>xf3_i387"
16670 [(set (match_operand:XF 0 "register_operand" "=f")
16671 (unspec:XF [(float_extend:XF
16672 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16673 UNSPEC_XTRACT_FRACT))
16674 (set (match_operand:XF 1 "register_operand" "=u")
16675 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16676 "TARGET_USE_FANCY_MATH_387
16677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16678 || TARGET_MIX_SSE_I387)
16679 && flag_unsafe_math_optimizations"
16681 [(set_attr "type" "fpspc")
16682 (set_attr "mode" "XF")])
16684 (define_expand "logbxf2"
16685 [(parallel [(set (match_dup 2)
16686 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16687 UNSPEC_XTRACT_FRACT))
16688 (set (match_operand:XF 0 "register_operand" "")
16689 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16690 "TARGET_USE_FANCY_MATH_387
16691 && flag_unsafe_math_optimizations"
16693 operands[2] = gen_reg_rtx (XFmode);
16696 (define_expand "logb<mode>2"
16697 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16698 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16699 "TARGET_USE_FANCY_MATH_387
16700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16701 || TARGET_MIX_SSE_I387)
16702 && flag_unsafe_math_optimizations"
16704 rtx op0 = gen_reg_rtx (XFmode);
16705 rtx op1 = gen_reg_rtx (XFmode);
16707 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16708 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16712 (define_expand "ilogbxf2"
16713 [(use (match_operand:SI 0 "register_operand" ""))
16714 (use (match_operand:XF 1 "register_operand" ""))]
16715 "TARGET_USE_FANCY_MATH_387
16716 && flag_unsafe_math_optimizations && !optimize_size"
16718 rtx op0 = gen_reg_rtx (XFmode);
16719 rtx op1 = gen_reg_rtx (XFmode);
16721 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16722 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16726 (define_expand "ilogb<mode>2"
16727 [(use (match_operand:SI 0 "register_operand" ""))
16728 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16729 "TARGET_USE_FANCY_MATH_387
16730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16731 || TARGET_MIX_SSE_I387)
16732 && flag_unsafe_math_optimizations && !optimize_size"
16734 rtx op0 = gen_reg_rtx (XFmode);
16735 rtx op1 = gen_reg_rtx (XFmode);
16737 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16738 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16742 (define_insn "*f2xm1xf2_i387"
16743 [(set (match_operand:XF 0 "register_operand" "=f")
16744 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16746 "TARGET_USE_FANCY_MATH_387
16747 && flag_unsafe_math_optimizations"
16749 [(set_attr "type" "fpspc")
16750 (set_attr "mode" "XF")])
16752 (define_insn "*fscalexf4_i387"
16753 [(set (match_operand:XF 0 "register_operand" "=f")
16754 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16755 (match_operand:XF 3 "register_operand" "1")]
16756 UNSPEC_FSCALE_FRACT))
16757 (set (match_operand:XF 1 "register_operand" "=u")
16758 (unspec:XF [(match_dup 2) (match_dup 3)]
16759 UNSPEC_FSCALE_EXP))]
16760 "TARGET_USE_FANCY_MATH_387
16761 && flag_unsafe_math_optimizations"
16763 [(set_attr "type" "fpspc")
16764 (set_attr "mode" "XF")])
16766 (define_expand "expNcorexf3"
16767 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16768 (match_operand:XF 2 "register_operand" "")))
16769 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16770 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16771 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16772 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16773 (parallel [(set (match_operand:XF 0 "register_operand" "")
16774 (unspec:XF [(match_dup 8) (match_dup 4)]
16775 UNSPEC_FSCALE_FRACT))
16777 (unspec:XF [(match_dup 8) (match_dup 4)]
16778 UNSPEC_FSCALE_EXP))])]
16779 "TARGET_USE_FANCY_MATH_387
16780 && flag_unsafe_math_optimizations && !optimize_size"
16784 for (i = 3; i < 10; i++)
16785 operands[i] = gen_reg_rtx (XFmode);
16787 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16790 (define_expand "expxf2"
16791 [(use (match_operand:XF 0 "register_operand" ""))
16792 (use (match_operand:XF 1 "register_operand" ""))]
16793 "TARGET_USE_FANCY_MATH_387
16794 && flag_unsafe_math_optimizations && !optimize_size"
16796 rtx op2 = gen_reg_rtx (XFmode);
16797 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16799 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16803 (define_expand "exp<mode>2"
16804 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16805 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16806 "TARGET_USE_FANCY_MATH_387
16807 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16808 || TARGET_MIX_SSE_I387)
16809 && flag_unsafe_math_optimizations && !optimize_size"
16811 rtx op0 = gen_reg_rtx (XFmode);
16812 rtx op1 = gen_reg_rtx (XFmode);
16814 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16815 emit_insn (gen_expxf2 (op0, op1));
16816 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16820 (define_expand "exp10xf2"
16821 [(use (match_operand:XF 0 "register_operand" ""))
16822 (use (match_operand:XF 1 "register_operand" ""))]
16823 "TARGET_USE_FANCY_MATH_387
16824 && flag_unsafe_math_optimizations && !optimize_size"
16826 rtx op2 = gen_reg_rtx (XFmode);
16827 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16829 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16833 (define_expand "exp10<mode>2"
16834 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16835 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16836 "TARGET_USE_FANCY_MATH_387
16837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16838 || TARGET_MIX_SSE_I387)
16839 && flag_unsafe_math_optimizations && !optimize_size"
16841 rtx op0 = gen_reg_rtx (XFmode);
16842 rtx op1 = gen_reg_rtx (XFmode);
16844 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16845 emit_insn (gen_exp10xf2 (op0, op1));
16846 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16850 (define_expand "exp2xf2"
16851 [(use (match_operand:XF 0 "register_operand" ""))
16852 (use (match_operand:XF 1 "register_operand" ""))]
16853 "TARGET_USE_FANCY_MATH_387
16854 && flag_unsafe_math_optimizations && !optimize_size"
16856 rtx op2 = gen_reg_rtx (XFmode);
16857 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16859 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16863 (define_expand "exp2<mode>2"
16864 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16865 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16866 "TARGET_USE_FANCY_MATH_387
16867 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16868 || TARGET_MIX_SSE_I387)
16869 && flag_unsafe_math_optimizations && !optimize_size"
16871 rtx op0 = gen_reg_rtx (XFmode);
16872 rtx op1 = gen_reg_rtx (XFmode);
16874 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16875 emit_insn (gen_exp2xf2 (op0, op1));
16876 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16880 (define_expand "expm1xf2"
16881 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16883 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16884 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16885 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16886 (parallel [(set (match_dup 7)
16887 (unspec:XF [(match_dup 6) (match_dup 4)]
16888 UNSPEC_FSCALE_FRACT))
16890 (unspec:XF [(match_dup 6) (match_dup 4)]
16891 UNSPEC_FSCALE_EXP))])
16892 (parallel [(set (match_dup 10)
16893 (unspec:XF [(match_dup 9) (match_dup 8)]
16894 UNSPEC_FSCALE_FRACT))
16895 (set (match_dup 11)
16896 (unspec:XF [(match_dup 9) (match_dup 8)]
16897 UNSPEC_FSCALE_EXP))])
16898 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16899 (set (match_operand:XF 0 "register_operand" "")
16900 (plus:XF (match_dup 12) (match_dup 7)))]
16901 "TARGET_USE_FANCY_MATH_387
16902 && flag_unsafe_math_optimizations && !optimize_size"
16906 for (i = 2; i < 13; i++)
16907 operands[i] = gen_reg_rtx (XFmode);
16909 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16910 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16913 (define_expand "expm1<mode>2"
16914 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16915 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16916 "TARGET_USE_FANCY_MATH_387
16917 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16918 || TARGET_MIX_SSE_I387)
16919 && flag_unsafe_math_optimizations && !optimize_size"
16921 rtx op0 = gen_reg_rtx (XFmode);
16922 rtx op1 = gen_reg_rtx (XFmode);
16924 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16925 emit_insn (gen_expm1xf2 (op0, op1));
16926 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16930 (define_expand "ldexpxf3"
16931 [(set (match_dup 3)
16932 (float:XF (match_operand:SI 2 "register_operand" "")))
16933 (parallel [(set (match_operand:XF 0 " register_operand" "")
16934 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16936 UNSPEC_FSCALE_FRACT))
16938 (unspec:XF [(match_dup 1) (match_dup 3)]
16939 UNSPEC_FSCALE_EXP))])]
16940 "TARGET_USE_FANCY_MATH_387
16941 && flag_unsafe_math_optimizations && !optimize_size"
16943 operands[3] = gen_reg_rtx (XFmode);
16944 operands[4] = gen_reg_rtx (XFmode);
16947 (define_expand "ldexp<mode>3"
16948 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16949 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16950 (use (match_operand:SI 2 "register_operand" ""))]
16951 "TARGET_USE_FANCY_MATH_387
16952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16953 || TARGET_MIX_SSE_I387)
16954 && flag_unsafe_math_optimizations && !optimize_size"
16956 rtx op0 = gen_reg_rtx (XFmode);
16957 rtx op1 = gen_reg_rtx (XFmode);
16959 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16960 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16961 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16966 (define_insn "frndintxf2"
16967 [(set (match_operand:XF 0 "register_operand" "=f")
16968 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16970 "TARGET_USE_FANCY_MATH_387
16971 && flag_unsafe_math_optimizations"
16973 [(set_attr "type" "fpspc")
16974 (set_attr "mode" "XF")])
16976 (define_expand "rintdf2"
16977 [(use (match_operand:DF 0 "register_operand" ""))
16978 (use (match_operand:DF 1 "register_operand" ""))]
16979 "(TARGET_USE_FANCY_MATH_387
16980 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16981 && flag_unsafe_math_optimizations)
16982 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16983 && !flag_trapping_math
16984 && !optimize_size)"
16986 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16987 && !flag_trapping_math
16989 ix86_expand_rint (operand0, operand1);
16992 rtx op0 = gen_reg_rtx (XFmode);
16993 rtx op1 = gen_reg_rtx (XFmode);
16995 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16996 emit_insn (gen_frndintxf2 (op0, op1));
16998 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17003 (define_expand "rintsf2"
17004 [(use (match_operand:SF 0 "register_operand" ""))
17005 (use (match_operand:SF 1 "register_operand" ""))]
17006 "(TARGET_USE_FANCY_MATH_387
17007 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17008 && flag_unsafe_math_optimizations)
17009 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17010 && !flag_trapping_math
17011 && !optimize_size)"
17013 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17014 && !flag_trapping_math
17016 ix86_expand_rint (operand0, operand1);
17019 rtx op0 = gen_reg_rtx (XFmode);
17020 rtx op1 = gen_reg_rtx (XFmode);
17022 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17023 emit_insn (gen_frndintxf2 (op0, op1));
17025 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17030 (define_expand "rintxf2"
17031 [(use (match_operand:XF 0 "register_operand" ""))
17032 (use (match_operand:XF 1 "register_operand" ""))]
17033 "TARGET_USE_FANCY_MATH_387
17034 && flag_unsafe_math_optimizations && !optimize_size"
17036 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17040 (define_expand "roundsf2"
17041 [(match_operand:SF 0 "register_operand" "")
17042 (match_operand:SF 1 "nonimmediate_operand" "")]
17043 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17044 && !flag_trapping_math && !flag_rounding_math
17047 ix86_expand_round (operand0, operand1);
17051 (define_expand "rounddf2"
17052 [(match_operand:DF 0 "register_operand" "")
17053 (match_operand:DF 1 "nonimmediate_operand" "")]
17054 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17055 && !flag_trapping_math && !flag_rounding_math
17059 ix86_expand_round (operand0, operand1);
17061 ix86_expand_rounddf_32 (operand0, operand1);
17065 (define_insn_and_split "*fistdi2_1"
17066 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17067 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17069 "TARGET_USE_FANCY_MATH_387
17070 && !(reload_completed || reload_in_progress)"
17075 if (memory_operand (operands[0], VOIDmode))
17076 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17079 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17080 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17085 [(set_attr "type" "fpspc")
17086 (set_attr "mode" "DI")])
17088 (define_insn "fistdi2"
17089 [(set (match_operand:DI 0 "memory_operand" "=m")
17090 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17092 (clobber (match_scratch:XF 2 "=&1f"))]
17093 "TARGET_USE_FANCY_MATH_387"
17094 "* return output_fix_trunc (insn, operands, 0);"
17095 [(set_attr "type" "fpspc")
17096 (set_attr "mode" "DI")])
17098 (define_insn "fistdi2_with_temp"
17099 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17100 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17102 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17103 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17104 "TARGET_USE_FANCY_MATH_387"
17106 [(set_attr "type" "fpspc")
17107 (set_attr "mode" "DI")])
17110 [(set (match_operand:DI 0 "register_operand" "")
17111 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17113 (clobber (match_operand:DI 2 "memory_operand" ""))
17114 (clobber (match_scratch 3 ""))]
17116 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17117 (clobber (match_dup 3))])
17118 (set (match_dup 0) (match_dup 2))]
17122 [(set (match_operand:DI 0 "memory_operand" "")
17123 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17125 (clobber (match_operand:DI 2 "memory_operand" ""))
17126 (clobber (match_scratch 3 ""))]
17128 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17129 (clobber (match_dup 3))])]
17132 (define_insn_and_split "*fist<mode>2_1"
17133 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17134 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17136 "TARGET_USE_FANCY_MATH_387
17137 && !(reload_completed || reload_in_progress)"
17142 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17143 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17147 [(set_attr "type" "fpspc")
17148 (set_attr "mode" "<MODE>")])
17150 (define_insn "fist<mode>2"
17151 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17152 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17154 "TARGET_USE_FANCY_MATH_387"
17155 "* return output_fix_trunc (insn, operands, 0);"
17156 [(set_attr "type" "fpspc")
17157 (set_attr "mode" "<MODE>")])
17159 (define_insn "fist<mode>2_with_temp"
17160 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17161 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17163 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17164 "TARGET_USE_FANCY_MATH_387"
17166 [(set_attr "type" "fpspc")
17167 (set_attr "mode" "<MODE>")])
17170 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17171 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17173 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17175 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17177 (set (match_dup 0) (match_dup 2))]
17181 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17182 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17184 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17186 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17190 (define_expand "lrintxf<mode>2"
17191 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17192 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17194 "TARGET_USE_FANCY_MATH_387"
17197 (define_expand "lrint<mode>di2"
17198 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17199 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17200 UNSPEC_FIX_NOTRUNC))]
17201 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17204 (define_expand "lrint<mode>si2"
17205 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17206 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17207 UNSPEC_FIX_NOTRUNC))]
17208 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17211 (define_expand "lround<mode>di2"
17212 [(match_operand:DI 0 "nonimmediate_operand" "")
17213 (match_operand:SSEMODEF 1 "register_operand" "")]
17214 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17215 && !flag_trapping_math && !flag_rounding_math
17218 ix86_expand_lround (operand0, operand1);
17222 (define_expand "lround<mode>si2"
17223 [(match_operand:SI 0 "nonimmediate_operand" "")
17224 (match_operand:SSEMODEF 1 "register_operand" "")]
17225 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17226 && !flag_trapping_math && !flag_rounding_math
17229 ix86_expand_lround (operand0, operand1);
17233 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17234 (define_insn_and_split "frndintxf2_floor"
17235 [(set (match_operand:XF 0 "register_operand" "=f")
17236 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17237 UNSPEC_FRNDINT_FLOOR))
17238 (clobber (reg:CC FLAGS_REG))]
17239 "TARGET_USE_FANCY_MATH_387
17240 && flag_unsafe_math_optimizations
17241 && !(reload_completed || reload_in_progress)"
17246 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17248 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17249 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17251 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17252 operands[2], operands[3]));
17255 [(set_attr "type" "frndint")
17256 (set_attr "i387_cw" "floor")
17257 (set_attr "mode" "XF")])
17259 (define_insn "frndintxf2_floor_i387"
17260 [(set (match_operand:XF 0 "register_operand" "=f")
17261 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17262 UNSPEC_FRNDINT_FLOOR))
17263 (use (match_operand:HI 2 "memory_operand" "m"))
17264 (use (match_operand:HI 3 "memory_operand" "m"))]
17265 "TARGET_USE_FANCY_MATH_387
17266 && flag_unsafe_math_optimizations"
17267 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17268 [(set_attr "type" "frndint")
17269 (set_attr "i387_cw" "floor")
17270 (set_attr "mode" "XF")])
17272 (define_expand "floorxf2"
17273 [(use (match_operand:XF 0 "register_operand" ""))
17274 (use (match_operand:XF 1 "register_operand" ""))]
17275 "TARGET_USE_FANCY_MATH_387
17276 && flag_unsafe_math_optimizations && !optimize_size"
17278 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17282 (define_expand "floordf2"
17283 [(use (match_operand:DF 0 "register_operand" ""))
17284 (use (match_operand:DF 1 "register_operand" ""))]
17285 "((TARGET_USE_FANCY_MATH_387
17286 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17287 && flag_unsafe_math_optimizations)
17288 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17289 && !flag_trapping_math))
17292 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17293 && !flag_trapping_math)
17296 ix86_expand_floorceil (operand0, operand1, true);
17298 ix86_expand_floorceildf_32 (operand0, operand1, true);
17302 rtx op0 = gen_reg_rtx (XFmode);
17303 rtx op1 = gen_reg_rtx (XFmode);
17305 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17306 emit_insn (gen_frndintxf2_floor (op0, op1));
17308 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17313 (define_expand "floorsf2"
17314 [(use (match_operand:SF 0 "register_operand" ""))
17315 (use (match_operand:SF 1 "register_operand" ""))]
17316 "((TARGET_USE_FANCY_MATH_387
17317 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17318 && flag_unsafe_math_optimizations)
17319 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17320 && !flag_trapping_math))
17323 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17324 && !flag_trapping_math)
17325 ix86_expand_floorceil (operand0, operand1, true);
17328 rtx op0 = gen_reg_rtx (XFmode);
17329 rtx op1 = gen_reg_rtx (XFmode);
17331 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17332 emit_insn (gen_frndintxf2_floor (op0, op1));
17334 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17339 (define_insn_and_split "*fist<mode>2_floor_1"
17340 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17341 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17342 UNSPEC_FIST_FLOOR))
17343 (clobber (reg:CC FLAGS_REG))]
17344 "TARGET_USE_FANCY_MATH_387
17345 && flag_unsafe_math_optimizations
17346 && !(reload_completed || reload_in_progress)"
17351 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17353 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17354 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17355 if (memory_operand (operands[0], VOIDmode))
17356 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17357 operands[2], operands[3]));
17360 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17361 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17362 operands[2], operands[3],
17367 [(set_attr "type" "fistp")
17368 (set_attr "i387_cw" "floor")
17369 (set_attr "mode" "<MODE>")])
17371 (define_insn "fistdi2_floor"
17372 [(set (match_operand:DI 0 "memory_operand" "=m")
17373 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17374 UNSPEC_FIST_FLOOR))
17375 (use (match_operand:HI 2 "memory_operand" "m"))
17376 (use (match_operand:HI 3 "memory_operand" "m"))
17377 (clobber (match_scratch:XF 4 "=&1f"))]
17378 "TARGET_USE_FANCY_MATH_387
17379 && flag_unsafe_math_optimizations"
17380 "* return output_fix_trunc (insn, operands, 0);"
17381 [(set_attr "type" "fistp")
17382 (set_attr "i387_cw" "floor")
17383 (set_attr "mode" "DI")])
17385 (define_insn "fistdi2_floor_with_temp"
17386 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17387 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17388 UNSPEC_FIST_FLOOR))
17389 (use (match_operand:HI 2 "memory_operand" "m,m"))
17390 (use (match_operand:HI 3 "memory_operand" "m,m"))
17391 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17392 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17393 "TARGET_USE_FANCY_MATH_387
17394 && flag_unsafe_math_optimizations"
17396 [(set_attr "type" "fistp")
17397 (set_attr "i387_cw" "floor")
17398 (set_attr "mode" "DI")])
17401 [(set (match_operand:DI 0 "register_operand" "")
17402 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17403 UNSPEC_FIST_FLOOR))
17404 (use (match_operand:HI 2 "memory_operand" ""))
17405 (use (match_operand:HI 3 "memory_operand" ""))
17406 (clobber (match_operand:DI 4 "memory_operand" ""))
17407 (clobber (match_scratch 5 ""))]
17409 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17410 (use (match_dup 2))
17411 (use (match_dup 3))
17412 (clobber (match_dup 5))])
17413 (set (match_dup 0) (match_dup 4))]
17417 [(set (match_operand:DI 0 "memory_operand" "")
17418 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17419 UNSPEC_FIST_FLOOR))
17420 (use (match_operand:HI 2 "memory_operand" ""))
17421 (use (match_operand:HI 3 "memory_operand" ""))
17422 (clobber (match_operand:DI 4 "memory_operand" ""))
17423 (clobber (match_scratch 5 ""))]
17425 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17426 (use (match_dup 2))
17427 (use (match_dup 3))
17428 (clobber (match_dup 5))])]
17431 (define_insn "fist<mode>2_floor"
17432 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17433 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17434 UNSPEC_FIST_FLOOR))
17435 (use (match_operand:HI 2 "memory_operand" "m"))
17436 (use (match_operand:HI 3 "memory_operand" "m"))]
17437 "TARGET_USE_FANCY_MATH_387
17438 && flag_unsafe_math_optimizations"
17439 "* return output_fix_trunc (insn, operands, 0);"
17440 [(set_attr "type" "fistp")
17441 (set_attr "i387_cw" "floor")
17442 (set_attr "mode" "<MODE>")])
17444 (define_insn "fist<mode>2_floor_with_temp"
17445 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17446 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17447 UNSPEC_FIST_FLOOR))
17448 (use (match_operand:HI 2 "memory_operand" "m,m"))
17449 (use (match_operand:HI 3 "memory_operand" "m,m"))
17450 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17451 "TARGET_USE_FANCY_MATH_387
17452 && flag_unsafe_math_optimizations"
17454 [(set_attr "type" "fistp")
17455 (set_attr "i387_cw" "floor")
17456 (set_attr "mode" "<MODE>")])
17459 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17460 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17461 UNSPEC_FIST_FLOOR))
17462 (use (match_operand:HI 2 "memory_operand" ""))
17463 (use (match_operand:HI 3 "memory_operand" ""))
17464 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17466 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17467 UNSPEC_FIST_FLOOR))
17468 (use (match_dup 2))
17469 (use (match_dup 3))])
17470 (set (match_dup 0) (match_dup 4))]
17474 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17475 (unspec:X87MODEI12 [(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:X87MODEI12 4 "memory_operand" ""))]
17481 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17482 UNSPEC_FIST_FLOOR))
17483 (use (match_dup 2))
17484 (use (match_dup 3))])]
17487 (define_expand "lfloorxf<mode>2"
17488 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17489 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17490 UNSPEC_FIST_FLOOR))
17491 (clobber (reg:CC FLAGS_REG))])]
17492 "TARGET_USE_FANCY_MATH_387
17493 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17494 && flag_unsafe_math_optimizations"
17497 (define_expand "lfloor<mode>di2"
17498 [(match_operand:DI 0 "nonimmediate_operand" "")
17499 (match_operand:SSEMODEF 1 "register_operand" "")]
17500 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17501 && !flag_trapping_math
17504 ix86_expand_lfloorceil (operand0, operand1, true);
17508 (define_expand "lfloor<mode>si2"
17509 [(match_operand:SI 0 "nonimmediate_operand" "")
17510 (match_operand:SSEMODEF 1 "register_operand" "")]
17511 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17512 && !flag_trapping_math
17513 && (!optimize_size || !TARGET_64BIT)"
17515 ix86_expand_lfloorceil (operand0, operand1, true);
17519 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17520 (define_insn_and_split "frndintxf2_ceil"
17521 [(set (match_operand:XF 0 "register_operand" "=f")
17522 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17523 UNSPEC_FRNDINT_CEIL))
17524 (clobber (reg:CC FLAGS_REG))]
17525 "TARGET_USE_FANCY_MATH_387
17526 && flag_unsafe_math_optimizations
17527 && !(reload_completed || reload_in_progress)"
17532 ix86_optimize_mode_switching[I387_CEIL] = 1;
17534 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17535 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17537 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17538 operands[2], operands[3]));
17541 [(set_attr "type" "frndint")
17542 (set_attr "i387_cw" "ceil")
17543 (set_attr "mode" "XF")])
17545 (define_insn "frndintxf2_ceil_i387"
17546 [(set (match_operand:XF 0 "register_operand" "=f")
17547 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17548 UNSPEC_FRNDINT_CEIL))
17549 (use (match_operand:HI 2 "memory_operand" "m"))
17550 (use (match_operand:HI 3 "memory_operand" "m"))]
17551 "TARGET_USE_FANCY_MATH_387
17552 && flag_unsafe_math_optimizations"
17553 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17554 [(set_attr "type" "frndint")
17555 (set_attr "i387_cw" "ceil")
17556 (set_attr "mode" "XF")])
17558 (define_expand "ceilxf2"
17559 [(use (match_operand:XF 0 "register_operand" ""))
17560 (use (match_operand:XF 1 "register_operand" ""))]
17561 "TARGET_USE_FANCY_MATH_387
17562 && flag_unsafe_math_optimizations && !optimize_size"
17564 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17568 (define_expand "ceildf2"
17569 [(use (match_operand:DF 0 "register_operand" ""))
17570 (use (match_operand:DF 1 "register_operand" ""))]
17571 "((TARGET_USE_FANCY_MATH_387
17572 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17573 && flag_unsafe_math_optimizations)
17574 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17575 && !flag_trapping_math))
17578 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17579 && !flag_trapping_math)
17582 ix86_expand_floorceil (operand0, operand1, false);
17584 ix86_expand_floorceildf_32 (operand0, operand1, false);
17588 rtx op0 = gen_reg_rtx (XFmode);
17589 rtx op1 = gen_reg_rtx (XFmode);
17591 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17592 emit_insn (gen_frndintxf2_ceil (op0, op1));
17594 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17599 (define_expand "ceilsf2"
17600 [(use (match_operand:SF 0 "register_operand" ""))
17601 (use (match_operand:SF 1 "register_operand" ""))]
17602 "((TARGET_USE_FANCY_MATH_387
17603 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17604 && flag_unsafe_math_optimizations)
17605 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17606 && !flag_trapping_math))
17609 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17610 && !flag_trapping_math)
17611 ix86_expand_floorceil (operand0, operand1, false);
17614 rtx op0 = gen_reg_rtx (XFmode);
17615 rtx op1 = gen_reg_rtx (XFmode);
17617 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17618 emit_insn (gen_frndintxf2_ceil (op0, op1));
17620 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17625 (define_insn_and_split "*fist<mode>2_ceil_1"
17626 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17627 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17629 (clobber (reg:CC FLAGS_REG))]
17630 "TARGET_USE_FANCY_MATH_387
17631 && flag_unsafe_math_optimizations
17632 && !(reload_completed || reload_in_progress)"
17637 ix86_optimize_mode_switching[I387_CEIL] = 1;
17639 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17640 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17641 if (memory_operand (operands[0], VOIDmode))
17642 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17643 operands[2], operands[3]));
17646 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17647 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17648 operands[2], operands[3],
17653 [(set_attr "type" "fistp")
17654 (set_attr "i387_cw" "ceil")
17655 (set_attr "mode" "<MODE>")])
17657 (define_insn "fistdi2_ceil"
17658 [(set (match_operand:DI 0 "memory_operand" "=m")
17659 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17661 (use (match_operand:HI 2 "memory_operand" "m"))
17662 (use (match_operand:HI 3 "memory_operand" "m"))
17663 (clobber (match_scratch:XF 4 "=&1f"))]
17664 "TARGET_USE_FANCY_MATH_387
17665 && flag_unsafe_math_optimizations"
17666 "* return output_fix_trunc (insn, operands, 0);"
17667 [(set_attr "type" "fistp")
17668 (set_attr "i387_cw" "ceil")
17669 (set_attr "mode" "DI")])
17671 (define_insn "fistdi2_ceil_with_temp"
17672 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17673 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17675 (use (match_operand:HI 2 "memory_operand" "m,m"))
17676 (use (match_operand:HI 3 "memory_operand" "m,m"))
17677 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17678 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17679 "TARGET_USE_FANCY_MATH_387
17680 && flag_unsafe_math_optimizations"
17682 [(set_attr "type" "fistp")
17683 (set_attr "i387_cw" "ceil")
17684 (set_attr "mode" "DI")])
17687 [(set (match_operand:DI 0 "register_operand" "")
17688 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17690 (use (match_operand:HI 2 "memory_operand" ""))
17691 (use (match_operand:HI 3 "memory_operand" ""))
17692 (clobber (match_operand:DI 4 "memory_operand" ""))
17693 (clobber (match_scratch 5 ""))]
17695 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17696 (use (match_dup 2))
17697 (use (match_dup 3))
17698 (clobber (match_dup 5))])
17699 (set (match_dup 0) (match_dup 4))]
17703 [(set (match_operand:DI 0 "memory_operand" "")
17704 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17706 (use (match_operand:HI 2 "memory_operand" ""))
17707 (use (match_operand:HI 3 "memory_operand" ""))
17708 (clobber (match_operand:DI 4 "memory_operand" ""))
17709 (clobber (match_scratch 5 ""))]
17711 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17712 (use (match_dup 2))
17713 (use (match_dup 3))
17714 (clobber (match_dup 5))])]
17717 (define_insn "fist<mode>2_ceil"
17718 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17719 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17721 (use (match_operand:HI 2 "memory_operand" "m"))
17722 (use (match_operand:HI 3 "memory_operand" "m"))]
17723 "TARGET_USE_FANCY_MATH_387
17724 && flag_unsafe_math_optimizations"
17725 "* return output_fix_trunc (insn, operands, 0);"
17726 [(set_attr "type" "fistp")
17727 (set_attr "i387_cw" "ceil")
17728 (set_attr "mode" "<MODE>")])
17730 (define_insn "fist<mode>2_ceil_with_temp"
17731 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17732 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17734 (use (match_operand:HI 2 "memory_operand" "m,m"))
17735 (use (match_operand:HI 3 "memory_operand" "m,m"))
17736 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17737 "TARGET_USE_FANCY_MATH_387
17738 && flag_unsafe_math_optimizations"
17740 [(set_attr "type" "fistp")
17741 (set_attr "i387_cw" "ceil")
17742 (set_attr "mode" "<MODE>")])
17745 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17746 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17748 (use (match_operand:HI 2 "memory_operand" ""))
17749 (use (match_operand:HI 3 "memory_operand" ""))
17750 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17752 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17754 (use (match_dup 2))
17755 (use (match_dup 3))])
17756 (set (match_dup 0) (match_dup 4))]
17760 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17761 (unspec:X87MODEI12 [(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:X87MODEI12 4 "memory_operand" ""))]
17767 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17769 (use (match_dup 2))
17770 (use (match_dup 3))])]
17773 (define_expand "lceilxf<mode>2"
17774 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17775 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17777 (clobber (reg:CC FLAGS_REG))])]
17778 "TARGET_USE_FANCY_MATH_387
17779 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17780 && flag_unsafe_math_optimizations"
17783 (define_expand "lceil<mode>di2"
17784 [(match_operand:DI 0 "nonimmediate_operand" "")
17785 (match_operand:SSEMODEF 1 "register_operand" "")]
17786 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17787 && !flag_trapping_math"
17789 ix86_expand_lfloorceil (operand0, operand1, false);
17793 (define_expand "lceil<mode>si2"
17794 [(match_operand:SI 0 "nonimmediate_operand" "")
17795 (match_operand:SSEMODEF 1 "register_operand" "")]
17796 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17797 && !flag_trapping_math"
17799 ix86_expand_lfloorceil (operand0, operand1, false);
17803 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17804 (define_insn_and_split "frndintxf2_trunc"
17805 [(set (match_operand:XF 0 "register_operand" "=f")
17806 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17807 UNSPEC_FRNDINT_TRUNC))
17808 (clobber (reg:CC FLAGS_REG))]
17809 "TARGET_USE_FANCY_MATH_387
17810 && flag_unsafe_math_optimizations
17811 && !(reload_completed || reload_in_progress)"
17816 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17818 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17819 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17821 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17822 operands[2], operands[3]));
17825 [(set_attr "type" "frndint")
17826 (set_attr "i387_cw" "trunc")
17827 (set_attr "mode" "XF")])
17829 (define_insn "frndintxf2_trunc_i387"
17830 [(set (match_operand:XF 0 "register_operand" "=f")
17831 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17832 UNSPEC_FRNDINT_TRUNC))
17833 (use (match_operand:HI 2 "memory_operand" "m"))
17834 (use (match_operand:HI 3 "memory_operand" "m"))]
17835 "TARGET_USE_FANCY_MATH_387
17836 && flag_unsafe_math_optimizations"
17837 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17838 [(set_attr "type" "frndint")
17839 (set_attr "i387_cw" "trunc")
17840 (set_attr "mode" "XF")])
17842 (define_expand "btruncxf2"
17843 [(use (match_operand:XF 0 "register_operand" ""))
17844 (use (match_operand:XF 1 "register_operand" ""))]
17845 "TARGET_USE_FANCY_MATH_387
17846 && flag_unsafe_math_optimizations && !optimize_size"
17848 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17852 (define_expand "btruncdf2"
17853 [(use (match_operand:DF 0 "register_operand" ""))
17854 (use (match_operand:DF 1 "register_operand" ""))]
17855 "((TARGET_USE_FANCY_MATH_387
17856 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17857 && flag_unsafe_math_optimizations)
17858 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17859 && !flag_trapping_math))
17862 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17863 && !flag_trapping_math)
17866 ix86_expand_trunc (operand0, operand1);
17868 ix86_expand_truncdf_32 (operand0, operand1);
17872 rtx op0 = gen_reg_rtx (XFmode);
17873 rtx op1 = gen_reg_rtx (XFmode);
17875 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17876 emit_insn (gen_frndintxf2_trunc (op0, op1));
17878 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17883 (define_expand "btruncsf2"
17884 [(use (match_operand:SF 0 "register_operand" ""))
17885 (use (match_operand:SF 1 "register_operand" ""))]
17886 "((TARGET_USE_FANCY_MATH_387
17887 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17888 && flag_unsafe_math_optimizations)
17889 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17890 && !flag_trapping_math))
17893 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17894 && !flag_trapping_math)
17895 ix86_expand_trunc (operand0, operand1);
17898 rtx op0 = gen_reg_rtx (XFmode);
17899 rtx op1 = gen_reg_rtx (XFmode);
17901 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17902 emit_insn (gen_frndintxf2_trunc (op0, op1));
17904 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17909 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17910 (define_insn_and_split "frndintxf2_mask_pm"
17911 [(set (match_operand:XF 0 "register_operand" "=f")
17912 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17913 UNSPEC_FRNDINT_MASK_PM))
17914 (clobber (reg:CC FLAGS_REG))]
17915 "TARGET_USE_FANCY_MATH_387
17916 && flag_unsafe_math_optimizations
17917 && !(reload_completed || reload_in_progress)"
17922 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17924 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17925 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17927 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17928 operands[2], operands[3]));
17931 [(set_attr "type" "frndint")
17932 (set_attr "i387_cw" "mask_pm")
17933 (set_attr "mode" "XF")])
17935 (define_insn "frndintxf2_mask_pm_i387"
17936 [(set (match_operand:XF 0 "register_operand" "=f")
17937 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17938 UNSPEC_FRNDINT_MASK_PM))
17939 (use (match_operand:HI 2 "memory_operand" "m"))
17940 (use (match_operand:HI 3 "memory_operand" "m"))]
17941 "TARGET_USE_FANCY_MATH_387
17942 && flag_unsafe_math_optimizations"
17943 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17944 [(set_attr "type" "frndint")
17945 (set_attr "i387_cw" "mask_pm")
17946 (set_attr "mode" "XF")])
17948 (define_expand "nearbyintxf2"
17949 [(use (match_operand:XF 0 "register_operand" ""))
17950 (use (match_operand:XF 1 "register_operand" ""))]
17951 "TARGET_USE_FANCY_MATH_387
17952 && flag_unsafe_math_optimizations"
17954 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17959 (define_expand "nearbyintdf2"
17960 [(use (match_operand:DF 0 "register_operand" ""))
17961 (use (match_operand:DF 1 "register_operand" ""))]
17962 "TARGET_USE_FANCY_MATH_387
17963 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17964 && flag_unsafe_math_optimizations"
17966 rtx op0 = gen_reg_rtx (XFmode);
17967 rtx op1 = gen_reg_rtx (XFmode);
17969 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17970 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17972 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17976 (define_expand "nearbyintsf2"
17977 [(use (match_operand:SF 0 "register_operand" ""))
17978 (use (match_operand:SF 1 "register_operand" ""))]
17979 "TARGET_USE_FANCY_MATH_387
17980 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17981 && flag_unsafe_math_optimizations"
17983 rtx op0 = gen_reg_rtx (XFmode);
17984 rtx op1 = gen_reg_rtx (XFmode);
17986 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17987 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17989 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17993 (define_insn "fxam<mode>2_i387"
17994 [(set (match_operand:HI 0 "register_operand" "=a")
17996 [(match_operand:X87MODEF 1 "register_operand" "f")]
17998 "TARGET_USE_FANCY_MATH_387"
17999 "fxam\n\tfnstsw\t%0"
18000 [(set_attr "type" "multi")
18001 (set_attr "unit" "i387")
18002 (set_attr "mode" "<MODE>")])
18004 (define_expand "isinf<mode>2"
18005 [(use (match_operand:SI 0 "register_operand" ""))
18006 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18007 "TARGET_USE_FANCY_MATH_387
18008 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18009 || TARGET_MIX_SSE_I387)"
18011 rtx mask = GEN_INT (0x45);
18012 rtx val = GEN_INT (0x05);
18016 rtx scratch = gen_reg_rtx (HImode);
18017 rtx res = gen_reg_rtx (QImode);
18019 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18020 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18021 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18022 cond = gen_rtx_fmt_ee (EQ, QImode,
18023 gen_rtx_REG (CCmode, FLAGS_REG),
18025 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18026 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18031 ;; Block operation instructions
18033 (define_expand "movmemsi"
18034 [(use (match_operand:BLK 0 "memory_operand" ""))
18035 (use (match_operand:BLK 1 "memory_operand" ""))
18036 (use (match_operand:SI 2 "nonmemory_operand" ""))
18037 (use (match_operand:SI 3 "const_int_operand" ""))
18038 (use (match_operand:SI 4 "const_int_operand" ""))
18039 (use (match_operand:SI 5 "const_int_operand" ""))]
18042 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18043 operands[4], operands[5]))
18049 (define_expand "movmemdi"
18050 [(use (match_operand:BLK 0 "memory_operand" ""))
18051 (use (match_operand:BLK 1 "memory_operand" ""))
18052 (use (match_operand:DI 2 "nonmemory_operand" ""))
18053 (use (match_operand:DI 3 "const_int_operand" ""))
18054 (use (match_operand:SI 4 "const_int_operand" ""))
18055 (use (match_operand:SI 5 "const_int_operand" ""))]
18058 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18059 operands[4], operands[5]))
18065 ;; Most CPUs don't like single string operations
18066 ;; Handle this case here to simplify previous expander.
18068 (define_expand "strmov"
18069 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18070 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18071 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18072 (clobber (reg:CC FLAGS_REG))])
18073 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18074 (clobber (reg:CC FLAGS_REG))])]
18077 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18079 /* If .md ever supports :P for Pmode, these can be directly
18080 in the pattern above. */
18081 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18082 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18084 if (TARGET_SINGLE_STRINGOP || optimize_size)
18086 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18087 operands[2], operands[3],
18088 operands[5], operands[6]));
18092 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18095 (define_expand "strmov_singleop"
18096 [(parallel [(set (match_operand 1 "memory_operand" "")
18097 (match_operand 3 "memory_operand" ""))
18098 (set (match_operand 0 "register_operand" "")
18099 (match_operand 4 "" ""))
18100 (set (match_operand 2 "register_operand" "")
18101 (match_operand 5 "" ""))])]
18102 "TARGET_SINGLE_STRINGOP || optimize_size"
18105 (define_insn "*strmovdi_rex_1"
18106 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18107 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18108 (set (match_operand:DI 0 "register_operand" "=D")
18109 (plus:DI (match_dup 2)
18111 (set (match_operand:DI 1 "register_operand" "=S")
18112 (plus:DI (match_dup 3)
18114 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18116 [(set_attr "type" "str")
18117 (set_attr "mode" "DI")
18118 (set_attr "memory" "both")])
18120 (define_insn "*strmovsi_1"
18121 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18122 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18123 (set (match_operand:SI 0 "register_operand" "=D")
18124 (plus:SI (match_dup 2)
18126 (set (match_operand:SI 1 "register_operand" "=S")
18127 (plus:SI (match_dup 3)
18129 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18131 [(set_attr "type" "str")
18132 (set_attr "mode" "SI")
18133 (set_attr "memory" "both")])
18135 (define_insn "*strmovsi_rex_1"
18136 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18137 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18138 (set (match_operand:DI 0 "register_operand" "=D")
18139 (plus:DI (match_dup 2)
18141 (set (match_operand:DI 1 "register_operand" "=S")
18142 (plus:DI (match_dup 3)
18144 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18146 [(set_attr "type" "str")
18147 (set_attr "mode" "SI")
18148 (set_attr "memory" "both")])
18150 (define_insn "*strmovhi_1"
18151 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18152 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18153 (set (match_operand:SI 0 "register_operand" "=D")
18154 (plus:SI (match_dup 2)
18156 (set (match_operand:SI 1 "register_operand" "=S")
18157 (plus:SI (match_dup 3)
18159 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18161 [(set_attr "type" "str")
18162 (set_attr "memory" "both")
18163 (set_attr "mode" "HI")])
18165 (define_insn "*strmovhi_rex_1"
18166 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18167 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18168 (set (match_operand:DI 0 "register_operand" "=D")
18169 (plus:DI (match_dup 2)
18171 (set (match_operand:DI 1 "register_operand" "=S")
18172 (plus:DI (match_dup 3)
18174 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18176 [(set_attr "type" "str")
18177 (set_attr "memory" "both")
18178 (set_attr "mode" "HI")])
18180 (define_insn "*strmovqi_1"
18181 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18182 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18183 (set (match_operand:SI 0 "register_operand" "=D")
18184 (plus:SI (match_dup 2)
18186 (set (match_operand:SI 1 "register_operand" "=S")
18187 (plus:SI (match_dup 3)
18189 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18191 [(set_attr "type" "str")
18192 (set_attr "memory" "both")
18193 (set_attr "mode" "QI")])
18195 (define_insn "*strmovqi_rex_1"
18196 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18197 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18198 (set (match_operand:DI 0 "register_operand" "=D")
18199 (plus:DI (match_dup 2)
18201 (set (match_operand:DI 1 "register_operand" "=S")
18202 (plus:DI (match_dup 3)
18204 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18206 [(set_attr "type" "str")
18207 (set_attr "memory" "both")
18208 (set_attr "mode" "QI")])
18210 (define_expand "rep_mov"
18211 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18212 (set (match_operand 0 "register_operand" "")
18213 (match_operand 5 "" ""))
18214 (set (match_operand 2 "register_operand" "")
18215 (match_operand 6 "" ""))
18216 (set (match_operand 1 "memory_operand" "")
18217 (match_operand 3 "memory_operand" ""))
18218 (use (match_dup 4))])]
18222 (define_insn "*rep_movdi_rex64"
18223 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18224 (set (match_operand:DI 0 "register_operand" "=D")
18225 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18227 (match_operand:DI 3 "register_operand" "0")))
18228 (set (match_operand:DI 1 "register_operand" "=S")
18229 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18230 (match_operand:DI 4 "register_operand" "1")))
18231 (set (mem:BLK (match_dup 3))
18232 (mem:BLK (match_dup 4)))
18233 (use (match_dup 5))]
18235 "{rep\;movsq|rep movsq}"
18236 [(set_attr "type" "str")
18237 (set_attr "prefix_rep" "1")
18238 (set_attr "memory" "both")
18239 (set_attr "mode" "DI")])
18241 (define_insn "*rep_movsi"
18242 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18243 (set (match_operand:SI 0 "register_operand" "=D")
18244 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18246 (match_operand:SI 3 "register_operand" "0")))
18247 (set (match_operand:SI 1 "register_operand" "=S")
18248 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18249 (match_operand:SI 4 "register_operand" "1")))
18250 (set (mem:BLK (match_dup 3))
18251 (mem:BLK (match_dup 4)))
18252 (use (match_dup 5))]
18254 "{rep\;movsl|rep movsd}"
18255 [(set_attr "type" "str")
18256 (set_attr "prefix_rep" "1")
18257 (set_attr "memory" "both")
18258 (set_attr "mode" "SI")])
18260 (define_insn "*rep_movsi_rex64"
18261 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18262 (set (match_operand:DI 0 "register_operand" "=D")
18263 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18265 (match_operand:DI 3 "register_operand" "0")))
18266 (set (match_operand:DI 1 "register_operand" "=S")
18267 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18268 (match_operand:DI 4 "register_operand" "1")))
18269 (set (mem:BLK (match_dup 3))
18270 (mem:BLK (match_dup 4)))
18271 (use (match_dup 5))]
18273 "{rep\;movsl|rep movsd}"
18274 [(set_attr "type" "str")
18275 (set_attr "prefix_rep" "1")
18276 (set_attr "memory" "both")
18277 (set_attr "mode" "SI")])
18279 (define_insn "*rep_movqi"
18280 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18281 (set (match_operand:SI 0 "register_operand" "=D")
18282 (plus:SI (match_operand:SI 3 "register_operand" "0")
18283 (match_operand:SI 5 "register_operand" "2")))
18284 (set (match_operand:SI 1 "register_operand" "=S")
18285 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18286 (set (mem:BLK (match_dup 3))
18287 (mem:BLK (match_dup 4)))
18288 (use (match_dup 5))]
18290 "{rep\;movsb|rep movsb}"
18291 [(set_attr "type" "str")
18292 (set_attr "prefix_rep" "1")
18293 (set_attr "memory" "both")
18294 (set_attr "mode" "SI")])
18296 (define_insn "*rep_movqi_rex64"
18297 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18298 (set (match_operand:DI 0 "register_operand" "=D")
18299 (plus:DI (match_operand:DI 3 "register_operand" "0")
18300 (match_operand:DI 5 "register_operand" "2")))
18301 (set (match_operand:DI 1 "register_operand" "=S")
18302 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18303 (set (mem:BLK (match_dup 3))
18304 (mem:BLK (match_dup 4)))
18305 (use (match_dup 5))]
18307 "{rep\;movsb|rep movsb}"
18308 [(set_attr "type" "str")
18309 (set_attr "prefix_rep" "1")
18310 (set_attr "memory" "both")
18311 (set_attr "mode" "SI")])
18313 (define_expand "setmemsi"
18314 [(use (match_operand:BLK 0 "memory_operand" ""))
18315 (use (match_operand:SI 1 "nonmemory_operand" ""))
18316 (use (match_operand 2 "const_int_operand" ""))
18317 (use (match_operand 3 "const_int_operand" ""))
18318 (use (match_operand:SI 4 "const_int_operand" ""))
18319 (use (match_operand:SI 5 "const_int_operand" ""))]
18322 if (ix86_expand_setmem (operands[0], operands[1],
18323 operands[2], operands[3],
18324 operands[4], operands[5]))
18330 (define_expand "setmemdi"
18331 [(use (match_operand:BLK 0 "memory_operand" ""))
18332 (use (match_operand:DI 1 "nonmemory_operand" ""))
18333 (use (match_operand 2 "const_int_operand" ""))
18334 (use (match_operand 3 "const_int_operand" ""))
18335 (use (match_operand 4 "const_int_operand" ""))
18336 (use (match_operand 5 "const_int_operand" ""))]
18339 if (ix86_expand_setmem (operands[0], operands[1],
18340 operands[2], operands[3],
18341 operands[4], operands[5]))
18347 ;; Most CPUs don't like single string operations
18348 ;; Handle this case here to simplify previous expander.
18350 (define_expand "strset"
18351 [(set (match_operand 1 "memory_operand" "")
18352 (match_operand 2 "register_operand" ""))
18353 (parallel [(set (match_operand 0 "register_operand" "")
18355 (clobber (reg:CC FLAGS_REG))])]
18358 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18359 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18361 /* If .md ever supports :P for Pmode, this can be directly
18362 in the pattern above. */
18363 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18364 GEN_INT (GET_MODE_SIZE (GET_MODE
18366 if (TARGET_SINGLE_STRINGOP || optimize_size)
18368 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18374 (define_expand "strset_singleop"
18375 [(parallel [(set (match_operand 1 "memory_operand" "")
18376 (match_operand 2 "register_operand" ""))
18377 (set (match_operand 0 "register_operand" "")
18378 (match_operand 3 "" ""))])]
18379 "TARGET_SINGLE_STRINGOP || optimize_size"
18382 (define_insn "*strsetdi_rex_1"
18383 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18384 (match_operand:DI 2 "register_operand" "a"))
18385 (set (match_operand:DI 0 "register_operand" "=D")
18386 (plus:DI (match_dup 1)
18388 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18390 [(set_attr "type" "str")
18391 (set_attr "memory" "store")
18392 (set_attr "mode" "DI")])
18394 (define_insn "*strsetsi_1"
18395 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18396 (match_operand:SI 2 "register_operand" "a"))
18397 (set (match_operand:SI 0 "register_operand" "=D")
18398 (plus:SI (match_dup 1)
18400 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18402 [(set_attr "type" "str")
18403 (set_attr "memory" "store")
18404 (set_attr "mode" "SI")])
18406 (define_insn "*strsetsi_rex_1"
18407 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18408 (match_operand:SI 2 "register_operand" "a"))
18409 (set (match_operand:DI 0 "register_operand" "=D")
18410 (plus:DI (match_dup 1)
18412 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18414 [(set_attr "type" "str")
18415 (set_attr "memory" "store")
18416 (set_attr "mode" "SI")])
18418 (define_insn "*strsethi_1"
18419 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18420 (match_operand:HI 2 "register_operand" "a"))
18421 (set (match_operand:SI 0 "register_operand" "=D")
18422 (plus:SI (match_dup 1)
18424 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18426 [(set_attr "type" "str")
18427 (set_attr "memory" "store")
18428 (set_attr "mode" "HI")])
18430 (define_insn "*strsethi_rex_1"
18431 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18432 (match_operand:HI 2 "register_operand" "a"))
18433 (set (match_operand:DI 0 "register_operand" "=D")
18434 (plus:DI (match_dup 1)
18436 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18438 [(set_attr "type" "str")
18439 (set_attr "memory" "store")
18440 (set_attr "mode" "HI")])
18442 (define_insn "*strsetqi_1"
18443 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18444 (match_operand:QI 2 "register_operand" "a"))
18445 (set (match_operand:SI 0 "register_operand" "=D")
18446 (plus:SI (match_dup 1)
18448 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18450 [(set_attr "type" "str")
18451 (set_attr "memory" "store")
18452 (set_attr "mode" "QI")])
18454 (define_insn "*strsetqi_rex_1"
18455 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18456 (match_operand:QI 2 "register_operand" "a"))
18457 (set (match_operand:DI 0 "register_operand" "=D")
18458 (plus:DI (match_dup 1)
18460 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18462 [(set_attr "type" "str")
18463 (set_attr "memory" "store")
18464 (set_attr "mode" "QI")])
18466 (define_expand "rep_stos"
18467 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18468 (set (match_operand 0 "register_operand" "")
18469 (match_operand 4 "" ""))
18470 (set (match_operand 2 "memory_operand" "") (const_int 0))
18471 (use (match_operand 3 "register_operand" ""))
18472 (use (match_dup 1))])]
18476 (define_insn "*rep_stosdi_rex64"
18477 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18478 (set (match_operand:DI 0 "register_operand" "=D")
18479 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18481 (match_operand:DI 3 "register_operand" "0")))
18482 (set (mem:BLK (match_dup 3))
18484 (use (match_operand:DI 2 "register_operand" "a"))
18485 (use (match_dup 4))]
18487 "{rep\;stosq|rep stosq}"
18488 [(set_attr "type" "str")
18489 (set_attr "prefix_rep" "1")
18490 (set_attr "memory" "store")
18491 (set_attr "mode" "DI")])
18493 (define_insn "*rep_stossi"
18494 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18495 (set (match_operand:SI 0 "register_operand" "=D")
18496 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18498 (match_operand:SI 3 "register_operand" "0")))
18499 (set (mem:BLK (match_dup 3))
18501 (use (match_operand:SI 2 "register_operand" "a"))
18502 (use (match_dup 4))]
18504 "{rep\;stosl|rep stosd}"
18505 [(set_attr "type" "str")
18506 (set_attr "prefix_rep" "1")
18507 (set_attr "memory" "store")
18508 (set_attr "mode" "SI")])
18510 (define_insn "*rep_stossi_rex64"
18511 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18512 (set (match_operand:DI 0 "register_operand" "=D")
18513 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18515 (match_operand:DI 3 "register_operand" "0")))
18516 (set (mem:BLK (match_dup 3))
18518 (use (match_operand:SI 2 "register_operand" "a"))
18519 (use (match_dup 4))]
18521 "{rep\;stosl|rep stosd}"
18522 [(set_attr "type" "str")
18523 (set_attr "prefix_rep" "1")
18524 (set_attr "memory" "store")
18525 (set_attr "mode" "SI")])
18527 (define_insn "*rep_stosqi"
18528 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18529 (set (match_operand:SI 0 "register_operand" "=D")
18530 (plus:SI (match_operand:SI 3 "register_operand" "0")
18531 (match_operand:SI 4 "register_operand" "1")))
18532 (set (mem:BLK (match_dup 3))
18534 (use (match_operand:QI 2 "register_operand" "a"))
18535 (use (match_dup 4))]
18537 "{rep\;stosb|rep stosb}"
18538 [(set_attr "type" "str")
18539 (set_attr "prefix_rep" "1")
18540 (set_attr "memory" "store")
18541 (set_attr "mode" "QI")])
18543 (define_insn "*rep_stosqi_rex64"
18544 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18545 (set (match_operand:DI 0 "register_operand" "=D")
18546 (plus:DI (match_operand:DI 3 "register_operand" "0")
18547 (match_operand:DI 4 "register_operand" "1")))
18548 (set (mem:BLK (match_dup 3))
18550 (use (match_operand:QI 2 "register_operand" "a"))
18551 (use (match_dup 4))]
18553 "{rep\;stosb|rep stosb}"
18554 [(set_attr "type" "str")
18555 (set_attr "prefix_rep" "1")
18556 (set_attr "memory" "store")
18557 (set_attr "mode" "QI")])
18559 (define_expand "cmpstrnsi"
18560 [(set (match_operand:SI 0 "register_operand" "")
18561 (compare:SI (match_operand:BLK 1 "general_operand" "")
18562 (match_operand:BLK 2 "general_operand" "")))
18563 (use (match_operand 3 "general_operand" ""))
18564 (use (match_operand 4 "immediate_operand" ""))]
18565 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18567 rtx addr1, addr2, out, outlow, count, countreg, align;
18569 /* Can't use this if the user has appropriated esi or edi. */
18570 if (global_regs[4] || global_regs[5])
18575 out = gen_reg_rtx (SImode);
18577 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18578 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18579 if (addr1 != XEXP (operands[1], 0))
18580 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18581 if (addr2 != XEXP (operands[2], 0))
18582 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18584 count = operands[3];
18585 countreg = ix86_zero_extend_to_Pmode (count);
18587 /* %%% Iff we are testing strict equality, we can use known alignment
18588 to good advantage. This may be possible with combine, particularly
18589 once cc0 is dead. */
18590 align = operands[4];
18592 if (CONST_INT_P (count))
18594 if (INTVAL (count) == 0)
18596 emit_move_insn (operands[0], const0_rtx);
18599 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18600 operands[1], operands[2]));
18605 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18607 emit_insn (gen_cmpsi_1 (countreg, countreg));
18608 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18609 operands[1], operands[2]));
18612 outlow = gen_lowpart (QImode, out);
18613 emit_insn (gen_cmpintqi (outlow));
18614 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18616 if (operands[0] != out)
18617 emit_move_insn (operands[0], out);
18622 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18624 (define_expand "cmpintqi"
18625 [(set (match_dup 1)
18626 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18628 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18629 (parallel [(set (match_operand:QI 0 "register_operand" "")
18630 (minus:QI (match_dup 1)
18632 (clobber (reg:CC FLAGS_REG))])]
18634 "operands[1] = gen_reg_rtx (QImode);
18635 operands[2] = gen_reg_rtx (QImode);")
18637 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18638 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18640 (define_expand "cmpstrnqi_nz_1"
18641 [(parallel [(set (reg:CC FLAGS_REG)
18642 (compare:CC (match_operand 4 "memory_operand" "")
18643 (match_operand 5 "memory_operand" "")))
18644 (use (match_operand 2 "register_operand" ""))
18645 (use (match_operand:SI 3 "immediate_operand" ""))
18646 (clobber (match_operand 0 "register_operand" ""))
18647 (clobber (match_operand 1 "register_operand" ""))
18648 (clobber (match_dup 2))])]
18652 (define_insn "*cmpstrnqi_nz_1"
18653 [(set (reg:CC FLAGS_REG)
18654 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18655 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18656 (use (match_operand:SI 6 "register_operand" "2"))
18657 (use (match_operand:SI 3 "immediate_operand" "i"))
18658 (clobber (match_operand:SI 0 "register_operand" "=S"))
18659 (clobber (match_operand:SI 1 "register_operand" "=D"))
18660 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18663 [(set_attr "type" "str")
18664 (set_attr "mode" "QI")
18665 (set_attr "prefix_rep" "1")])
18667 (define_insn "*cmpstrnqi_nz_rex_1"
18668 [(set (reg:CC FLAGS_REG)
18669 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18670 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18671 (use (match_operand:DI 6 "register_operand" "2"))
18672 (use (match_operand:SI 3 "immediate_operand" "i"))
18673 (clobber (match_operand:DI 0 "register_operand" "=S"))
18674 (clobber (match_operand:DI 1 "register_operand" "=D"))
18675 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18678 [(set_attr "type" "str")
18679 (set_attr "mode" "QI")
18680 (set_attr "prefix_rep" "1")])
18682 ;; The same, but the count is not known to not be zero.
18684 (define_expand "cmpstrnqi_1"
18685 [(parallel [(set (reg:CC FLAGS_REG)
18686 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18688 (compare:CC (match_operand 4 "memory_operand" "")
18689 (match_operand 5 "memory_operand" ""))
18691 (use (match_operand:SI 3 "immediate_operand" ""))
18692 (use (reg:CC FLAGS_REG))
18693 (clobber (match_operand 0 "register_operand" ""))
18694 (clobber (match_operand 1 "register_operand" ""))
18695 (clobber (match_dup 2))])]
18699 (define_insn "*cmpstrnqi_1"
18700 [(set (reg:CC FLAGS_REG)
18701 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18703 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18704 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18706 (use (match_operand:SI 3 "immediate_operand" "i"))
18707 (use (reg:CC FLAGS_REG))
18708 (clobber (match_operand:SI 0 "register_operand" "=S"))
18709 (clobber (match_operand:SI 1 "register_operand" "=D"))
18710 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18713 [(set_attr "type" "str")
18714 (set_attr "mode" "QI")
18715 (set_attr "prefix_rep" "1")])
18717 (define_insn "*cmpstrnqi_rex_1"
18718 [(set (reg:CC FLAGS_REG)
18719 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18721 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18722 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18724 (use (match_operand:SI 3 "immediate_operand" "i"))
18725 (use (reg:CC FLAGS_REG))
18726 (clobber (match_operand:DI 0 "register_operand" "=S"))
18727 (clobber (match_operand:DI 1 "register_operand" "=D"))
18728 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18731 [(set_attr "type" "str")
18732 (set_attr "mode" "QI")
18733 (set_attr "prefix_rep" "1")])
18735 (define_expand "strlensi"
18736 [(set (match_operand:SI 0 "register_operand" "")
18737 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18738 (match_operand:QI 2 "immediate_operand" "")
18739 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18742 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18748 (define_expand "strlendi"
18749 [(set (match_operand:DI 0 "register_operand" "")
18750 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18751 (match_operand:QI 2 "immediate_operand" "")
18752 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18755 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18761 (define_expand "strlenqi_1"
18762 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18763 (clobber (match_operand 1 "register_operand" ""))
18764 (clobber (reg:CC FLAGS_REG))])]
18768 (define_insn "*strlenqi_1"
18769 [(set (match_operand:SI 0 "register_operand" "=&c")
18770 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18771 (match_operand:QI 2 "register_operand" "a")
18772 (match_operand:SI 3 "immediate_operand" "i")
18773 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18774 (clobber (match_operand:SI 1 "register_operand" "=D"))
18775 (clobber (reg:CC FLAGS_REG))]
18778 [(set_attr "type" "str")
18779 (set_attr "mode" "QI")
18780 (set_attr "prefix_rep" "1")])
18782 (define_insn "*strlenqi_rex_1"
18783 [(set (match_operand:DI 0 "register_operand" "=&c")
18784 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18785 (match_operand:QI 2 "register_operand" "a")
18786 (match_operand:DI 3 "immediate_operand" "i")
18787 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18788 (clobber (match_operand:DI 1 "register_operand" "=D"))
18789 (clobber (reg:CC FLAGS_REG))]
18792 [(set_attr "type" "str")
18793 (set_attr "mode" "QI")
18794 (set_attr "prefix_rep" "1")])
18796 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18797 ;; handled in combine, but it is not currently up to the task.
18798 ;; When used for their truth value, the cmpstrn* expanders generate
18807 ;; The intermediate three instructions are unnecessary.
18809 ;; This one handles cmpstrn*_nz_1...
18812 (set (reg:CC FLAGS_REG)
18813 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18814 (mem:BLK (match_operand 5 "register_operand" ""))))
18815 (use (match_operand 6 "register_operand" ""))
18816 (use (match_operand:SI 3 "immediate_operand" ""))
18817 (clobber (match_operand 0 "register_operand" ""))
18818 (clobber (match_operand 1 "register_operand" ""))
18819 (clobber (match_operand 2 "register_operand" ""))])
18820 (set (match_operand:QI 7 "register_operand" "")
18821 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18822 (set (match_operand:QI 8 "register_operand" "")
18823 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18824 (set (reg FLAGS_REG)
18825 (compare (match_dup 7) (match_dup 8)))
18827 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18829 (set (reg:CC FLAGS_REG)
18830 (compare:CC (mem:BLK (match_dup 4))
18831 (mem:BLK (match_dup 5))))
18832 (use (match_dup 6))
18833 (use (match_dup 3))
18834 (clobber (match_dup 0))
18835 (clobber (match_dup 1))
18836 (clobber (match_dup 2))])]
18839 ;; ...and this one handles cmpstrn*_1.
18842 (set (reg:CC FLAGS_REG)
18843 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18845 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18846 (mem:BLK (match_operand 5 "register_operand" "")))
18848 (use (match_operand:SI 3 "immediate_operand" ""))
18849 (use (reg:CC FLAGS_REG))
18850 (clobber (match_operand 0 "register_operand" ""))
18851 (clobber (match_operand 1 "register_operand" ""))
18852 (clobber (match_operand 2 "register_operand" ""))])
18853 (set (match_operand:QI 7 "register_operand" "")
18854 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18855 (set (match_operand:QI 8 "register_operand" "")
18856 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18857 (set (reg FLAGS_REG)
18858 (compare (match_dup 7) (match_dup 8)))
18860 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18862 (set (reg:CC FLAGS_REG)
18863 (if_then_else:CC (ne (match_dup 6)
18865 (compare:CC (mem:BLK (match_dup 4))
18866 (mem:BLK (match_dup 5)))
18868 (use (match_dup 3))
18869 (use (reg:CC FLAGS_REG))
18870 (clobber (match_dup 0))
18871 (clobber (match_dup 1))
18872 (clobber (match_dup 2))])]
18877 ;; Conditional move instructions.
18879 (define_expand "movdicc"
18880 [(set (match_operand:DI 0 "register_operand" "")
18881 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18882 (match_operand:DI 2 "general_operand" "")
18883 (match_operand:DI 3 "general_operand" "")))]
18885 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18887 (define_insn "x86_movdicc_0_m1_rex64"
18888 [(set (match_operand:DI 0 "register_operand" "=r")
18889 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18892 (clobber (reg:CC FLAGS_REG))]
18895 ; Since we don't have the proper number of operands for an alu insn,
18896 ; fill in all the blanks.
18897 [(set_attr "type" "alu")
18898 (set_attr "pent_pair" "pu")
18899 (set_attr "memory" "none")
18900 (set_attr "imm_disp" "false")
18901 (set_attr "mode" "DI")
18902 (set_attr "length_immediate" "0")])
18904 (define_insn "*movdicc_c_rex64"
18905 [(set (match_operand:DI 0 "register_operand" "=r,r")
18906 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18907 [(reg FLAGS_REG) (const_int 0)])
18908 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18909 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18910 "TARGET_64BIT && TARGET_CMOVE
18911 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18913 cmov%O2%C1\t{%2, %0|%0, %2}
18914 cmov%O2%c1\t{%3, %0|%0, %3}"
18915 [(set_attr "type" "icmov")
18916 (set_attr "mode" "DI")])
18918 (define_expand "movsicc"
18919 [(set (match_operand:SI 0 "register_operand" "")
18920 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18921 (match_operand:SI 2 "general_operand" "")
18922 (match_operand:SI 3 "general_operand" "")))]
18924 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18926 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18927 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18928 ;; So just document what we're doing explicitly.
18930 (define_insn "x86_movsicc_0_m1"
18931 [(set (match_operand:SI 0 "register_operand" "=r")
18932 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18935 (clobber (reg:CC FLAGS_REG))]
18938 ; Since we don't have the proper number of operands for an alu insn,
18939 ; fill in all the blanks.
18940 [(set_attr "type" "alu")
18941 (set_attr "pent_pair" "pu")
18942 (set_attr "memory" "none")
18943 (set_attr "imm_disp" "false")
18944 (set_attr "mode" "SI")
18945 (set_attr "length_immediate" "0")])
18947 (define_insn "*movsicc_noc"
18948 [(set (match_operand:SI 0 "register_operand" "=r,r")
18949 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18950 [(reg FLAGS_REG) (const_int 0)])
18951 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18952 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18954 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18956 cmov%O2%C1\t{%2, %0|%0, %2}
18957 cmov%O2%c1\t{%3, %0|%0, %3}"
18958 [(set_attr "type" "icmov")
18959 (set_attr "mode" "SI")])
18961 (define_expand "movhicc"
18962 [(set (match_operand:HI 0 "register_operand" "")
18963 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18964 (match_operand:HI 2 "general_operand" "")
18965 (match_operand:HI 3 "general_operand" "")))]
18966 "TARGET_HIMODE_MATH"
18967 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18969 (define_insn "*movhicc_noc"
18970 [(set (match_operand:HI 0 "register_operand" "=r,r")
18971 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18972 [(reg FLAGS_REG) (const_int 0)])
18973 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18974 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18976 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18978 cmov%O2%C1\t{%2, %0|%0, %2}
18979 cmov%O2%c1\t{%3, %0|%0, %3}"
18980 [(set_attr "type" "icmov")
18981 (set_attr "mode" "HI")])
18983 (define_expand "movqicc"
18984 [(set (match_operand:QI 0 "register_operand" "")
18985 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18986 (match_operand:QI 2 "general_operand" "")
18987 (match_operand:QI 3 "general_operand" "")))]
18988 "TARGET_QIMODE_MATH"
18989 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18991 (define_insn_and_split "*movqicc_noc"
18992 [(set (match_operand:QI 0 "register_operand" "=r,r")
18993 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18994 [(match_operand 4 "flags_reg_operand" "")
18996 (match_operand:QI 2 "register_operand" "r,0")
18997 (match_operand:QI 3 "register_operand" "0,r")))]
18998 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19000 "&& reload_completed"
19001 [(set (match_dup 0)
19002 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19005 "operands[0] = gen_lowpart (SImode, operands[0]);
19006 operands[2] = gen_lowpart (SImode, operands[2]);
19007 operands[3] = gen_lowpart (SImode, operands[3]);"
19008 [(set_attr "type" "icmov")
19009 (set_attr "mode" "SI")])
19011 (define_expand "movsfcc"
19012 [(set (match_operand:SF 0 "register_operand" "")
19013 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19014 (match_operand:SF 2 "register_operand" "")
19015 (match_operand:SF 3 "register_operand" "")))]
19016 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19017 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19019 (define_insn "*movsfcc_1_387"
19020 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19021 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19022 [(reg FLAGS_REG) (const_int 0)])
19023 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19024 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19025 "TARGET_80387 && TARGET_CMOVE
19026 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19028 fcmov%F1\t{%2, %0|%0, %2}
19029 fcmov%f1\t{%3, %0|%0, %3}
19030 cmov%O2%C1\t{%2, %0|%0, %2}
19031 cmov%O2%c1\t{%3, %0|%0, %3}"
19032 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19033 (set_attr "mode" "SF,SF,SI,SI")])
19035 (define_expand "movdfcc"
19036 [(set (match_operand:DF 0 "register_operand" "")
19037 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19038 (match_operand:DF 2 "register_operand" "")
19039 (match_operand:DF 3 "register_operand" "")))]
19040 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19041 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19043 (define_insn "*movdfcc_1"
19044 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19045 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19046 [(reg FLAGS_REG) (const_int 0)])
19047 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19048 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19049 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19050 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19052 fcmov%F1\t{%2, %0|%0, %2}
19053 fcmov%f1\t{%3, %0|%0, %3}
19056 [(set_attr "type" "fcmov,fcmov,multi,multi")
19057 (set_attr "mode" "DF")])
19059 (define_insn "*movdfcc_1_rex64"
19060 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19061 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19062 [(reg FLAGS_REG) (const_int 0)])
19063 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19064 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19065 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19066 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19068 fcmov%F1\t{%2, %0|%0, %2}
19069 fcmov%f1\t{%3, %0|%0, %3}
19070 cmov%O2%C1\t{%2, %0|%0, %2}
19071 cmov%O2%c1\t{%3, %0|%0, %3}"
19072 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19073 (set_attr "mode" "DF")])
19076 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19077 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19078 [(match_operand 4 "flags_reg_operand" "")
19080 (match_operand:DF 2 "nonimmediate_operand" "")
19081 (match_operand:DF 3 "nonimmediate_operand" "")))]
19082 "!TARGET_64BIT && reload_completed"
19083 [(set (match_dup 2)
19084 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19088 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19091 "split_di (operands+2, 1, operands+5, operands+6);
19092 split_di (operands+3, 1, operands+7, operands+8);
19093 split_di (operands, 1, operands+2, operands+3);")
19095 (define_expand "movxfcc"
19096 [(set (match_operand:XF 0 "register_operand" "")
19097 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19098 (match_operand:XF 2 "register_operand" "")
19099 (match_operand:XF 3 "register_operand" "")))]
19100 "TARGET_80387 && TARGET_CMOVE"
19101 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19103 (define_insn "*movxfcc_1"
19104 [(set (match_operand:XF 0 "register_operand" "=f,f")
19105 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19106 [(reg FLAGS_REG) (const_int 0)])
19107 (match_operand:XF 2 "register_operand" "f,0")
19108 (match_operand:XF 3 "register_operand" "0,f")))]
19109 "TARGET_80387 && TARGET_CMOVE"
19111 fcmov%F1\t{%2, %0|%0, %2}
19112 fcmov%f1\t{%3, %0|%0, %3}"
19113 [(set_attr "type" "fcmov")
19114 (set_attr "mode" "XF")])
19116 ;; These versions of the min/max patterns are intentionally ignorant of
19117 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19118 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19119 ;; are undefined in this condition, we're certain this is correct.
19121 (define_insn "sminsf3"
19122 [(set (match_operand:SF 0 "register_operand" "=x")
19123 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19124 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19126 "minss\t{%2, %0|%0, %2}"
19127 [(set_attr "type" "sseadd")
19128 (set_attr "mode" "SF")])
19130 (define_insn "smaxsf3"
19131 [(set (match_operand:SF 0 "register_operand" "=x")
19132 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19133 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19135 "maxss\t{%2, %0|%0, %2}"
19136 [(set_attr "type" "sseadd")
19137 (set_attr "mode" "SF")])
19139 (define_insn "smindf3"
19140 [(set (match_operand:DF 0 "register_operand" "=x")
19141 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19142 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19143 "TARGET_SSE2 && TARGET_SSE_MATH"
19144 "minsd\t{%2, %0|%0, %2}"
19145 [(set_attr "type" "sseadd")
19146 (set_attr "mode" "DF")])
19148 (define_insn "smaxdf3"
19149 [(set (match_operand:DF 0 "register_operand" "=x")
19150 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19151 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19152 "TARGET_SSE2 && TARGET_SSE_MATH"
19153 "maxsd\t{%2, %0|%0, %2}"
19154 [(set_attr "type" "sseadd")
19155 (set_attr "mode" "DF")])
19157 ;; These versions of the min/max patterns implement exactly the operations
19158 ;; min = (op1 < op2 ? op1 : op2)
19159 ;; max = (!(op1 < op2) ? op1 : op2)
19160 ;; Their operands are not commutative, and thus they may be used in the
19161 ;; presence of -0.0 and NaN.
19163 (define_insn "*ieee_sminsf3"
19164 [(set (match_operand:SF 0 "register_operand" "=x")
19165 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19166 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19169 "minss\t{%2, %0|%0, %2}"
19170 [(set_attr "type" "sseadd")
19171 (set_attr "mode" "SF")])
19173 (define_insn "*ieee_smaxsf3"
19174 [(set (match_operand:SF 0 "register_operand" "=x")
19175 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19176 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19179 "maxss\t{%2, %0|%0, %2}"
19180 [(set_attr "type" "sseadd")
19181 (set_attr "mode" "SF")])
19183 (define_insn "*ieee_smindf3"
19184 [(set (match_operand:DF 0 "register_operand" "=x")
19185 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19186 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19188 "TARGET_SSE2 && TARGET_SSE_MATH"
19189 "minsd\t{%2, %0|%0, %2}"
19190 [(set_attr "type" "sseadd")
19191 (set_attr "mode" "DF")])
19193 (define_insn "*ieee_smaxdf3"
19194 [(set (match_operand:DF 0 "register_operand" "=x")
19195 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19196 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19198 "TARGET_SSE2 && TARGET_SSE_MATH"
19199 "maxsd\t{%2, %0|%0, %2}"
19200 [(set_attr "type" "sseadd")
19201 (set_attr "mode" "DF")])
19203 ;; Make two stack loads independent:
19205 ;; fld %st(0) -> fld bb
19206 ;; fmul bb fmul %st(1), %st
19208 ;; Actually we only match the last two instructions for simplicity.
19210 [(set (match_operand 0 "fp_register_operand" "")
19211 (match_operand 1 "fp_register_operand" ""))
19213 (match_operator 2 "binary_fp_operator"
19215 (match_operand 3 "memory_operand" "")]))]
19216 "REGNO (operands[0]) != REGNO (operands[1])"
19217 [(set (match_dup 0) (match_dup 3))
19218 (set (match_dup 0) (match_dup 4))]
19220 ;; The % modifier is not operational anymore in peephole2's, so we have to
19221 ;; swap the operands manually in the case of addition and multiplication.
19222 "if (COMMUTATIVE_ARITH_P (operands[2]))
19223 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19224 operands[0], operands[1]);
19226 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19227 operands[1], operands[0]);")
19229 ;; Conditional addition patterns
19230 (define_expand "addqicc"
19231 [(match_operand:QI 0 "register_operand" "")
19232 (match_operand 1 "comparison_operator" "")
19233 (match_operand:QI 2 "register_operand" "")
19234 (match_operand:QI 3 "const_int_operand" "")]
19236 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19238 (define_expand "addhicc"
19239 [(match_operand:HI 0 "register_operand" "")
19240 (match_operand 1 "comparison_operator" "")
19241 (match_operand:HI 2 "register_operand" "")
19242 (match_operand:HI 3 "const_int_operand" "")]
19244 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19246 (define_expand "addsicc"
19247 [(match_operand:SI 0 "register_operand" "")
19248 (match_operand 1 "comparison_operator" "")
19249 (match_operand:SI 2 "register_operand" "")
19250 (match_operand:SI 3 "const_int_operand" "")]
19252 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19254 (define_expand "adddicc"
19255 [(match_operand:DI 0 "register_operand" "")
19256 (match_operand 1 "comparison_operator" "")
19257 (match_operand:DI 2 "register_operand" "")
19258 (match_operand:DI 3 "const_int_operand" "")]
19260 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19263 ;; Misc patterns (?)
19265 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19266 ;; Otherwise there will be nothing to keep
19268 ;; [(set (reg ebp) (reg esp))]
19269 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19270 ;; (clobber (eflags)]
19271 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19273 ;; in proper program order.
19274 (define_insn "pro_epilogue_adjust_stack_1"
19275 [(set (match_operand:SI 0 "register_operand" "=r,r")
19276 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19277 (match_operand:SI 2 "immediate_operand" "i,i")))
19278 (clobber (reg:CC FLAGS_REG))
19279 (clobber (mem:BLK (scratch)))]
19282 switch (get_attr_type (insn))
19285 return "mov{l}\t{%1, %0|%0, %1}";
19288 if (CONST_INT_P (operands[2])
19289 && (INTVAL (operands[2]) == 128
19290 || (INTVAL (operands[2]) < 0
19291 && INTVAL (operands[2]) != -128)))
19293 operands[2] = GEN_INT (-INTVAL (operands[2]));
19294 return "sub{l}\t{%2, %0|%0, %2}";
19296 return "add{l}\t{%2, %0|%0, %2}";
19299 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19300 return "lea{l}\t{%a2, %0|%0, %a2}";
19303 gcc_unreachable ();
19306 [(set (attr "type")
19307 (cond [(eq_attr "alternative" "0")
19308 (const_string "alu")
19309 (match_operand:SI 2 "const0_operand" "")
19310 (const_string "imov")
19312 (const_string "lea")))
19313 (set_attr "mode" "SI")])
19315 (define_insn "pro_epilogue_adjust_stack_rex64"
19316 [(set (match_operand:DI 0 "register_operand" "=r,r")
19317 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19318 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19319 (clobber (reg:CC FLAGS_REG))
19320 (clobber (mem:BLK (scratch)))]
19323 switch (get_attr_type (insn))
19326 return "mov{q}\t{%1, %0|%0, %1}";
19329 if (CONST_INT_P (operands[2])
19330 /* Avoid overflows. */
19331 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19332 && (INTVAL (operands[2]) == 128
19333 || (INTVAL (operands[2]) < 0
19334 && INTVAL (operands[2]) != -128)))
19336 operands[2] = GEN_INT (-INTVAL (operands[2]));
19337 return "sub{q}\t{%2, %0|%0, %2}";
19339 return "add{q}\t{%2, %0|%0, %2}";
19342 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19343 return "lea{q}\t{%a2, %0|%0, %a2}";
19346 gcc_unreachable ();
19349 [(set (attr "type")
19350 (cond [(eq_attr "alternative" "0")
19351 (const_string "alu")
19352 (match_operand:DI 2 "const0_operand" "")
19353 (const_string "imov")
19355 (const_string "lea")))
19356 (set_attr "mode" "DI")])
19358 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19359 [(set (match_operand:DI 0 "register_operand" "=r,r")
19360 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19361 (match_operand:DI 3 "immediate_operand" "i,i")))
19362 (use (match_operand:DI 2 "register_operand" "r,r"))
19363 (clobber (reg:CC FLAGS_REG))
19364 (clobber (mem:BLK (scratch)))]
19367 switch (get_attr_type (insn))
19370 return "add{q}\t{%2, %0|%0, %2}";
19373 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19374 return "lea{q}\t{%a2, %0|%0, %a2}";
19377 gcc_unreachable ();
19380 [(set_attr "type" "alu,lea")
19381 (set_attr "mode" "DI")])
19383 (define_expand "allocate_stack_worker"
19384 [(match_operand:SI 0 "register_operand" "")]
19385 "TARGET_STACK_PROBE"
19387 if (reload_completed)
19390 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19392 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19397 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19399 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19404 (define_insn "allocate_stack_worker_1"
19405 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19406 UNSPECV_STACK_PROBE)
19407 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19408 (clobber (match_scratch:SI 1 "=0"))
19409 (clobber (reg:CC FLAGS_REG))]
19410 "!TARGET_64BIT && TARGET_STACK_PROBE"
19412 [(set_attr "type" "multi")
19413 (set_attr "length" "5")])
19415 (define_expand "allocate_stack_worker_postreload"
19416 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19417 UNSPECV_STACK_PROBE)
19418 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19419 (clobber (match_dup 0))
19420 (clobber (reg:CC FLAGS_REG))])]
19424 (define_insn "allocate_stack_worker_rex64"
19425 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19426 UNSPECV_STACK_PROBE)
19427 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19428 (clobber (match_scratch:DI 1 "=0"))
19429 (clobber (reg:CC FLAGS_REG))]
19430 "TARGET_64BIT && TARGET_STACK_PROBE"
19432 [(set_attr "type" "multi")
19433 (set_attr "length" "5")])
19435 (define_expand "allocate_stack_worker_rex64_postreload"
19436 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19437 UNSPECV_STACK_PROBE)
19438 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19439 (clobber (match_dup 0))
19440 (clobber (reg:CC FLAGS_REG))])]
19444 (define_expand "allocate_stack"
19445 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19446 (minus:SI (reg:SI SP_REG)
19447 (match_operand:SI 1 "general_operand" "")))
19448 (clobber (reg:CC FLAGS_REG))])
19449 (parallel [(set (reg:SI SP_REG)
19450 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19451 (clobber (reg:CC FLAGS_REG))])]
19452 "TARGET_STACK_PROBE"
19454 #ifdef CHECK_STACK_LIMIT
19455 if (CONST_INT_P (operands[1])
19456 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19457 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19461 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19464 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19468 (define_expand "builtin_setjmp_receiver"
19469 [(label_ref (match_operand 0 "" ""))]
19470 "!TARGET_64BIT && flag_pic"
19475 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19476 rtx label_rtx = gen_label_rtx ();
19477 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19478 xops[0] = xops[1] = picreg;
19479 xops[2] = gen_rtx_CONST (SImode,
19480 gen_rtx_MINUS (SImode,
19481 gen_rtx_LABEL_REF (SImode, label_rtx),
19482 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19483 ix86_expand_binary_operator (MINUS, SImode, xops);
19486 emit_insn (gen_set_got (pic_offset_table_rtx));
19490 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19493 [(set (match_operand 0 "register_operand" "")
19494 (match_operator 3 "promotable_binary_operator"
19495 [(match_operand 1 "register_operand" "")
19496 (match_operand 2 "aligned_operand" "")]))
19497 (clobber (reg:CC FLAGS_REG))]
19498 "! TARGET_PARTIAL_REG_STALL && reload_completed
19499 && ((GET_MODE (operands[0]) == HImode
19500 && ((!optimize_size && !TARGET_FAST_PREFIX)
19501 /* ??? next two lines just !satisfies_constraint_K (...) */
19502 || !CONST_INT_P (operands[2])
19503 || satisfies_constraint_K (operands[2])))
19504 || (GET_MODE (operands[0]) == QImode
19505 && (TARGET_PROMOTE_QImode || optimize_size)))"
19506 [(parallel [(set (match_dup 0)
19507 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19508 (clobber (reg:CC FLAGS_REG))])]
19509 "operands[0] = gen_lowpart (SImode, operands[0]);
19510 operands[1] = gen_lowpart (SImode, operands[1]);
19511 if (GET_CODE (operands[3]) != ASHIFT)
19512 operands[2] = gen_lowpart (SImode, operands[2]);
19513 PUT_MODE (operands[3], SImode);")
19515 ; Promote the QImode tests, as i386 has encoding of the AND
19516 ; instruction with 32-bit sign-extended immediate and thus the
19517 ; instruction size is unchanged, except in the %eax case for
19518 ; which it is increased by one byte, hence the ! optimize_size.
19520 [(set (match_operand 0 "flags_reg_operand" "")
19521 (match_operator 2 "compare_operator"
19522 [(and (match_operand 3 "aligned_operand" "")
19523 (match_operand 4 "const_int_operand" ""))
19525 (set (match_operand 1 "register_operand" "")
19526 (and (match_dup 3) (match_dup 4)))]
19527 "! TARGET_PARTIAL_REG_STALL && reload_completed
19528 /* Ensure that the operand will remain sign-extended immediate. */
19529 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19531 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19532 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19533 [(parallel [(set (match_dup 0)
19534 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19537 (and:SI (match_dup 3) (match_dup 4)))])]
19540 = gen_int_mode (INTVAL (operands[4])
19541 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19542 operands[1] = gen_lowpart (SImode, operands[1]);
19543 operands[3] = gen_lowpart (SImode, operands[3]);
19546 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19547 ; the TEST instruction with 32-bit sign-extended immediate and thus
19548 ; the instruction size would at least double, which is not what we
19549 ; want even with ! optimize_size.
19551 [(set (match_operand 0 "flags_reg_operand" "")
19552 (match_operator 1 "compare_operator"
19553 [(and (match_operand:HI 2 "aligned_operand" "")
19554 (match_operand:HI 3 "const_int_operand" ""))
19556 "! TARGET_PARTIAL_REG_STALL && reload_completed
19557 /* Ensure that the operand will remain sign-extended immediate. */
19558 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19559 && ! TARGET_FAST_PREFIX
19560 && ! optimize_size"
19561 [(set (match_dup 0)
19562 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19566 = gen_int_mode (INTVAL (operands[3])
19567 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19568 operands[2] = gen_lowpart (SImode, operands[2]);
19572 [(set (match_operand 0 "register_operand" "")
19573 (neg (match_operand 1 "register_operand" "")))
19574 (clobber (reg:CC FLAGS_REG))]
19575 "! TARGET_PARTIAL_REG_STALL && reload_completed
19576 && (GET_MODE (operands[0]) == HImode
19577 || (GET_MODE (operands[0]) == QImode
19578 && (TARGET_PROMOTE_QImode || optimize_size)))"
19579 [(parallel [(set (match_dup 0)
19580 (neg:SI (match_dup 1)))
19581 (clobber (reg:CC FLAGS_REG))])]
19582 "operands[0] = gen_lowpart (SImode, operands[0]);
19583 operands[1] = gen_lowpart (SImode, operands[1]);")
19586 [(set (match_operand 0 "register_operand" "")
19587 (not (match_operand 1 "register_operand" "")))]
19588 "! TARGET_PARTIAL_REG_STALL && reload_completed
19589 && (GET_MODE (operands[0]) == HImode
19590 || (GET_MODE (operands[0]) == QImode
19591 && (TARGET_PROMOTE_QImode || optimize_size)))"
19592 [(set (match_dup 0)
19593 (not:SI (match_dup 1)))]
19594 "operands[0] = gen_lowpart (SImode, operands[0]);
19595 operands[1] = gen_lowpart (SImode, operands[1]);")
19598 [(set (match_operand 0 "register_operand" "")
19599 (if_then_else (match_operator 1 "comparison_operator"
19600 [(reg FLAGS_REG) (const_int 0)])
19601 (match_operand 2 "register_operand" "")
19602 (match_operand 3 "register_operand" "")))]
19603 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19604 && (GET_MODE (operands[0]) == HImode
19605 || (GET_MODE (operands[0]) == QImode
19606 && (TARGET_PROMOTE_QImode || optimize_size)))"
19607 [(set (match_dup 0)
19608 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19609 "operands[0] = gen_lowpart (SImode, operands[0]);
19610 operands[2] = gen_lowpart (SImode, operands[2]);
19611 operands[3] = gen_lowpart (SImode, operands[3]);")
19614 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19615 ;; transform a complex memory operation into two memory to register operations.
19617 ;; Don't push memory operands
19619 [(set (match_operand:SI 0 "push_operand" "")
19620 (match_operand:SI 1 "memory_operand" ""))
19621 (match_scratch:SI 2 "r")]
19622 "!optimize_size && !TARGET_PUSH_MEMORY
19623 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19624 [(set (match_dup 2) (match_dup 1))
19625 (set (match_dup 0) (match_dup 2))]
19629 [(set (match_operand:DI 0 "push_operand" "")
19630 (match_operand:DI 1 "memory_operand" ""))
19631 (match_scratch:DI 2 "r")]
19632 "!optimize_size && !TARGET_PUSH_MEMORY
19633 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19634 [(set (match_dup 2) (match_dup 1))
19635 (set (match_dup 0) (match_dup 2))]
19638 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19641 [(set (match_operand:SF 0 "push_operand" "")
19642 (match_operand:SF 1 "memory_operand" ""))
19643 (match_scratch:SF 2 "r")]
19644 "!optimize_size && !TARGET_PUSH_MEMORY
19645 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19646 [(set (match_dup 2) (match_dup 1))
19647 (set (match_dup 0) (match_dup 2))]
19651 [(set (match_operand:HI 0 "push_operand" "")
19652 (match_operand:HI 1 "memory_operand" ""))
19653 (match_scratch:HI 2 "r")]
19654 "!optimize_size && !TARGET_PUSH_MEMORY
19655 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19656 [(set (match_dup 2) (match_dup 1))
19657 (set (match_dup 0) (match_dup 2))]
19661 [(set (match_operand:QI 0 "push_operand" "")
19662 (match_operand:QI 1 "memory_operand" ""))
19663 (match_scratch:QI 2 "q")]
19664 "!optimize_size && !TARGET_PUSH_MEMORY
19665 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19666 [(set (match_dup 2) (match_dup 1))
19667 (set (match_dup 0) (match_dup 2))]
19670 ;; Don't move an immediate directly to memory when the instruction
19673 [(match_scratch:SI 1 "r")
19674 (set (match_operand:SI 0 "memory_operand" "")
19677 && ! TARGET_USE_MOV0
19678 && TARGET_SPLIT_LONG_MOVES
19679 && get_attr_length (insn) >= ix86_cost->large_insn
19680 && peep2_regno_dead_p (0, FLAGS_REG)"
19681 [(parallel [(set (match_dup 1) (const_int 0))
19682 (clobber (reg:CC FLAGS_REG))])
19683 (set (match_dup 0) (match_dup 1))]
19687 [(match_scratch:HI 1 "r")
19688 (set (match_operand:HI 0 "memory_operand" "")
19691 && ! TARGET_USE_MOV0
19692 && TARGET_SPLIT_LONG_MOVES
19693 && get_attr_length (insn) >= ix86_cost->large_insn
19694 && peep2_regno_dead_p (0, FLAGS_REG)"
19695 [(parallel [(set (match_dup 2) (const_int 0))
19696 (clobber (reg:CC FLAGS_REG))])
19697 (set (match_dup 0) (match_dup 1))]
19698 "operands[2] = gen_lowpart (SImode, operands[1]);")
19701 [(match_scratch:QI 1 "q")
19702 (set (match_operand:QI 0 "memory_operand" "")
19705 && ! TARGET_USE_MOV0
19706 && TARGET_SPLIT_LONG_MOVES
19707 && get_attr_length (insn) >= ix86_cost->large_insn
19708 && peep2_regno_dead_p (0, FLAGS_REG)"
19709 [(parallel [(set (match_dup 2) (const_int 0))
19710 (clobber (reg:CC FLAGS_REG))])
19711 (set (match_dup 0) (match_dup 1))]
19712 "operands[2] = gen_lowpart (SImode, operands[1]);")
19715 [(match_scratch:SI 2 "r")
19716 (set (match_operand:SI 0 "memory_operand" "")
19717 (match_operand:SI 1 "immediate_operand" ""))]
19719 && get_attr_length (insn) >= ix86_cost->large_insn
19720 && TARGET_SPLIT_LONG_MOVES"
19721 [(set (match_dup 2) (match_dup 1))
19722 (set (match_dup 0) (match_dup 2))]
19726 [(match_scratch:HI 2 "r")
19727 (set (match_operand:HI 0 "memory_operand" "")
19728 (match_operand:HI 1 "immediate_operand" ""))]
19729 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19730 && TARGET_SPLIT_LONG_MOVES"
19731 [(set (match_dup 2) (match_dup 1))
19732 (set (match_dup 0) (match_dup 2))]
19736 [(match_scratch:QI 2 "q")
19737 (set (match_operand:QI 0 "memory_operand" "")
19738 (match_operand:QI 1 "immediate_operand" ""))]
19739 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19740 && TARGET_SPLIT_LONG_MOVES"
19741 [(set (match_dup 2) (match_dup 1))
19742 (set (match_dup 0) (match_dup 2))]
19745 ;; Don't compare memory with zero, load and use a test instead.
19747 [(set (match_operand 0 "flags_reg_operand" "")
19748 (match_operator 1 "compare_operator"
19749 [(match_operand:SI 2 "memory_operand" "")
19751 (match_scratch:SI 3 "r")]
19752 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19753 [(set (match_dup 3) (match_dup 2))
19754 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19757 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19758 ;; Don't split NOTs with a displacement operand, because resulting XOR
19759 ;; will not be pairable anyway.
19761 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19762 ;; represented using a modRM byte. The XOR replacement is long decoded,
19763 ;; so this split helps here as well.
19765 ;; Note: Can't do this as a regular split because we can't get proper
19766 ;; lifetime information then.
19769 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19770 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19772 && peep2_regno_dead_p (0, FLAGS_REG)
19773 && ((TARGET_PENTIUM
19774 && (!MEM_P (operands[0])
19775 || !memory_displacement_operand (operands[0], SImode)))
19776 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19777 [(parallel [(set (match_dup 0)
19778 (xor:SI (match_dup 1) (const_int -1)))
19779 (clobber (reg:CC FLAGS_REG))])]
19783 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19784 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19786 && peep2_regno_dead_p (0, FLAGS_REG)
19787 && ((TARGET_PENTIUM
19788 && (!MEM_P (operands[0])
19789 || !memory_displacement_operand (operands[0], HImode)))
19790 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19791 [(parallel [(set (match_dup 0)
19792 (xor:HI (match_dup 1) (const_int -1)))
19793 (clobber (reg:CC FLAGS_REG))])]
19797 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19798 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19800 && peep2_regno_dead_p (0, FLAGS_REG)
19801 && ((TARGET_PENTIUM
19802 && (!MEM_P (operands[0])
19803 || !memory_displacement_operand (operands[0], QImode)))
19804 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19805 [(parallel [(set (match_dup 0)
19806 (xor:QI (match_dup 1) (const_int -1)))
19807 (clobber (reg:CC FLAGS_REG))])]
19810 ;; Non pairable "test imm, reg" instructions can be translated to
19811 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19812 ;; byte opcode instead of two, have a short form for byte operands),
19813 ;; so do it for other CPUs as well. Given that the value was dead,
19814 ;; this should not create any new dependencies. Pass on the sub-word
19815 ;; versions if we're concerned about partial register stalls.
19818 [(set (match_operand 0 "flags_reg_operand" "")
19819 (match_operator 1 "compare_operator"
19820 [(and:SI (match_operand:SI 2 "register_operand" "")
19821 (match_operand:SI 3 "immediate_operand" ""))
19823 "ix86_match_ccmode (insn, CCNOmode)
19824 && (true_regnum (operands[2]) != 0
19825 || satisfies_constraint_K (operands[3]))
19826 && peep2_reg_dead_p (1, operands[2])"
19828 [(set (match_dup 0)
19829 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19832 (and:SI (match_dup 2) (match_dup 3)))])]
19835 ;; We don't need to handle HImode case, because it will be promoted to SImode
19836 ;; on ! TARGET_PARTIAL_REG_STALL
19839 [(set (match_operand 0 "flags_reg_operand" "")
19840 (match_operator 1 "compare_operator"
19841 [(and:QI (match_operand:QI 2 "register_operand" "")
19842 (match_operand:QI 3 "immediate_operand" ""))
19844 "! TARGET_PARTIAL_REG_STALL
19845 && ix86_match_ccmode (insn, CCNOmode)
19846 && true_regnum (operands[2]) != 0
19847 && peep2_reg_dead_p (1, operands[2])"
19849 [(set (match_dup 0)
19850 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19853 (and:QI (match_dup 2) (match_dup 3)))])]
19857 [(set (match_operand 0 "flags_reg_operand" "")
19858 (match_operator 1 "compare_operator"
19861 (match_operand 2 "ext_register_operand" "")
19864 (match_operand 3 "const_int_operand" ""))
19866 "! TARGET_PARTIAL_REG_STALL
19867 && ix86_match_ccmode (insn, CCNOmode)
19868 && true_regnum (operands[2]) != 0
19869 && peep2_reg_dead_p (1, operands[2])"
19870 [(parallel [(set (match_dup 0)
19879 (set (zero_extract:SI (match_dup 2)
19890 ;; Don't do logical operations with memory inputs.
19892 [(match_scratch:SI 2 "r")
19893 (parallel [(set (match_operand:SI 0 "register_operand" "")
19894 (match_operator:SI 3 "arith_or_logical_operator"
19896 (match_operand:SI 1 "memory_operand" "")]))
19897 (clobber (reg:CC FLAGS_REG))])]
19898 "! optimize_size && ! TARGET_READ_MODIFY"
19899 [(set (match_dup 2) (match_dup 1))
19900 (parallel [(set (match_dup 0)
19901 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19902 (clobber (reg:CC FLAGS_REG))])]
19906 [(match_scratch:SI 2 "r")
19907 (parallel [(set (match_operand:SI 0 "register_operand" "")
19908 (match_operator:SI 3 "arith_or_logical_operator"
19909 [(match_operand:SI 1 "memory_operand" "")
19911 (clobber (reg:CC FLAGS_REG))])]
19912 "! optimize_size && ! TARGET_READ_MODIFY"
19913 [(set (match_dup 2) (match_dup 1))
19914 (parallel [(set (match_dup 0)
19915 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19916 (clobber (reg:CC FLAGS_REG))])]
19919 ; Don't do logical operations with memory outputs
19921 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19922 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19923 ; the same decoder scheduling characteristics as the original.
19926 [(match_scratch:SI 2 "r")
19927 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19928 (match_operator:SI 3 "arith_or_logical_operator"
19930 (match_operand:SI 1 "nonmemory_operand" "")]))
19931 (clobber (reg:CC FLAGS_REG))])]
19932 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19933 [(set (match_dup 2) (match_dup 0))
19934 (parallel [(set (match_dup 2)
19935 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19936 (clobber (reg:CC FLAGS_REG))])
19937 (set (match_dup 0) (match_dup 2))]
19941 [(match_scratch:SI 2 "r")
19942 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19943 (match_operator:SI 3 "arith_or_logical_operator"
19944 [(match_operand:SI 1 "nonmemory_operand" "")
19946 (clobber (reg:CC FLAGS_REG))])]
19947 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19948 [(set (match_dup 2) (match_dup 0))
19949 (parallel [(set (match_dup 2)
19950 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19951 (clobber (reg:CC FLAGS_REG))])
19952 (set (match_dup 0) (match_dup 2))]
19955 ;; Attempt to always use XOR for zeroing registers.
19957 [(set (match_operand 0 "register_operand" "")
19958 (match_operand 1 "const0_operand" ""))]
19959 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19960 && (! TARGET_USE_MOV0 || optimize_size)
19961 && GENERAL_REG_P (operands[0])
19962 && peep2_regno_dead_p (0, FLAGS_REG)"
19963 [(parallel [(set (match_dup 0) (const_int 0))
19964 (clobber (reg:CC FLAGS_REG))])]
19966 operands[0] = gen_lowpart (word_mode, operands[0]);
19970 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19972 "(GET_MODE (operands[0]) == QImode
19973 || GET_MODE (operands[0]) == HImode)
19974 && (! TARGET_USE_MOV0 || optimize_size)
19975 && peep2_regno_dead_p (0, FLAGS_REG)"
19976 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19977 (clobber (reg:CC FLAGS_REG))])])
19979 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19981 [(set (match_operand 0 "register_operand" "")
19983 "(GET_MODE (operands[0]) == HImode
19984 || GET_MODE (operands[0]) == SImode
19985 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19986 && (optimize_size || TARGET_PENTIUM)
19987 && peep2_regno_dead_p (0, FLAGS_REG)"
19988 [(parallel [(set (match_dup 0) (const_int -1))
19989 (clobber (reg:CC FLAGS_REG))])]
19990 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19993 ;; Attempt to convert simple leas to adds. These can be created by
19996 [(set (match_operand:SI 0 "register_operand" "")
19997 (plus:SI (match_dup 0)
19998 (match_operand:SI 1 "nonmemory_operand" "")))]
19999 "peep2_regno_dead_p (0, FLAGS_REG)"
20000 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20001 (clobber (reg:CC FLAGS_REG))])]
20005 [(set (match_operand:SI 0 "register_operand" "")
20006 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20007 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20008 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20009 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20010 (clobber (reg:CC FLAGS_REG))])]
20011 "operands[2] = gen_lowpart (SImode, operands[2]);")
20014 [(set (match_operand:DI 0 "register_operand" "")
20015 (plus:DI (match_dup 0)
20016 (match_operand:DI 1 "x86_64_general_operand" "")))]
20017 "peep2_regno_dead_p (0, FLAGS_REG)"
20018 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20019 (clobber (reg:CC FLAGS_REG))])]
20023 [(set (match_operand:SI 0 "register_operand" "")
20024 (mult:SI (match_dup 0)
20025 (match_operand:SI 1 "const_int_operand" "")))]
20026 "exact_log2 (INTVAL (operands[1])) >= 0
20027 && peep2_regno_dead_p (0, FLAGS_REG)"
20028 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20029 (clobber (reg:CC FLAGS_REG))])]
20030 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20033 [(set (match_operand:DI 0 "register_operand" "")
20034 (mult:DI (match_dup 0)
20035 (match_operand:DI 1 "const_int_operand" "")))]
20036 "exact_log2 (INTVAL (operands[1])) >= 0
20037 && peep2_regno_dead_p (0, FLAGS_REG)"
20038 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20039 (clobber (reg:CC FLAGS_REG))])]
20040 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20043 [(set (match_operand:SI 0 "register_operand" "")
20044 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20045 (match_operand:DI 2 "const_int_operand" "")) 0))]
20046 "exact_log2 (INTVAL (operands[2])) >= 0
20047 && REGNO (operands[0]) == REGNO (operands[1])
20048 && peep2_regno_dead_p (0, FLAGS_REG)"
20049 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20050 (clobber (reg:CC FLAGS_REG))])]
20051 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20053 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20054 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20055 ;; many CPUs it is also faster, since special hardware to avoid esp
20056 ;; dependencies is present.
20058 ;; While some of these conversions may be done using splitters, we use peepholes
20059 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20061 ;; Convert prologue esp subtractions to push.
20062 ;; We need register to push. In order to keep verify_flow_info happy we have
20064 ;; - use scratch and clobber it in order to avoid dependencies
20065 ;; - use already live register
20066 ;; We can't use the second way right now, since there is no reliable way how to
20067 ;; verify that given register is live. First choice will also most likely in
20068 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20069 ;; call clobbered registers are dead. We may want to use base pointer as an
20070 ;; alternative when no register is available later.
20073 [(match_scratch:SI 0 "r")
20074 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20075 (clobber (reg:CC FLAGS_REG))
20076 (clobber (mem:BLK (scratch)))])]
20077 "optimize_size || !TARGET_SUB_ESP_4"
20078 [(clobber (match_dup 0))
20079 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20080 (clobber (mem:BLK (scratch)))])])
20083 [(match_scratch:SI 0 "r")
20084 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20085 (clobber (reg:CC FLAGS_REG))
20086 (clobber (mem:BLK (scratch)))])]
20087 "optimize_size || !TARGET_SUB_ESP_8"
20088 [(clobber (match_dup 0))
20089 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20090 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20091 (clobber (mem:BLK (scratch)))])])
20093 ;; Convert esp subtractions to push.
20095 [(match_scratch:SI 0 "r")
20096 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20097 (clobber (reg:CC FLAGS_REG))])]
20098 "optimize_size || !TARGET_SUB_ESP_4"
20099 [(clobber (match_dup 0))
20100 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20103 [(match_scratch:SI 0 "r")
20104 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20105 (clobber (reg:CC FLAGS_REG))])]
20106 "optimize_size || !TARGET_SUB_ESP_8"
20107 [(clobber (match_dup 0))
20108 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20109 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20111 ;; Convert epilogue deallocator to pop.
20113 [(match_scratch:SI 0 "r")
20114 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20115 (clobber (reg:CC FLAGS_REG))
20116 (clobber (mem:BLK (scratch)))])]
20117 "optimize_size || !TARGET_ADD_ESP_4"
20118 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20119 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20120 (clobber (mem:BLK (scratch)))])]
20123 ;; Two pops case is tricky, since pop causes dependency on destination register.
20124 ;; We use two registers if available.
20126 [(match_scratch:SI 0 "r")
20127 (match_scratch:SI 1 "r")
20128 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20129 (clobber (reg:CC FLAGS_REG))
20130 (clobber (mem:BLK (scratch)))])]
20131 "optimize_size || !TARGET_ADD_ESP_8"
20132 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20133 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20134 (clobber (mem:BLK (scratch)))])
20135 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20136 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
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)))])]
20145 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20146 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20147 (clobber (mem:BLK (scratch)))])
20148 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20149 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20152 ;; Convert esp additions to pop.
20154 [(match_scratch:SI 0 "r")
20155 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20156 (clobber (reg:CC FLAGS_REG))])]
20158 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20159 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20162 ;; Two pops case is tricky, since pop causes dependency on destination register.
20163 ;; We use two registers if available.
20165 [(match_scratch:SI 0 "r")
20166 (match_scratch:SI 1 "r")
20167 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20168 (clobber (reg:CC FLAGS_REG))])]
20170 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20171 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20172 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20173 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20177 [(match_scratch:SI 0 "r")
20178 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20179 (clobber (reg:CC FLAGS_REG))])]
20181 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20182 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20183 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20184 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20187 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20188 ;; required and register dies. Similarly for 128 to plus -128.
20190 [(set (match_operand 0 "flags_reg_operand" "")
20191 (match_operator 1 "compare_operator"
20192 [(match_operand 2 "register_operand" "")
20193 (match_operand 3 "const_int_operand" "")]))]
20194 "(INTVAL (operands[3]) == -1
20195 || INTVAL (operands[3]) == 1
20196 || INTVAL (operands[3]) == 128)
20197 && ix86_match_ccmode (insn, CCGCmode)
20198 && peep2_reg_dead_p (1, operands[2])"
20199 [(parallel [(set (match_dup 0)
20200 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20201 (clobber (match_dup 2))])]
20205 [(match_scratch:DI 0 "r")
20206 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20207 (clobber (reg:CC FLAGS_REG))
20208 (clobber (mem:BLK (scratch)))])]
20209 "optimize_size || !TARGET_SUB_ESP_4"
20210 [(clobber (match_dup 0))
20211 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20212 (clobber (mem:BLK (scratch)))])])
20215 [(match_scratch:DI 0 "r")
20216 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20217 (clobber (reg:CC FLAGS_REG))
20218 (clobber (mem:BLK (scratch)))])]
20219 "optimize_size || !TARGET_SUB_ESP_8"
20220 [(clobber (match_dup 0))
20221 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20222 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20223 (clobber (mem:BLK (scratch)))])])
20225 ;; Convert esp subtractions to push.
20227 [(match_scratch:DI 0 "r")
20228 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20229 (clobber (reg:CC FLAGS_REG))])]
20230 "optimize_size || !TARGET_SUB_ESP_4"
20231 [(clobber (match_dup 0))
20232 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20235 [(match_scratch:DI 0 "r")
20236 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20237 (clobber (reg:CC FLAGS_REG))])]
20238 "optimize_size || !TARGET_SUB_ESP_8"
20239 [(clobber (match_dup 0))
20240 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20241 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20243 ;; Convert epilogue deallocator to pop.
20245 [(match_scratch:DI 0 "r")
20246 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20247 (clobber (reg:CC FLAGS_REG))
20248 (clobber (mem:BLK (scratch)))])]
20249 "optimize_size || !TARGET_ADD_ESP_4"
20250 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20251 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20252 (clobber (mem:BLK (scratch)))])]
20255 ;; Two pops case is tricky, since pop causes dependency on destination register.
20256 ;; We use two registers if available.
20258 [(match_scratch:DI 0 "r")
20259 (match_scratch:DI 1 "r")
20260 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20261 (clobber (reg:CC FLAGS_REG))
20262 (clobber (mem:BLK (scratch)))])]
20263 "optimize_size || !TARGET_ADD_ESP_8"
20264 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20265 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20266 (clobber (mem:BLK (scratch)))])
20267 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20268 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
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)))])]
20277 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20278 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20279 (clobber (mem:BLK (scratch)))])
20280 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20281 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20284 ;; Convert esp additions to pop.
20286 [(match_scratch:DI 0 "r")
20287 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20288 (clobber (reg:CC FLAGS_REG))])]
20290 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20291 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20294 ;; Two pops case is tricky, since pop causes dependency on destination register.
20295 ;; We use two registers if available.
20297 [(match_scratch:DI 0 "r")
20298 (match_scratch:DI 1 "r")
20299 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20300 (clobber (reg:CC FLAGS_REG))])]
20302 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20303 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20304 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20305 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20309 [(match_scratch:DI 0 "r")
20310 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20311 (clobber (reg:CC FLAGS_REG))])]
20313 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20314 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20315 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20316 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20319 ;; Convert imul by three, five and nine into lea
20322 [(set (match_operand:SI 0 "register_operand" "")
20323 (mult:SI (match_operand:SI 1 "register_operand" "")
20324 (match_operand:SI 2 "const_int_operand" "")))
20325 (clobber (reg:CC FLAGS_REG))])]
20326 "INTVAL (operands[2]) == 3
20327 || INTVAL (operands[2]) == 5
20328 || INTVAL (operands[2]) == 9"
20329 [(set (match_dup 0)
20330 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20332 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20336 [(set (match_operand:SI 0 "register_operand" "")
20337 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20338 (match_operand:SI 2 "const_int_operand" "")))
20339 (clobber (reg:CC FLAGS_REG))])]
20341 && (INTVAL (operands[2]) == 3
20342 || INTVAL (operands[2]) == 5
20343 || INTVAL (operands[2]) == 9)"
20344 [(set (match_dup 0) (match_dup 1))
20346 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20348 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20352 [(set (match_operand:DI 0 "register_operand" "")
20353 (mult:DI (match_operand:DI 1 "register_operand" "")
20354 (match_operand:DI 2 "const_int_operand" "")))
20355 (clobber (reg:CC FLAGS_REG))])]
20357 && (INTVAL (operands[2]) == 3
20358 || INTVAL (operands[2]) == 5
20359 || INTVAL (operands[2]) == 9)"
20360 [(set (match_dup 0)
20361 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20363 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20367 [(set (match_operand:DI 0 "register_operand" "")
20368 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20369 (match_operand:DI 2 "const_int_operand" "")))
20370 (clobber (reg:CC FLAGS_REG))])]
20373 && (INTVAL (operands[2]) == 3
20374 || INTVAL (operands[2]) == 5
20375 || INTVAL (operands[2]) == 9)"
20376 [(set (match_dup 0) (match_dup 1))
20378 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20380 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20382 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20383 ;; imul $32bit_imm, reg, reg is direct decoded.
20385 [(match_scratch:DI 3 "r")
20386 (parallel [(set (match_operand:DI 0 "register_operand" "")
20387 (mult:DI (match_operand:DI 1 "memory_operand" "")
20388 (match_operand:DI 2 "immediate_operand" "")))
20389 (clobber (reg:CC FLAGS_REG))])]
20390 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20391 && !satisfies_constraint_K (operands[2])"
20392 [(set (match_dup 3) (match_dup 1))
20393 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20394 (clobber (reg:CC FLAGS_REG))])]
20398 [(match_scratch:SI 3 "r")
20399 (parallel [(set (match_operand:SI 0 "register_operand" "")
20400 (mult:SI (match_operand:SI 1 "memory_operand" "")
20401 (match_operand:SI 2 "immediate_operand" "")))
20402 (clobber (reg:CC FLAGS_REG))])]
20403 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20404 && !satisfies_constraint_K (operands[2])"
20405 [(set (match_dup 3) (match_dup 1))
20406 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20407 (clobber (reg:CC FLAGS_REG))])]
20411 [(match_scratch:SI 3 "r")
20412 (parallel [(set (match_operand:DI 0 "register_operand" "")
20414 (mult:SI (match_operand:SI 1 "memory_operand" "")
20415 (match_operand:SI 2 "immediate_operand" ""))))
20416 (clobber (reg:CC FLAGS_REG))])]
20417 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20418 && !satisfies_constraint_K (operands[2])"
20419 [(set (match_dup 3) (match_dup 1))
20420 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20421 (clobber (reg:CC FLAGS_REG))])]
20424 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20425 ;; Convert it into imul reg, reg
20426 ;; It would be better to force assembler to encode instruction using long
20427 ;; immediate, but there is apparently no way to do so.
20429 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20430 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20431 (match_operand:DI 2 "const_int_operand" "")))
20432 (clobber (reg:CC FLAGS_REG))])
20433 (match_scratch:DI 3 "r")]
20434 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20435 && satisfies_constraint_K (operands[2])"
20436 [(set (match_dup 3) (match_dup 2))
20437 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20438 (clobber (reg:CC FLAGS_REG))])]
20440 if (!rtx_equal_p (operands[0], operands[1]))
20441 emit_move_insn (operands[0], operands[1]);
20445 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20446 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20447 (match_operand:SI 2 "const_int_operand" "")))
20448 (clobber (reg:CC FLAGS_REG))])
20449 (match_scratch:SI 3 "r")]
20450 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20451 && satisfies_constraint_K (operands[2])"
20452 [(set (match_dup 3) (match_dup 2))
20453 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20454 (clobber (reg:CC FLAGS_REG))])]
20456 if (!rtx_equal_p (operands[0], operands[1]))
20457 emit_move_insn (operands[0], operands[1]);
20461 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20462 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20463 (match_operand:HI 2 "immediate_operand" "")))
20464 (clobber (reg:CC FLAGS_REG))])
20465 (match_scratch:HI 3 "r")]
20466 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20467 [(set (match_dup 3) (match_dup 2))
20468 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20469 (clobber (reg:CC FLAGS_REG))])]
20471 if (!rtx_equal_p (operands[0], operands[1]))
20472 emit_move_insn (operands[0], operands[1]);
20475 ;; After splitting up read-modify operations, array accesses with memory
20476 ;; operands might end up in form:
20478 ;; movl 4(%esp), %edx
20480 ;; instead of pre-splitting:
20482 ;; addl 4(%esp), %eax
20484 ;; movl 4(%esp), %edx
20485 ;; leal (%edx,%eax,4), %eax
20488 [(parallel [(set (match_operand 0 "register_operand" "")
20489 (ashift (match_operand 1 "register_operand" "")
20490 (match_operand 2 "const_int_operand" "")))
20491 (clobber (reg:CC FLAGS_REG))])
20492 (set (match_operand 3 "register_operand")
20493 (match_operand 4 "x86_64_general_operand" ""))
20494 (parallel [(set (match_operand 5 "register_operand" "")
20495 (plus (match_operand 6 "register_operand" "")
20496 (match_operand 7 "register_operand" "")))
20497 (clobber (reg:CC FLAGS_REG))])]
20498 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20499 /* Validate MODE for lea. */
20500 && ((!TARGET_PARTIAL_REG_STALL
20501 && (GET_MODE (operands[0]) == QImode
20502 || GET_MODE (operands[0]) == HImode))
20503 || GET_MODE (operands[0]) == SImode
20504 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20505 /* We reorder load and the shift. */
20506 && !rtx_equal_p (operands[1], operands[3])
20507 && !reg_overlap_mentioned_p (operands[0], operands[4])
20508 /* Last PLUS must consist of operand 0 and 3. */
20509 && !rtx_equal_p (operands[0], operands[3])
20510 && (rtx_equal_p (operands[3], operands[6])
20511 || rtx_equal_p (operands[3], operands[7]))
20512 && (rtx_equal_p (operands[0], operands[6])
20513 || rtx_equal_p (operands[0], operands[7]))
20514 /* The intermediate operand 0 must die or be same as output. */
20515 && (rtx_equal_p (operands[0], operands[5])
20516 || peep2_reg_dead_p (3, operands[0]))"
20517 [(set (match_dup 3) (match_dup 4))
20518 (set (match_dup 0) (match_dup 1))]
20520 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20521 int scale = 1 << INTVAL (operands[2]);
20522 rtx index = gen_lowpart (Pmode, operands[1]);
20523 rtx base = gen_lowpart (Pmode, operands[3]);
20524 rtx dest = gen_lowpart (mode, operands[5]);
20526 operands[1] = gen_rtx_PLUS (Pmode, base,
20527 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20529 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20530 operands[0] = dest;
20533 ;; Call-value patterns last so that the wildcard operand does not
20534 ;; disrupt insn-recog's switch tables.
20536 (define_insn "*call_value_pop_0"
20537 [(set (match_operand 0 "" "")
20538 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20539 (match_operand:SI 2 "" "")))
20540 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20541 (match_operand:SI 3 "immediate_operand" "")))]
20544 if (SIBLING_CALL_P (insn))
20547 return "call\t%P1";
20549 [(set_attr "type" "callv")])
20551 (define_insn "*call_value_pop_1"
20552 [(set (match_operand 0 "" "")
20553 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20554 (match_operand:SI 2 "" "")))
20555 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20556 (match_operand:SI 3 "immediate_operand" "i")))]
20559 if (constant_call_address_operand (operands[1], Pmode))
20561 if (SIBLING_CALL_P (insn))
20564 return "call\t%P1";
20566 if (SIBLING_CALL_P (insn))
20569 return "call\t%A1";
20571 [(set_attr "type" "callv")])
20573 (define_insn "*call_value_0"
20574 [(set (match_operand 0 "" "")
20575 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20576 (match_operand:SI 2 "" "")))]
20579 if (SIBLING_CALL_P (insn))
20582 return "call\t%P1";
20584 [(set_attr "type" "callv")])
20586 (define_insn "*call_value_0_rex64"
20587 [(set (match_operand 0 "" "")
20588 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20589 (match_operand:DI 2 "const_int_operand" "")))]
20592 if (SIBLING_CALL_P (insn))
20595 return "call\t%P1";
20597 [(set_attr "type" "callv")])
20599 (define_insn "*call_value_1"
20600 [(set (match_operand 0 "" "")
20601 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20602 (match_operand:SI 2 "" "")))]
20603 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20605 if (constant_call_address_operand (operands[1], Pmode))
20606 return "call\t%P1";
20607 return "call\t%A1";
20609 [(set_attr "type" "callv")])
20611 (define_insn "*sibcall_value_1"
20612 [(set (match_operand 0 "" "")
20613 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20614 (match_operand:SI 2 "" "")))]
20615 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20617 if (constant_call_address_operand (operands[1], Pmode))
20621 [(set_attr "type" "callv")])
20623 (define_insn "*call_value_1_rex64"
20624 [(set (match_operand 0 "" "")
20625 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20626 (match_operand:DI 2 "" "")))]
20627 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20629 if (constant_call_address_operand (operands[1], Pmode))
20630 return "call\t%P1";
20631 return "call\t%A1";
20633 [(set_attr "type" "callv")])
20635 (define_insn "*sibcall_value_1_rex64"
20636 [(set (match_operand 0 "" "")
20637 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20638 (match_operand:DI 2 "" "")))]
20639 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20641 [(set_attr "type" "callv")])
20643 (define_insn "*sibcall_value_1_rex64_v"
20644 [(set (match_operand 0 "" "")
20645 (call (mem:QI (reg:DI R11_REG))
20646 (match_operand:DI 1 "" "")))]
20647 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20649 [(set_attr "type" "callv")])
20651 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20652 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20653 ;; caught for use by garbage collectors and the like. Using an insn that
20654 ;; maps to SIGILL makes it more likely the program will rightfully die.
20655 ;; Keeping with tradition, "6" is in honor of #UD.
20656 (define_insn "trap"
20657 [(trap_if (const_int 1) (const_int 6))]
20659 { return ASM_SHORT "0x0b0f"; }
20660 [(set_attr "length" "2")])
20662 (define_expand "sse_prologue_save"
20663 [(parallel [(set (match_operand:BLK 0 "" "")
20664 (unspec:BLK [(reg:DI 21)
20671 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20672 (use (match_operand:DI 1 "register_operand" ""))
20673 (use (match_operand:DI 2 "immediate_operand" ""))
20674 (use (label_ref:DI (match_operand 3 "" "")))])]
20678 (define_insn "*sse_prologue_save_insn"
20679 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20680 (match_operand:DI 4 "const_int_operand" "n")))
20681 (unspec:BLK [(reg:DI 21)
20688 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20689 (use (match_operand:DI 1 "register_operand" "r"))
20690 (use (match_operand:DI 2 "const_int_operand" "i"))
20691 (use (label_ref:DI (match_operand 3 "" "X")))]
20693 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20694 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20698 operands[0] = gen_rtx_MEM (Pmode,
20699 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20700 output_asm_insn (\"jmp\\t%A1\", operands);
20701 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20703 operands[4] = adjust_address (operands[0], DImode, i*16);
20704 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20705 PUT_MODE (operands[4], TImode);
20706 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20707 output_asm_insn (\"rex\", operands);
20708 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20710 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20711 CODE_LABEL_NUMBER (operands[3]));
20715 [(set_attr "type" "other")
20716 (set_attr "length_immediate" "0")
20717 (set_attr "length_address" "0")
20718 (set_attr "length" "135")
20719 (set_attr "memory" "store")
20720 (set_attr "modrm" "0")
20721 (set_attr "mode" "DI")])
20723 (define_expand "prefetch"
20724 [(prefetch (match_operand 0 "address_operand" "")
20725 (match_operand:SI 1 "const_int_operand" "")
20726 (match_operand:SI 2 "const_int_operand" ""))]
20727 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20729 int rw = INTVAL (operands[1]);
20730 int locality = INTVAL (operands[2]);
20732 gcc_assert (rw == 0 || rw == 1);
20733 gcc_assert (locality >= 0 && locality <= 3);
20734 gcc_assert (GET_MODE (operands[0]) == Pmode
20735 || GET_MODE (operands[0]) == VOIDmode);
20737 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20738 supported by SSE counterpart or the SSE prefetch is not available
20739 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20741 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20742 operands[2] = GEN_INT (3);
20744 operands[1] = const0_rtx;
20747 (define_insn "*prefetch_sse"
20748 [(prefetch (match_operand:SI 0 "address_operand" "p")
20750 (match_operand:SI 1 "const_int_operand" ""))]
20751 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20753 static const char * const patterns[4] = {
20754 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20757 int locality = INTVAL (operands[1]);
20758 gcc_assert (locality >= 0 && locality <= 3);
20760 return patterns[locality];
20762 [(set_attr "type" "sse")
20763 (set_attr "memory" "none")])
20765 (define_insn "*prefetch_sse_rex"
20766 [(prefetch (match_operand:DI 0 "address_operand" "p")
20768 (match_operand:SI 1 "const_int_operand" ""))]
20769 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20771 static const char * const patterns[4] = {
20772 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20775 int locality = INTVAL (operands[1]);
20776 gcc_assert (locality >= 0 && locality <= 3);
20778 return patterns[locality];
20780 [(set_attr "type" "sse")
20781 (set_attr "memory" "none")])
20783 (define_insn "*prefetch_3dnow"
20784 [(prefetch (match_operand:SI 0 "address_operand" "p")
20785 (match_operand:SI 1 "const_int_operand" "n")
20787 "TARGET_3DNOW && !TARGET_64BIT"
20789 if (INTVAL (operands[1]) == 0)
20790 return "prefetch\t%a0";
20792 return "prefetchw\t%a0";
20794 [(set_attr "type" "mmx")
20795 (set_attr "memory" "none")])
20797 (define_insn "*prefetch_3dnow_rex"
20798 [(prefetch (match_operand:DI 0 "address_operand" "p")
20799 (match_operand:SI 1 "const_int_operand" "n")
20801 "TARGET_3DNOW && TARGET_64BIT"
20803 if (INTVAL (operands[1]) == 0)
20804 return "prefetch\t%a0";
20806 return "prefetchw\t%a0";
20808 [(set_attr "type" "mmx")
20809 (set_attr "memory" "none")])
20811 (define_expand "stack_protect_set"
20812 [(match_operand 0 "memory_operand" "")
20813 (match_operand 1 "memory_operand" "")]
20816 #ifdef TARGET_THREAD_SSP_OFFSET
20818 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20819 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20821 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20822 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20825 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20827 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20832 (define_insn "stack_protect_set_si"
20833 [(set (match_operand:SI 0 "memory_operand" "=m")
20834 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20835 (set (match_scratch:SI 2 "=&r") (const_int 0))
20836 (clobber (reg:CC FLAGS_REG))]
20838 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20839 [(set_attr "type" "multi")])
20841 (define_insn "stack_protect_set_di"
20842 [(set (match_operand:DI 0 "memory_operand" "=m")
20843 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20844 (set (match_scratch:DI 2 "=&r") (const_int 0))
20845 (clobber (reg:CC FLAGS_REG))]
20847 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20848 [(set_attr "type" "multi")])
20850 (define_insn "stack_tls_protect_set_si"
20851 [(set (match_operand:SI 0 "memory_operand" "=m")
20852 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20853 (set (match_scratch:SI 2 "=&r") (const_int 0))
20854 (clobber (reg:CC FLAGS_REG))]
20856 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20857 [(set_attr "type" "multi")])
20859 (define_insn "stack_tls_protect_set_di"
20860 [(set (match_operand:DI 0 "memory_operand" "=m")
20861 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20862 (set (match_scratch:DI 2 "=&r") (const_int 0))
20863 (clobber (reg:CC FLAGS_REG))]
20866 /* The kernel uses a different segment register for performance reasons; a
20867 system call would not have to trash the userspace segment register,
20868 which would be expensive */
20869 if (ix86_cmodel != CM_KERNEL)
20870 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20872 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20874 [(set_attr "type" "multi")])
20876 (define_expand "stack_protect_test"
20877 [(match_operand 0 "memory_operand" "")
20878 (match_operand 1 "memory_operand" "")
20879 (match_operand 2 "" "")]
20882 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20883 ix86_compare_op0 = operands[0];
20884 ix86_compare_op1 = operands[1];
20885 ix86_compare_emitted = flags;
20887 #ifdef TARGET_THREAD_SSP_OFFSET
20889 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20890 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20892 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20893 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20896 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20898 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20900 emit_jump_insn (gen_beq (operands[2]));
20904 (define_insn "stack_protect_test_si"
20905 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20906 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20907 (match_operand:SI 2 "memory_operand" "m")]
20909 (clobber (match_scratch:SI 3 "=&r"))]
20911 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20912 [(set_attr "type" "multi")])
20914 (define_insn "stack_protect_test_di"
20915 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20916 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20917 (match_operand:DI 2 "memory_operand" "m")]
20919 (clobber (match_scratch:DI 3 "=&r"))]
20921 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20922 [(set_attr "type" "multi")])
20924 (define_insn "stack_tls_protect_test_si"
20925 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20926 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20927 (match_operand:SI 2 "const_int_operand" "i")]
20928 UNSPEC_SP_TLS_TEST))
20929 (clobber (match_scratch:SI 3 "=r"))]
20931 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20932 [(set_attr "type" "multi")])
20934 (define_insn "stack_tls_protect_test_di"
20935 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20936 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20937 (match_operand:DI 2 "const_int_operand" "i")]
20938 UNSPEC_SP_TLS_TEST))
20939 (clobber (match_scratch:DI 3 "=r"))]
20942 /* The kernel uses a different segment register for performance reasons; a
20943 system call would not have to trash the userspace segment register,
20944 which would be expensive */
20945 if (ix86_cmodel != CM_KERNEL)
20946 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20948 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20950 [(set_attr "type" "multi")])
20954 (include "sync.md")