1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 29)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 30)
99 (UNSPEC_NOP 38) ; prevents combiner cleverness
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
128 (UNSPEC_FRNDINT_FLOOR 70)
129 (UNSPEC_FRNDINT_CEIL 71)
130 (UNSPEC_FRNDINT_TRUNC 72)
131 (UNSPEC_FRNDINT_MASK_PM 73)
132 (UNSPEC_FIST_FLOOR 74)
133 (UNSPEC_FIST_CEIL 75)
135 ; x87 Double output FP
136 (UNSPEC_SINCOS_COS 80)
137 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
161 (UNSPEC_INSERTQI 132)
166 [(UNSPECV_BLOCKAGE 0)
167 (UNSPECV_STACK_PROBE 1)
176 (UNSPECV_CMPXCHG_1 10)
177 (UNSPECV_CMPXCHG_2 11)
182 ;; Registers by name.
193 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
196 ;; In C guard expressions, put expressions which may be compile-time
197 ;; constants first. This allows for better optimization. For
198 ;; example, write "TARGET_64BIT && reload_completed", not
199 ;; "reload_completed && TARGET_64BIT".
202 ;; Processor type. This attribute must exactly match the processor_type
203 ;; enumeration in i386.h.
204 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
205 nocona,core2,generic32,generic64,amdfam10"
206 (const (symbol_ref "ix86_tune")))
208 ;; A basic instruction type. Refinements due to arguments to be
209 ;; provided in other attributes.
212 alu,alu1,negnot,imov,imovx,lea,
213 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
214 icmp,test,ibr,setcc,icmov,
215 push,pop,call,callv,leave,
217 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
218 sselog,sselog1,sseiadd,sseishft,sseimul,
219 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
220 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
221 (const_string "other"))
223 ;; Main data type used by the insn
225 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
226 (const_string "unknown"))
228 ;; The CPU unit operations uses.
229 (define_attr "unit" "integer,i387,sse,mmx,unknown"
230 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
231 (const_string "i387")
232 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
233 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
235 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
237 (eq_attr "type" "other")
238 (const_string "unknown")]
239 (const_string "integer")))
241 ;; The (bounding maximum) length of an instruction immediate.
242 (define_attr "length_immediate" ""
243 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
246 (eq_attr "unit" "i387,sse,mmx")
248 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
250 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
251 (eq_attr "type" "imov,test")
252 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
253 (eq_attr "type" "call")
254 (if_then_else (match_operand 0 "constant_call_address_operand" "")
257 (eq_attr "type" "callv")
258 (if_then_else (match_operand 1 "constant_call_address_operand" "")
261 ;; We don't know the size before shorten_branches. Expect
262 ;; the instruction to fit for better scheduling.
263 (eq_attr "type" "ibr")
266 (symbol_ref "/* Update immediate_length and other attributes! */
267 gcc_unreachable (),1")))
269 ;; The (bounding maximum) length of an instruction address.
270 (define_attr "length_address" ""
271 (cond [(eq_attr "type" "str,other,multi,fxch")
273 (and (eq_attr "type" "call")
274 (match_operand 0 "constant_call_address_operand" ""))
276 (and (eq_attr "type" "callv")
277 (match_operand 1 "constant_call_address_operand" ""))
280 (symbol_ref "ix86_attr_length_address_default (insn)")))
282 ;; Set when length prefix is used.
283 (define_attr "prefix_data16" ""
284 (if_then_else (ior (eq_attr "mode" "HI")
285 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
289 ;; Set when string REP prefix is used.
290 (define_attr "prefix_rep" ""
291 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
295 ;; Set when 0f opcode prefix is used.
296 (define_attr "prefix_0f" ""
298 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
299 (eq_attr "unit" "sse,mmx"))
303 ;; Set when REX opcode prefix is used.
304 (define_attr "prefix_rex" ""
305 (cond [(and (eq_attr "mode" "DI")
306 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
308 (and (eq_attr "mode" "QI")
309 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
312 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
318 ;; Set when modrm byte is used.
319 (define_attr "modrm" ""
320 (cond [(eq_attr "type" "str,leave")
322 (eq_attr "unit" "i387")
324 (and (eq_attr "type" "incdec")
325 (ior (match_operand:SI 1 "register_operand" "")
326 (match_operand:HI 1 "register_operand" "")))
328 (and (eq_attr "type" "push")
329 (not (match_operand 1 "memory_operand" "")))
331 (and (eq_attr "type" "pop")
332 (not (match_operand 0 "memory_operand" "")))
334 (and (eq_attr "type" "imov")
335 (ior (and (match_operand 0 "register_operand" "")
336 (match_operand 1 "immediate_operand" ""))
337 (ior (and (match_operand 0 "ax_reg_operand" "")
338 (match_operand 1 "memory_displacement_only_operand" ""))
339 (and (match_operand 0 "memory_displacement_only_operand" "")
340 (match_operand 1 "ax_reg_operand" "")))))
342 (and (eq_attr "type" "call")
343 (match_operand 0 "constant_call_address_operand" ""))
345 (and (eq_attr "type" "callv")
346 (match_operand 1 "constant_call_address_operand" ""))
351 ;; The (bounding maximum) length of an instruction in bytes.
352 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
353 ;; Later we may want to split them and compute proper length as for
355 (define_attr "length" ""
356 (cond [(eq_attr "type" "other,multi,fistp,frndint")
358 (eq_attr "type" "fcmp")
360 (eq_attr "unit" "i387")
362 (plus (attr "prefix_data16")
363 (attr "length_address")))]
364 (plus (plus (attr "modrm")
365 (plus (attr "prefix_0f")
366 (plus (attr "prefix_rex")
368 (plus (attr "prefix_rep")
369 (plus (attr "prefix_data16")
370 (plus (attr "length_immediate")
371 (attr "length_address")))))))
373 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
374 ;; `store' if there is a simple memory reference therein, or `unknown'
375 ;; if the instruction is complex.
377 (define_attr "memory" "none,load,store,both,unknown"
378 (cond [(eq_attr "type" "other,multi,str")
379 (const_string "unknown")
380 (eq_attr "type" "lea,fcmov,fpspc")
381 (const_string "none")
382 (eq_attr "type" "fistp,leave")
383 (const_string "both")
384 (eq_attr "type" "frndint")
385 (const_string "load")
386 (eq_attr "type" "push")
387 (if_then_else (match_operand 1 "memory_operand" "")
388 (const_string "both")
389 (const_string "store"))
390 (eq_attr "type" "pop")
391 (if_then_else (match_operand 0 "memory_operand" "")
392 (const_string "both")
393 (const_string "load"))
394 (eq_attr "type" "setcc")
395 (if_then_else (match_operand 0 "memory_operand" "")
396 (const_string "store")
397 (const_string "none"))
398 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
399 (if_then_else (ior (match_operand 0 "memory_operand" "")
400 (match_operand 1 "memory_operand" ""))
401 (const_string "load")
402 (const_string "none"))
403 (eq_attr "type" "ibr")
404 (if_then_else (match_operand 0 "memory_operand" "")
405 (const_string "load")
406 (const_string "none"))
407 (eq_attr "type" "call")
408 (if_then_else (match_operand 0 "constant_call_address_operand" "")
409 (const_string "none")
410 (const_string "load"))
411 (eq_attr "type" "callv")
412 (if_then_else (match_operand 1 "constant_call_address_operand" "")
413 (const_string "none")
414 (const_string "load"))
415 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
416 (match_operand 1 "memory_operand" ""))
417 (const_string "both")
418 (and (match_operand 0 "memory_operand" "")
419 (match_operand 1 "memory_operand" ""))
420 (const_string "both")
421 (match_operand 0 "memory_operand" "")
422 (const_string "store")
423 (match_operand 1 "memory_operand" "")
424 (const_string "load")
426 "!alu1,negnot,ishift1,
427 imov,imovx,icmp,test,bitmanip,
429 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
430 mmx,mmxmov,mmxcmp,mmxcvt")
431 (match_operand 2 "memory_operand" ""))
432 (const_string "load")
433 (and (eq_attr "type" "icmov")
434 (match_operand 3 "memory_operand" ""))
435 (const_string "load")
437 (const_string "none")))
439 ;; Indicates if an instruction has both an immediate and a displacement.
441 (define_attr "imm_disp" "false,true,unknown"
442 (cond [(eq_attr "type" "other,multi")
443 (const_string "unknown")
444 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
445 (and (match_operand 0 "memory_displacement_operand" "")
446 (match_operand 1 "immediate_operand" "")))
447 (const_string "true")
448 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
449 (and (match_operand 0 "memory_displacement_operand" "")
450 (match_operand 2 "immediate_operand" "")))
451 (const_string "true")
453 (const_string "false")))
455 ;; Indicates if an FP operation has an integer source.
457 (define_attr "fp_int_src" "false,true"
458 (const_string "false"))
460 ;; Defines rounding mode of an FP operation.
462 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
463 (const_string "any"))
465 ;; Describe a user's asm statement.
466 (define_asm_attributes
467 [(set_attr "length" "128")
468 (set_attr "type" "multi")])
470 ;; All x87 floating point modes
471 (define_mode_macro X87MODEF [SF DF XF])
473 ;; x87 SFmode and DFMode floating point modes
474 (define_mode_macro X87MODEF12 [SF DF])
476 ;; All integer modes handled by x87 fisttp operator.
477 (define_mode_macro X87MODEI [HI SI DI])
479 ;; All integer modes handled by integer x87 operators.
480 (define_mode_macro X87MODEI12 [HI SI])
482 ;; All SSE floating point modes
483 (define_mode_macro SSEMODEF [SF DF])
485 ;; All integer modes handled by SSE cvtts?2si* operators.
486 (define_mode_macro SSEMODEI24 [SI DI])
488 ;; SSE asm suffix for floating point modes
489 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
492 ;; Scheduling descriptions
494 (include "pentium.md")
497 (include "athlon.md")
501 ;; Operand and operator predicates and constraints
503 (include "predicates.md")
504 (include "constraints.md")
507 ;; Compare instructions.
509 ;; All compare insns have expanders that save the operands away without
510 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
511 ;; after the cmp) will actually emit the cmpM.
513 (define_expand "cmpti"
514 [(set (reg:CC FLAGS_REG)
515 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
516 (match_operand:TI 1 "x86_64_general_operand" "")))]
519 if (MEM_P (operands[0]) && MEM_P (operands[1]))
520 operands[0] = force_reg (TImode, operands[0]);
521 ix86_compare_op0 = operands[0];
522 ix86_compare_op1 = operands[1];
526 (define_expand "cmpdi"
527 [(set (reg:CC FLAGS_REG)
528 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
529 (match_operand:DI 1 "x86_64_general_operand" "")))]
532 if (MEM_P (operands[0]) && MEM_P (operands[1]))
533 operands[0] = force_reg (DImode, operands[0]);
534 ix86_compare_op0 = operands[0];
535 ix86_compare_op1 = operands[1];
539 (define_expand "cmpsi"
540 [(set (reg:CC FLAGS_REG)
541 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
542 (match_operand:SI 1 "general_operand" "")))]
545 if (MEM_P (operands[0]) && MEM_P (operands[1]))
546 operands[0] = force_reg (SImode, operands[0]);
547 ix86_compare_op0 = operands[0];
548 ix86_compare_op1 = operands[1];
552 (define_expand "cmphi"
553 [(set (reg:CC FLAGS_REG)
554 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
555 (match_operand:HI 1 "general_operand" "")))]
558 if (MEM_P (operands[0]) && MEM_P (operands[1]))
559 operands[0] = force_reg (HImode, operands[0]);
560 ix86_compare_op0 = operands[0];
561 ix86_compare_op1 = operands[1];
565 (define_expand "cmpqi"
566 [(set (reg:CC FLAGS_REG)
567 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
568 (match_operand:QI 1 "general_operand" "")))]
571 if (MEM_P (operands[0]) && MEM_P (operands[1]))
572 operands[0] = force_reg (QImode, operands[0]);
573 ix86_compare_op0 = operands[0];
574 ix86_compare_op1 = operands[1];
578 (define_insn "cmpdi_ccno_1_rex64"
579 [(set (reg FLAGS_REG)
580 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
581 (match_operand:DI 1 "const0_operand" "n,n")))]
582 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
584 test{q}\t{%0, %0|%0, %0}
585 cmp{q}\t{%1, %0|%0, %1}"
586 [(set_attr "type" "test,icmp")
587 (set_attr "length_immediate" "0,1")
588 (set_attr "mode" "DI")])
590 (define_insn "*cmpdi_minus_1_rex64"
591 [(set (reg FLAGS_REG)
592 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
593 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
595 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
596 "cmp{q}\t{%1, %0|%0, %1}"
597 [(set_attr "type" "icmp")
598 (set_attr "mode" "DI")])
600 (define_expand "cmpdi_1_rex64"
601 [(set (reg:CC FLAGS_REG)
602 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
603 (match_operand:DI 1 "general_operand" "")))]
607 (define_insn "cmpdi_1_insn_rex64"
608 [(set (reg FLAGS_REG)
609 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
610 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
611 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
612 "cmp{q}\t{%1, %0|%0, %1}"
613 [(set_attr "type" "icmp")
614 (set_attr "mode" "DI")])
617 (define_insn "*cmpsi_ccno_1"
618 [(set (reg FLAGS_REG)
619 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
620 (match_operand:SI 1 "const0_operand" "n,n")))]
621 "ix86_match_ccmode (insn, CCNOmode)"
623 test{l}\t{%0, %0|%0, %0}
624 cmp{l}\t{%1, %0|%0, %1}"
625 [(set_attr "type" "test,icmp")
626 (set_attr "length_immediate" "0,1")
627 (set_attr "mode" "SI")])
629 (define_insn "*cmpsi_minus_1"
630 [(set (reg FLAGS_REG)
631 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632 (match_operand:SI 1 "general_operand" "ri,mr"))
634 "ix86_match_ccmode (insn, CCGOCmode)"
635 "cmp{l}\t{%1, %0|%0, %1}"
636 [(set_attr "type" "icmp")
637 (set_attr "mode" "SI")])
639 (define_expand "cmpsi_1"
640 [(set (reg:CC FLAGS_REG)
641 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642 (match_operand:SI 1 "general_operand" "ri,mr")))]
646 (define_insn "*cmpsi_1_insn"
647 [(set (reg FLAGS_REG)
648 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
649 (match_operand:SI 1 "general_operand" "ri,mr")))]
650 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
651 && ix86_match_ccmode (insn, CCmode)"
652 "cmp{l}\t{%1, %0|%0, %1}"
653 [(set_attr "type" "icmp")
654 (set_attr "mode" "SI")])
656 (define_insn "*cmphi_ccno_1"
657 [(set (reg FLAGS_REG)
658 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
659 (match_operand:HI 1 "const0_operand" "n,n")))]
660 "ix86_match_ccmode (insn, CCNOmode)"
662 test{w}\t{%0, %0|%0, %0}
663 cmp{w}\t{%1, %0|%0, %1}"
664 [(set_attr "type" "test,icmp")
665 (set_attr "length_immediate" "0,1")
666 (set_attr "mode" "HI")])
668 (define_insn "*cmphi_minus_1"
669 [(set (reg FLAGS_REG)
670 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
671 (match_operand:HI 1 "general_operand" "ri,mr"))
673 "ix86_match_ccmode (insn, CCGOCmode)"
674 "cmp{w}\t{%1, %0|%0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "HI")])
678 (define_insn "*cmphi_1"
679 [(set (reg FLAGS_REG)
680 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
681 (match_operand:HI 1 "general_operand" "ri,mr")))]
682 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
683 && ix86_match_ccmode (insn, CCmode)"
684 "cmp{w}\t{%1, %0|%0, %1}"
685 [(set_attr "type" "icmp")
686 (set_attr "mode" "HI")])
688 (define_insn "*cmpqi_ccno_1"
689 [(set (reg FLAGS_REG)
690 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
691 (match_operand:QI 1 "const0_operand" "n,n")))]
692 "ix86_match_ccmode (insn, CCNOmode)"
694 test{b}\t{%0, %0|%0, %0}
695 cmp{b}\t{$0, %0|%0, 0}"
696 [(set_attr "type" "test,icmp")
697 (set_attr "length_immediate" "0,1")
698 (set_attr "mode" "QI")])
700 (define_insn "*cmpqi_1"
701 [(set (reg FLAGS_REG)
702 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
703 (match_operand:QI 1 "general_operand" "qi,mq")))]
704 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
705 && ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%1, %0|%0, %1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
710 (define_insn "*cmpqi_minus_1"
711 [(set (reg FLAGS_REG)
712 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
713 (match_operand:QI 1 "general_operand" "qi,mq"))
715 "ix86_match_ccmode (insn, CCGOCmode)"
716 "cmp{b}\t{%1, %0|%0, %1}"
717 [(set_attr "type" "icmp")
718 (set_attr "mode" "QI")])
720 (define_insn "*cmpqi_ext_1"
721 [(set (reg FLAGS_REG)
723 (match_operand:QI 0 "general_operand" "Qm")
726 (match_operand 1 "ext_register_operand" "Q")
729 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730 "cmp{b}\t{%h1, %0|%0, %h1}"
731 [(set_attr "type" "icmp")
732 (set_attr "mode" "QI")])
734 (define_insn "*cmpqi_ext_1_rex64"
735 [(set (reg FLAGS_REG)
737 (match_operand:QI 0 "register_operand" "Q")
740 (match_operand 1 "ext_register_operand" "Q")
743 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744 "cmp{b}\t{%h1, %0|%0, %h1}"
745 [(set_attr "type" "icmp")
746 (set_attr "mode" "QI")])
748 (define_insn "*cmpqi_ext_2"
749 [(set (reg FLAGS_REG)
753 (match_operand 0 "ext_register_operand" "Q")
756 (match_operand:QI 1 "const0_operand" "n")))]
757 "ix86_match_ccmode (insn, CCNOmode)"
759 [(set_attr "type" "test")
760 (set_attr "length_immediate" "0")
761 (set_attr "mode" "QI")])
763 (define_expand "cmpqi_ext_3"
764 [(set (reg:CC FLAGS_REG)
768 (match_operand 0 "ext_register_operand" "")
771 (match_operand:QI 1 "general_operand" "")))]
775 (define_insn "cmpqi_ext_3_insn"
776 [(set (reg FLAGS_REG)
780 (match_operand 0 "ext_register_operand" "Q")
783 (match_operand:QI 1 "general_operand" "Qmn")))]
784 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
785 "cmp{b}\t{%1, %h0|%h0, %1}"
786 [(set_attr "type" "icmp")
787 (set_attr "mode" "QI")])
789 (define_insn "cmpqi_ext_3_insn_rex64"
790 [(set (reg FLAGS_REG)
794 (match_operand 0 "ext_register_operand" "Q")
797 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
798 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
799 "cmp{b}\t{%1, %h0|%h0, %1}"
800 [(set_attr "type" "icmp")
801 (set_attr "mode" "QI")])
803 (define_insn "*cmpqi_ext_4"
804 [(set (reg FLAGS_REG)
808 (match_operand 0 "ext_register_operand" "Q")
813 (match_operand 1 "ext_register_operand" "Q")
816 "ix86_match_ccmode (insn, CCmode)"
817 "cmp{b}\t{%h1, %h0|%h0, %h1}"
818 [(set_attr "type" "icmp")
819 (set_attr "mode" "QI")])
821 ;; These implement float point compares.
822 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
823 ;; which would allow mix and match FP modes on the compares. Which is what
824 ;; the old patterns did, but with many more of them.
826 (define_expand "cmpxf"
827 [(set (reg:CC FLAGS_REG)
828 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
829 (match_operand:XF 1 "nonmemory_operand" "")))]
832 ix86_compare_op0 = operands[0];
833 ix86_compare_op1 = operands[1];
837 (define_expand "cmpdf"
838 [(set (reg:CC FLAGS_REG)
839 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
840 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
841 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
843 ix86_compare_op0 = operands[0];
844 ix86_compare_op1 = operands[1];
848 (define_expand "cmpsf"
849 [(set (reg:CC FLAGS_REG)
850 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
851 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
852 "TARGET_80387 || TARGET_SSE_MATH"
854 ix86_compare_op0 = operands[0];
855 ix86_compare_op1 = operands[1];
859 ;; FP compares, step 1:
860 ;; Set the FP condition codes.
862 ;; CCFPmode compare with exceptions
863 ;; CCFPUmode compare with no exceptions
865 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
866 ;; used to manage the reg stack popping would not be preserved.
868 (define_insn "*cmpfp_0"
869 [(set (match_operand:HI 0 "register_operand" "=a")
872 (match_operand 1 "register_operand" "f")
873 (match_operand 2 "const0_operand" "X"))]
876 && FLOAT_MODE_P (GET_MODE (operands[1]))
877 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
878 "* return output_fp_compare (insn, operands, 0, 0);"
879 [(set_attr "type" "multi")
880 (set_attr "unit" "i387")
882 (cond [(match_operand:SF 1 "" "")
884 (match_operand:DF 1 "" "")
887 (const_string "XF")))])
889 (define_insn "*cmpfp_sf"
890 [(set (match_operand:HI 0 "register_operand" "=a")
893 (match_operand:SF 1 "register_operand" "f")
894 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
897 "* return output_fp_compare (insn, operands, 0, 0);"
898 [(set_attr "type" "multi")
899 (set_attr "unit" "i387")
900 (set_attr "mode" "SF")])
902 (define_insn "*cmpfp_df"
903 [(set (match_operand:HI 0 "register_operand" "=a")
906 (match_operand:DF 1 "register_operand" "f")
907 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
910 "* return output_fp_compare (insn, operands, 0, 0);"
911 [(set_attr "type" "multi")
912 (set_attr "unit" "i387")
913 (set_attr "mode" "DF")])
915 (define_insn "*cmpfp_xf"
916 [(set (match_operand:HI 0 "register_operand" "=a")
919 (match_operand:XF 1 "register_operand" "f")
920 (match_operand:XF 2 "register_operand" "f"))]
923 "* return output_fp_compare (insn, operands, 0, 0);"
924 [(set_attr "type" "multi")
925 (set_attr "unit" "i387")
926 (set_attr "mode" "XF")])
928 (define_insn "*cmpfp_u"
929 [(set (match_operand:HI 0 "register_operand" "=a")
932 (match_operand 1 "register_operand" "f")
933 (match_operand 2 "register_operand" "f"))]
936 && FLOAT_MODE_P (GET_MODE (operands[1]))
937 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938 "* return output_fp_compare (insn, operands, 0, 1);"
939 [(set_attr "type" "multi")
940 (set_attr "unit" "i387")
942 (cond [(match_operand:SF 1 "" "")
944 (match_operand:DF 1 "" "")
947 (const_string "XF")))])
949 (define_insn "*cmpfp_<mode>"
950 [(set (match_operand:HI 0 "register_operand" "=a")
953 (match_operand 1 "register_operand" "f")
954 (match_operator 3 "float_operator"
955 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
957 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
958 && FLOAT_MODE_P (GET_MODE (operands[1]))
959 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
960 "* return output_fp_compare (insn, operands, 0, 0);"
961 [(set_attr "type" "multi")
962 (set_attr "unit" "i387")
963 (set_attr "fp_int_src" "true")
964 (set_attr "mode" "<MODE>")])
966 ;; FP compares, step 2
967 ;; Move the fpsw to ax.
969 (define_insn "x86_fnstsw_1"
970 [(set (match_operand:HI 0 "register_operand" "=a")
971 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
974 [(set_attr "length" "2")
975 (set_attr "mode" "SI")
976 (set_attr "unit" "i387")])
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
981 (define_insn "x86_sahf_1"
982 [(set (reg:CC FLAGS_REG)
983 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
986 [(set_attr "length" "1")
987 (set_attr "athlon_decode" "vector")
988 (set_attr "amdfam10_decode" "direct")
989 (set_attr "mode" "SI")])
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
993 (define_insn "*cmpfp_i_mixed"
994 [(set (reg:CCFP FLAGS_REG)
995 (compare:CCFP (match_operand 0 "register_operand" "f,x")
996 (match_operand 1 "nonimmediate_operand" "f,xm")))]
998 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000 "* return output_fp_compare (insn, operands, 1, 0);"
1001 [(set_attr "type" "fcmp,ssecomi")
1003 (if_then_else (match_operand:SF 1 "" "")
1005 (const_string "DF")))
1006 (set_attr "athlon_decode" "vector")
1007 (set_attr "amdfam10_decode" "direct")])
1009 (define_insn "*cmpfp_i_sse"
1010 [(set (reg:CCFP FLAGS_REG)
1011 (compare:CCFP (match_operand 0 "register_operand" "x")
1012 (match_operand 1 "nonimmediate_operand" "xm")))]
1014 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016 "* return output_fp_compare (insn, operands, 1, 0);"
1017 [(set_attr "type" "ssecomi")
1019 (if_then_else (match_operand:SF 1 "" "")
1021 (const_string "DF")))
1022 (set_attr "athlon_decode" "vector")
1023 (set_attr "amdfam10_decode" "direct")])
1025 (define_insn "*cmpfp_i_i387"
1026 [(set (reg:CCFP FLAGS_REG)
1027 (compare:CCFP (match_operand 0 "register_operand" "f")
1028 (match_operand 1 "register_operand" "f")))]
1029 "TARGET_80387 && TARGET_CMOVE
1030 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1031 && FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033 "* return output_fp_compare (insn, operands, 1, 0);"
1034 [(set_attr "type" "fcmp")
1036 (cond [(match_operand:SF 1 "" "")
1038 (match_operand:DF 1 "" "")
1041 (const_string "XF")))
1042 (set_attr "athlon_decode" "vector")
1043 (set_attr "amdfam10_decode" "direct")])
1045 (define_insn "*cmpfp_iu_mixed"
1046 [(set (reg:CCFPU FLAGS_REG)
1047 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1048 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1049 "TARGET_MIX_SSE_I387
1050 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1051 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052 "* return output_fp_compare (insn, operands, 1, 1);"
1053 [(set_attr "type" "fcmp,ssecomi")
1055 (if_then_else (match_operand:SF 1 "" "")
1057 (const_string "DF")))
1058 (set_attr "athlon_decode" "vector")
1059 (set_attr "amdfam10_decode" "direct")])
1061 (define_insn "*cmpfp_iu_sse"
1062 [(set (reg:CCFPU FLAGS_REG)
1063 (compare:CCFPU (match_operand 0 "register_operand" "x")
1064 (match_operand 1 "nonimmediate_operand" "xm")))]
1066 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1068 "* return output_fp_compare (insn, operands, 1, 1);"
1069 [(set_attr "type" "ssecomi")
1071 (if_then_else (match_operand:SF 1 "" "")
1073 (const_string "DF")))
1074 (set_attr "athlon_decode" "vector")
1075 (set_attr "amdfam10_decode" "direct")])
1077 (define_insn "*cmpfp_iu_387"
1078 [(set (reg:CCFPU FLAGS_REG)
1079 (compare:CCFPU (match_operand 0 "register_operand" "f")
1080 (match_operand 1 "register_operand" "f")))]
1081 "TARGET_80387 && TARGET_CMOVE
1082 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1083 && FLOAT_MODE_P (GET_MODE (operands[0]))
1084 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1085 "* return output_fp_compare (insn, operands, 1, 1);"
1086 [(set_attr "type" "fcmp")
1088 (cond [(match_operand:SF 1 "" "")
1090 (match_operand:DF 1 "" "")
1093 (const_string "XF")))
1094 (set_attr "athlon_decode" "vector")
1095 (set_attr "amdfam10_decode" "direct")])
1097 ;; Move instructions.
1099 ;; General case of fullword move.
1101 (define_expand "movsi"
1102 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1103 (match_operand:SI 1 "general_operand" ""))]
1105 "ix86_expand_move (SImode, operands); DONE;")
1107 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1110 ;; %%% We don't use a post-inc memory reference because x86 is not a
1111 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1112 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1113 ;; targets without our curiosities, and it is just as easy to represent
1114 ;; this differently.
1116 (define_insn "*pushsi2"
1117 [(set (match_operand:SI 0 "push_operand" "=<")
1118 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1121 [(set_attr "type" "push")
1122 (set_attr "mode" "SI")])
1124 ;; For 64BIT abi we always round up to 8 bytes.
1125 (define_insn "*pushsi2_rex64"
1126 [(set (match_operand:SI 0 "push_operand" "=X")
1127 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1130 [(set_attr "type" "push")
1131 (set_attr "mode" "SI")])
1133 (define_insn "*pushsi2_prologue"
1134 [(set (match_operand:SI 0 "push_operand" "=<")
1135 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1136 (clobber (mem:BLK (scratch)))]
1139 [(set_attr "type" "push")
1140 (set_attr "mode" "SI")])
1142 (define_insn "*popsi1_epilogue"
1143 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144 (mem:SI (reg:SI SP_REG)))
1145 (set (reg:SI SP_REG)
1146 (plus:SI (reg:SI SP_REG) (const_int 4)))
1147 (clobber (mem:BLK (scratch)))]
1150 [(set_attr "type" "pop")
1151 (set_attr "mode" "SI")])
1153 (define_insn "popsi1"
1154 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1155 (mem:SI (reg:SI SP_REG)))
1156 (set (reg:SI SP_REG)
1157 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1160 [(set_attr "type" "pop")
1161 (set_attr "mode" "SI")])
1163 (define_insn "*movsi_xor"
1164 [(set (match_operand:SI 0 "register_operand" "=r")
1165 (match_operand:SI 1 "const0_operand" "i"))
1166 (clobber (reg:CC FLAGS_REG))]
1167 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1168 "xor{l}\t{%0, %0|%0, %0}"
1169 [(set_attr "type" "alu1")
1170 (set_attr "mode" "SI")
1171 (set_attr "length_immediate" "0")])
1173 (define_insn "*movsi_or"
1174 [(set (match_operand:SI 0 "register_operand" "=r")
1175 (match_operand:SI 1 "immediate_operand" "i"))
1176 (clobber (reg:CC FLAGS_REG))]
1178 && operands[1] == constm1_rtx
1179 && (TARGET_PENTIUM || optimize_size)"
1181 operands[1] = constm1_rtx;
1182 return "or{l}\t{%1, %0|%0, %1}";
1184 [(set_attr "type" "alu1")
1185 (set_attr "mode" "SI")
1186 (set_attr "length_immediate" "1")])
1188 (define_insn "*movsi_1"
1189 [(set (match_operand:SI 0 "nonimmediate_operand"
1190 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1191 (match_operand:SI 1 "general_operand"
1192 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1193 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1195 switch (get_attr_type (insn))
1198 if (get_attr_mode (insn) == MODE_TI)
1199 return "pxor\t%0, %0";
1200 return "xorps\t%0, %0";
1203 switch (get_attr_mode (insn))
1206 return "movdqa\t{%1, %0|%0, %1}";
1208 return "movaps\t{%1, %0|%0, %1}";
1210 return "movd\t{%1, %0|%0, %1}";
1212 return "movss\t{%1, %0|%0, %1}";
1218 return "pxor\t%0, %0";
1221 if (get_attr_mode (insn) == MODE_DI)
1222 return "movq\t{%1, %0|%0, %1}";
1223 return "movd\t{%1, %0|%0, %1}";
1226 return "lea{l}\t{%1, %0|%0, %1}";
1229 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230 return "mov{l}\t{%1, %0|%0, %1}";
1234 (cond [(eq_attr "alternative" "2")
1235 (const_string "mmxadd")
1236 (eq_attr "alternative" "3,4,5")
1237 (const_string "mmxmov")
1238 (eq_attr "alternative" "6")
1239 (const_string "sselog1")
1240 (eq_attr "alternative" "7,8,9,10,11")
1241 (const_string "ssemov")
1242 (match_operand:DI 1 "pic_32bit_operand" "")
1243 (const_string "lea")
1245 (const_string "imov")))
1247 (cond [(eq_attr "alternative" "2,3")
1249 (eq_attr "alternative" "6,7")
1251 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252 (const_string "V4SF")
1253 (const_string "TI"))
1254 (and (eq_attr "alternative" "8,9,10,11")
1255 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1258 (const_string "SI")))])
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1268 movabs{l}\t{%1, %P0|%P0, %1}
1269 mov{l}\t{%1, %a0|%a0, %1}"
1270 [(set_attr "type" "imov")
1271 (set_attr "modrm" "0,*")
1272 (set_attr "length_address" "8,0")
1273 (set_attr "length_immediate" "0,*")
1274 (set_attr "memory" "store")
1275 (set_attr "mode" "SI")])
1277 (define_insn "*movabssi_2_rex64"
1278 [(set (match_operand:SI 0 "register_operand" "=a,r")
1279 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1282 movabs{l}\t{%P1, %0|%0, %P1}
1283 mov{l}\t{%a1, %0|%0, %a1}"
1284 [(set_attr "type" "imov")
1285 (set_attr "modrm" "0,*")
1286 (set_attr "length_address" "8,0")
1287 (set_attr "length_immediate" "0")
1288 (set_attr "memory" "load")
1289 (set_attr "mode" "SI")])
1291 (define_insn "*swapsi"
1292 [(set (match_operand:SI 0 "register_operand" "+r")
1293 (match_operand:SI 1 "register_operand" "+r"))
1298 [(set_attr "type" "imov")
1299 (set_attr "mode" "SI")
1300 (set_attr "pent_pair" "np")
1301 (set_attr "athlon_decode" "vector")
1302 (set_attr "amdfam10_decode" "double")])
1304 (define_expand "movhi"
1305 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306 (match_operand:HI 1 "general_operand" ""))]
1308 "ix86_expand_move (HImode, operands); DONE;")
1310 (define_insn "*pushhi2"
1311 [(set (match_operand:HI 0 "push_operand" "=X")
1312 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1315 [(set_attr "type" "push")
1316 (set_attr "mode" "SI")])
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320 [(set (match_operand:HI 0 "push_operand" "=X")
1321 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1324 [(set_attr "type" "push")
1325 (set_attr "mode" "DI")])
1327 (define_insn "*movhi_1"
1328 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1332 switch (get_attr_type (insn))
1335 /* movzwl is faster than movw on p2 due to partial word stalls,
1336 though not as fast as an aligned movl. */
1337 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1339 if (get_attr_mode (insn) == MODE_SI)
1340 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1342 return "mov{w}\t{%1, %0|%0, %1}";
1346 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347 (const_string "imov")
1348 (and (eq_attr "alternative" "0")
1349 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1351 (eq (symbol_ref "TARGET_HIMODE_MATH")
1353 (const_string "imov")
1354 (and (eq_attr "alternative" "1,2")
1355 (match_operand:HI 1 "aligned_operand" ""))
1356 (const_string "imov")
1357 (and (ne (symbol_ref "TARGET_MOVX")
1359 (eq_attr "alternative" "0,2"))
1360 (const_string "imovx")
1362 (const_string "imov")))
1364 (cond [(eq_attr "type" "imovx")
1366 (and (eq_attr "alternative" "1,2")
1367 (match_operand:HI 1 "aligned_operand" ""))
1369 (and (eq_attr "alternative" "0")
1370 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1372 (eq (symbol_ref "TARGET_HIMODE_MATH")
1376 (const_string "HI")))])
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1386 movabs{w}\t{%1, %P0|%P0, %1}
1387 mov{w}\t{%1, %a0|%a0, %1}"
1388 [(set_attr "type" "imov")
1389 (set_attr "modrm" "0,*")
1390 (set_attr "length_address" "8,0")
1391 (set_attr "length_immediate" "0,*")
1392 (set_attr "memory" "store")
1393 (set_attr "mode" "HI")])
1395 (define_insn "*movabshi_2_rex64"
1396 [(set (match_operand:HI 0 "register_operand" "=a,r")
1397 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1400 movabs{w}\t{%P1, %0|%0, %P1}
1401 mov{w}\t{%a1, %0|%0, %a1}"
1402 [(set_attr "type" "imov")
1403 (set_attr "modrm" "0,*")
1404 (set_attr "length_address" "8,0")
1405 (set_attr "length_immediate" "0")
1406 (set_attr "memory" "load")
1407 (set_attr "mode" "HI")])
1409 (define_insn "*swaphi_1"
1410 [(set (match_operand:HI 0 "register_operand" "+r")
1411 (match_operand:HI 1 "register_operand" "+r"))
1414 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1416 [(set_attr "type" "imov")
1417 (set_attr "mode" "SI")
1418 (set_attr "pent_pair" "np")
1419 (set_attr "athlon_decode" "vector")
1420 (set_attr "amdfam10_decode" "double")])
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424 [(set (match_operand:HI 0 "register_operand" "+r")
1425 (match_operand:HI 1 "register_operand" "+r"))
1428 "TARGET_PARTIAL_REG_STALL"
1430 [(set_attr "type" "imov")
1431 (set_attr "mode" "HI")
1432 (set_attr "pent_pair" "np")
1433 (set_attr "athlon_decode" "vector")])
1435 (define_expand "movstricthi"
1436 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437 (match_operand:HI 1 "general_operand" ""))]
1438 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1440 /* Don't generate memory->memory moves, go through a register */
1441 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442 operands[1] = force_reg (HImode, operands[1]);
1445 (define_insn "*movstricthi_1"
1446 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447 (match_operand:HI 1 "general_operand" "rn,m"))]
1448 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450 "mov{w}\t{%1, %0|%0, %1}"
1451 [(set_attr "type" "imov")
1452 (set_attr "mode" "HI")])
1454 (define_insn "*movstricthi_xor"
1455 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456 (match_operand:HI 1 "const0_operand" "i"))
1457 (clobber (reg:CC FLAGS_REG))]
1459 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1460 "xor{w}\t{%0, %0|%0, %0}"
1461 [(set_attr "type" "alu1")
1462 (set_attr "mode" "HI")
1463 (set_attr "length_immediate" "0")])
1465 (define_expand "movqi"
1466 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467 (match_operand:QI 1 "general_operand" ""))]
1469 "ix86_expand_move (QImode, operands); DONE;")
1471 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1472 ;; "push a byte". But actually we use pushl, which has the effect
1473 ;; of rounding the amount pushed up to a word.
1475 (define_insn "*pushqi2"
1476 [(set (match_operand:QI 0 "push_operand" "=X")
1477 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1480 [(set_attr "type" "push")
1481 (set_attr "mode" "SI")])
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485 [(set (match_operand:QI 0 "push_operand" "=X")
1486 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1489 [(set_attr "type" "push")
1490 (set_attr "mode" "DI")])
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there. Then we use movzx.
1502 (define_insn "*movqi_1"
1503 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1505 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1507 switch (get_attr_type (insn))
1510 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1511 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1513 if (get_attr_mode (insn) == MODE_SI)
1514 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1516 return "mov{b}\t{%1, %0|%0, %1}";
1520 (cond [(and (eq_attr "alternative" "5")
1521 (not (match_operand:QI 1 "aligned_operand" "")))
1522 (const_string "imovx")
1523 (ne (symbol_ref "optimize_size") (const_int 0))
1524 (const_string "imov")
1525 (and (eq_attr "alternative" "3")
1526 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1528 (eq (symbol_ref "TARGET_QIMODE_MATH")
1530 (const_string "imov")
1531 (eq_attr "alternative" "3,5")
1532 (const_string "imovx")
1533 (and (ne (symbol_ref "TARGET_MOVX")
1535 (eq_attr "alternative" "2"))
1536 (const_string "imovx")
1538 (const_string "imov")))
1540 (cond [(eq_attr "alternative" "3,4,5")
1542 (eq_attr "alternative" "6")
1544 (eq_attr "type" "imovx")
1546 (and (eq_attr "type" "imov")
1547 (and (eq_attr "alternative" "0,1")
1548 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1550 (and (eq (symbol_ref "optimize_size")
1552 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1555 ;; Avoid partial register stalls when not using QImode arithmetic
1556 (and (eq_attr "type" "imov")
1557 (and (eq_attr "alternative" "0,1")
1558 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1560 (eq (symbol_ref "TARGET_QIMODE_MATH")
1564 (const_string "QI")))])
1566 (define_expand "reload_outqi"
1567 [(parallel [(match_operand:QI 0 "" "=m")
1568 (match_operand:QI 1 "register_operand" "r")
1569 (match_operand:QI 2 "register_operand" "=&q")])]
1573 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1575 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1576 if (! q_regs_operand (op1, QImode))
1578 emit_insn (gen_movqi (op2, op1));
1581 emit_insn (gen_movqi (op0, op1));
1585 (define_insn "*swapqi_1"
1586 [(set (match_operand:QI 0 "register_operand" "+r")
1587 (match_operand:QI 1 "register_operand" "+r"))
1590 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1592 [(set_attr "type" "imov")
1593 (set_attr "mode" "SI")
1594 (set_attr "pent_pair" "np")
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "vector")])
1598 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1599 (define_insn "*swapqi_2"
1600 [(set (match_operand:QI 0 "register_operand" "+q")
1601 (match_operand:QI 1 "register_operand" "+q"))
1604 "TARGET_PARTIAL_REG_STALL"
1606 [(set_attr "type" "imov")
1607 (set_attr "mode" "QI")
1608 (set_attr "pent_pair" "np")
1609 (set_attr "athlon_decode" "vector")])
1611 (define_expand "movstrictqi"
1612 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1613 (match_operand:QI 1 "general_operand" ""))]
1614 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1616 /* Don't generate memory->memory moves, go through a register. */
1617 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1618 operands[1] = force_reg (QImode, operands[1]);
1621 (define_insn "*movstrictqi_1"
1622 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1623 (match_operand:QI 1 "general_operand" "*qn,m"))]
1624 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1625 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626 "mov{b}\t{%1, %0|%0, %1}"
1627 [(set_attr "type" "imov")
1628 (set_attr "mode" "QI")])
1630 (define_insn "*movstrictqi_xor"
1631 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1632 (match_operand:QI 1 "const0_operand" "i"))
1633 (clobber (reg:CC FLAGS_REG))]
1634 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1635 "xor{b}\t{%0, %0|%0, %0}"
1636 [(set_attr "type" "alu1")
1637 (set_attr "mode" "QI")
1638 (set_attr "length_immediate" "0")])
1640 (define_insn "*movsi_extv_1"
1641 [(set (match_operand:SI 0 "register_operand" "=R")
1642 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1646 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1647 [(set_attr "type" "imovx")
1648 (set_attr "mode" "SI")])
1650 (define_insn "*movhi_extv_1"
1651 [(set (match_operand:HI 0 "register_operand" "=R")
1652 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1656 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1657 [(set_attr "type" "imovx")
1658 (set_attr "mode" "SI")])
1660 (define_insn "*movqi_extv_1"
1661 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1662 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1667 switch (get_attr_type (insn))
1670 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1672 return "mov{b}\t{%h1, %0|%0, %h1}";
1676 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678 (ne (symbol_ref "TARGET_MOVX")
1680 (const_string "imovx")
1681 (const_string "imov")))
1683 (if_then_else (eq_attr "type" "imovx")
1685 (const_string "QI")))])
1687 (define_insn "*movqi_extv_1_rex64"
1688 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1689 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1694 switch (get_attr_type (insn))
1697 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1699 return "mov{b}\t{%h1, %0|%0, %h1}";
1703 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1704 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1705 (ne (symbol_ref "TARGET_MOVX")
1707 (const_string "imovx")
1708 (const_string "imov")))
1710 (if_then_else (eq_attr "type" "imovx")
1712 (const_string "QI")))])
1714 ;; Stores and loads of ax to arbitrary constant address.
1715 ;; We fake an second form of instruction to force reload to load address
1716 ;; into register when rax is not available
1717 (define_insn "*movabsqi_1_rex64"
1718 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1719 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1720 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1722 movabs{b}\t{%1, %P0|%P0, %1}
1723 mov{b}\t{%1, %a0|%a0, %1}"
1724 [(set_attr "type" "imov")
1725 (set_attr "modrm" "0,*")
1726 (set_attr "length_address" "8,0")
1727 (set_attr "length_immediate" "0,*")
1728 (set_attr "memory" "store")
1729 (set_attr "mode" "QI")])
1731 (define_insn "*movabsqi_2_rex64"
1732 [(set (match_operand:QI 0 "register_operand" "=a,r")
1733 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1734 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1736 movabs{b}\t{%P1, %0|%0, %P1}
1737 mov{b}\t{%a1, %0|%0, %a1}"
1738 [(set_attr "type" "imov")
1739 (set_attr "modrm" "0,*")
1740 (set_attr "length_address" "8,0")
1741 (set_attr "length_immediate" "0")
1742 (set_attr "memory" "load")
1743 (set_attr "mode" "QI")])
1745 (define_insn "*movdi_extzv_1"
1746 [(set (match_operand:DI 0 "register_operand" "=R")
1747 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1751 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1752 [(set_attr "type" "imovx")
1753 (set_attr "mode" "DI")])
1755 (define_insn "*movsi_extzv_1"
1756 [(set (match_operand:SI 0 "register_operand" "=R")
1757 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1761 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1762 [(set_attr "type" "imovx")
1763 (set_attr "mode" "SI")])
1765 (define_insn "*movqi_extzv_2"
1766 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1767 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1772 switch (get_attr_type (insn))
1775 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1777 return "mov{b}\t{%h1, %0|%0, %h1}";
1781 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1782 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1783 (ne (symbol_ref "TARGET_MOVX")
1785 (const_string "imovx")
1786 (const_string "imov")))
1788 (if_then_else (eq_attr "type" "imovx")
1790 (const_string "QI")))])
1792 (define_insn "*movqi_extzv_2_rex64"
1793 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1794 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1799 switch (get_attr_type (insn))
1802 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1804 return "mov{b}\t{%h1, %0|%0, %h1}";
1808 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1809 (ne (symbol_ref "TARGET_MOVX")
1811 (const_string "imovx")
1812 (const_string "imov")))
1814 (if_then_else (eq_attr "type" "imovx")
1816 (const_string "QI")))])
1818 (define_insn "movsi_insv_1"
1819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1822 (match_operand:SI 1 "general_operand" "Qmn"))]
1824 "mov{b}\t{%b1, %h0|%h0, %b1}"
1825 [(set_attr "type" "imov")
1826 (set_attr "mode" "QI")])
1828 (define_insn "*movsi_insv_1_rex64"
1829 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1832 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1834 "mov{b}\t{%b1, %h0|%h0, %b1}"
1835 [(set_attr "type" "imov")
1836 (set_attr "mode" "QI")])
1838 (define_insn "movdi_insv_1_rex64"
1839 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1842 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1844 "mov{b}\t{%b1, %h0|%h0, %b1}"
1845 [(set_attr "type" "imov")
1846 (set_attr "mode" "QI")])
1848 (define_insn "*movqi_insv_2"
1849 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1852 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1855 "mov{b}\t{%h1, %h0|%h0, %h1}"
1856 [(set_attr "type" "imov")
1857 (set_attr "mode" "QI")])
1859 (define_expand "movdi"
1860 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1861 (match_operand:DI 1 "general_operand" ""))]
1863 "ix86_expand_move (DImode, operands); DONE;")
1865 (define_insn "*pushdi"
1866 [(set (match_operand:DI 0 "push_operand" "=<")
1867 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1871 (define_insn "*pushdi2_rex64"
1872 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1873 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1878 [(set_attr "type" "push,multi")
1879 (set_attr "mode" "DI")])
1881 ;; Convert impossible pushes of immediate to existing instructions.
1882 ;; First try to get scratch register and go through it. In case this
1883 ;; fails, push sign extended lower part first and then overwrite
1884 ;; upper part by 32bit move.
1886 [(match_scratch:DI 2 "r")
1887 (set (match_operand:DI 0 "push_operand" "")
1888 (match_operand:DI 1 "immediate_operand" ""))]
1889 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890 && !x86_64_immediate_operand (operands[1], DImode)"
1891 [(set (match_dup 2) (match_dup 1))
1892 (set (match_dup 0) (match_dup 2))]
1895 ;; We need to define this as both peepholer and splitter for case
1896 ;; peephole2 pass is not run.
1897 ;; "&& 1" is needed to keep it from matching the previous pattern.
1899 [(set (match_operand:DI 0 "push_operand" "")
1900 (match_operand:DI 1 "immediate_operand" ""))]
1901 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1902 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1903 [(set (match_dup 0) (match_dup 1))
1904 (set (match_dup 2) (match_dup 3))]
1905 "split_di (operands + 1, 1, operands + 2, operands + 3);
1906 operands[1] = gen_lowpart (DImode, operands[2]);
1907 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1912 [(set (match_operand:DI 0 "push_operand" "")
1913 (match_operand:DI 1 "immediate_operand" ""))]
1914 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1915 ? flow2_completed : reload_completed)
1916 && !symbolic_operand (operands[1], DImode)
1917 && !x86_64_immediate_operand (operands[1], DImode)"
1918 [(set (match_dup 0) (match_dup 1))
1919 (set (match_dup 2) (match_dup 3))]
1920 "split_di (operands + 1, 1, operands + 2, operands + 3);
1921 operands[1] = gen_lowpart (DImode, operands[2]);
1922 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1926 (define_insn "*pushdi2_prologue_rex64"
1927 [(set (match_operand:DI 0 "push_operand" "=<")
1928 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1929 (clobber (mem:BLK (scratch)))]
1932 [(set_attr "type" "push")
1933 (set_attr "mode" "DI")])
1935 (define_insn "*popdi1_epilogue_rex64"
1936 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1937 (mem:DI (reg:DI SP_REG)))
1938 (set (reg:DI SP_REG)
1939 (plus:DI (reg:DI SP_REG) (const_int 8)))
1940 (clobber (mem:BLK (scratch)))]
1943 [(set_attr "type" "pop")
1944 (set_attr "mode" "DI")])
1946 (define_insn "popdi1"
1947 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1948 (mem:DI (reg:DI SP_REG)))
1949 (set (reg:DI SP_REG)
1950 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1953 [(set_attr "type" "pop")
1954 (set_attr "mode" "DI")])
1956 (define_insn "*movdi_xor_rex64"
1957 [(set (match_operand:DI 0 "register_operand" "=r")
1958 (match_operand:DI 1 "const0_operand" "i"))
1959 (clobber (reg:CC FLAGS_REG))]
1960 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1961 && reload_completed"
1962 "xor{l}\t{%k0, %k0|%k0, %k0}"
1963 [(set_attr "type" "alu1")
1964 (set_attr "mode" "SI")
1965 (set_attr "length_immediate" "0")])
1967 (define_insn "*movdi_or_rex64"
1968 [(set (match_operand:DI 0 "register_operand" "=r")
1969 (match_operand:DI 1 "const_int_operand" "i"))
1970 (clobber (reg:CC FLAGS_REG))]
1971 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1973 && operands[1] == constm1_rtx"
1975 operands[1] = constm1_rtx;
1976 return "or{q}\t{%1, %0|%0, %1}";
1978 [(set_attr "type" "alu1")
1979 (set_attr "mode" "DI")
1980 (set_attr "length_immediate" "1")])
1982 (define_insn "*movdi_2"
1983 [(set (match_operand:DI 0 "nonimmediate_operand"
1984 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
1985 (match_operand:DI 1 "general_operand"
1986 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
1987 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 movq\t{%1, %0|%0, %1}
1993 movq\t{%1, %0|%0, %1}
1995 movq\t{%1, %0|%0, %1}
1996 movdqa\t{%1, %0|%0, %1}
1997 movq\t{%1, %0|%0, %1}
1999 movlps\t{%1, %0|%0, %1}
2000 movaps\t{%1, %0|%0, %1}
2001 movlps\t{%1, %0|%0, %1}"
2002 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2006 [(set (match_operand:DI 0 "push_operand" "")
2007 (match_operand:DI 1 "general_operand" ""))]
2008 "!TARGET_64BIT && reload_completed
2009 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2011 "ix86_split_long_move (operands); DONE;")
2013 ;; %%% This multiword shite has got to go.
2015 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016 (match_operand:DI 1 "general_operand" ""))]
2017 "!TARGET_64BIT && reload_completed
2018 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2021 "ix86_split_long_move (operands); DONE;")
2023 (define_insn "*movdi_1_rex64"
2024 [(set (match_operand:DI 0 "nonimmediate_operand"
2025 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2026 (match_operand:DI 1 "general_operand"
2027 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2028 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2030 switch (get_attr_type (insn))
2033 if (SSE_REG_P (operands[0]))
2034 return "movq2dq\t{%1, %0|%0, %1}";
2036 return "movdq2q\t{%1, %0|%0, %1}";
2039 if (get_attr_mode (insn) == MODE_TI)
2040 return "movdqa\t{%1, %0|%0, %1}";
2044 /* Moves from and into integer register is done using movd
2045 opcode with REX prefix. */
2046 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2047 return "movd\t{%1, %0|%0, %1}";
2048 return "movq\t{%1, %0|%0, %1}";
2052 return "pxor\t%0, %0";
2058 return "lea{q}\t{%a1, %0|%0, %a1}";
2061 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2062 if (get_attr_mode (insn) == MODE_SI)
2063 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2064 else if (which_alternative == 2)
2065 return "movabs{q}\t{%1, %0|%0, %1}";
2067 return "mov{q}\t{%1, %0|%0, %1}";
2071 (cond [(eq_attr "alternative" "5")
2072 (const_string "mmxadd")
2073 (eq_attr "alternative" "6,7,8,9,10")
2074 (const_string "mmxmov")
2075 (eq_attr "alternative" "11")
2076 (const_string "sselog1")
2077 (eq_attr "alternative" "12,13,14,15,16")
2078 (const_string "ssemov")
2079 (eq_attr "alternative" "17,18")
2080 (const_string "ssecvt")
2081 (eq_attr "alternative" "4")
2082 (const_string "multi")
2083 (match_operand:DI 1 "pic_32bit_operand" "")
2084 (const_string "lea")
2086 (const_string "imov")))
2087 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2088 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2091 ;; Stores and loads of ax to arbitrary constant address.
2092 ;; We fake an second form of instruction to force reload to load address
2093 ;; into register when rax is not available
2094 (define_insn "*movabsdi_1_rex64"
2095 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2096 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2097 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2099 movabs{q}\t{%1, %P0|%P0, %1}
2100 mov{q}\t{%1, %a0|%a0, %1}"
2101 [(set_attr "type" "imov")
2102 (set_attr "modrm" "0,*")
2103 (set_attr "length_address" "8,0")
2104 (set_attr "length_immediate" "0,*")
2105 (set_attr "memory" "store")
2106 (set_attr "mode" "DI")])
2108 (define_insn "*movabsdi_2_rex64"
2109 [(set (match_operand:DI 0 "register_operand" "=a,r")
2110 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2111 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2113 movabs{q}\t{%P1, %0|%0, %P1}
2114 mov{q}\t{%a1, %0|%0, %a1}"
2115 [(set_attr "type" "imov")
2116 (set_attr "modrm" "0,*")
2117 (set_attr "length_address" "8,0")
2118 (set_attr "length_immediate" "0")
2119 (set_attr "memory" "load")
2120 (set_attr "mode" "DI")])
2122 ;; Convert impossible stores of immediate to existing instructions.
2123 ;; First try to get scratch register and go through it. In case this
2124 ;; fails, move by 32bit parts.
2126 [(match_scratch:DI 2 "r")
2127 (set (match_operand:DI 0 "memory_operand" "")
2128 (match_operand:DI 1 "immediate_operand" ""))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode)"
2131 [(set (match_dup 2) (match_dup 1))
2132 (set (match_dup 0) (match_dup 2))]
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2139 [(set (match_operand:DI 0 "memory_operand" "")
2140 (match_operand:DI 1 "immediate_operand" ""))]
2141 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143 [(set (match_dup 2) (match_dup 3))
2144 (set (match_dup 4) (match_dup 5))]
2145 "split_di (operands, 2, operands + 2, operands + 4);")
2148 [(set (match_operand:DI 0 "memory_operand" "")
2149 (match_operand:DI 1 "immediate_operand" ""))]
2150 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151 ? flow2_completed : reload_completed)
2152 && !symbolic_operand (operands[1], DImode)
2153 && !x86_64_immediate_operand (operands[1], DImode)"
2154 [(set (match_dup 2) (match_dup 3))
2155 (set (match_dup 4) (match_dup 5))]
2156 "split_di (operands, 2, operands + 2, operands + 4);")
2158 (define_insn "*swapdi_rex64"
2159 [(set (match_operand:DI 0 "register_operand" "+r")
2160 (match_operand:DI 1 "register_operand" "+r"))
2165 [(set_attr "type" "imov")
2166 (set_attr "mode" "DI")
2167 (set_attr "pent_pair" "np")
2168 (set_attr "athlon_decode" "vector")
2169 (set_attr "amdfam10_decode" "double")])
2171 (define_expand "movti"
2172 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2173 (match_operand:TI 1 "nonimmediate_operand" ""))]
2174 "TARGET_SSE || TARGET_64BIT"
2177 ix86_expand_move (TImode, operands);
2179 ix86_expand_vector_move (TImode, operands);
2183 (define_insn "*movti_internal"
2184 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2185 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2186 "TARGET_SSE && !TARGET_64BIT
2187 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 switch (which_alternative)
2192 if (get_attr_mode (insn) == MODE_V4SF)
2193 return "xorps\t%0, %0";
2195 return "pxor\t%0, %0";
2198 if (get_attr_mode (insn) == MODE_V4SF)
2199 return "movaps\t{%1, %0|%0, %1}";
2201 return "movdqa\t{%1, %0|%0, %1}";
2206 [(set_attr "type" "sselog1,ssemov,ssemov")
2208 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2209 (ne (symbol_ref "optimize_size") (const_int 0)))
2210 (const_string "V4SF")
2211 (and (eq_attr "alternative" "2")
2212 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2214 (const_string "V4SF")]
2215 (const_string "TI")))])
2217 (define_insn "*movti_rex64"
2218 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2219 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2221 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2223 switch (which_alternative)
2229 if (get_attr_mode (insn) == MODE_V4SF)
2230 return "xorps\t%0, %0";
2232 return "pxor\t%0, %0";
2235 if (get_attr_mode (insn) == MODE_V4SF)
2236 return "movaps\t{%1, %0|%0, %1}";
2238 return "movdqa\t{%1, %0|%0, %1}";
2243 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2245 (cond [(eq_attr "alternative" "2,3")
2247 (ne (symbol_ref "optimize_size")
2249 (const_string "V4SF")
2250 (const_string "TI"))
2251 (eq_attr "alternative" "4")
2253 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2255 (ne (symbol_ref "optimize_size")
2257 (const_string "V4SF")
2258 (const_string "TI"))]
2259 (const_string "DI")))])
2262 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2263 (match_operand:TI 1 "general_operand" ""))]
2264 "reload_completed && !SSE_REG_P (operands[0])
2265 && !SSE_REG_P (operands[1])"
2267 "ix86_split_long_move (operands); DONE;")
2269 (define_expand "movsf"
2270 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2271 (match_operand:SF 1 "general_operand" ""))]
2273 "ix86_expand_move (SFmode, operands); DONE;")
2275 (define_insn "*pushsf"
2276 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2277 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2280 /* Anything else should be already split before reg-stack. */
2281 gcc_assert (which_alternative == 1);
2282 return "push{l}\t%1";
2284 [(set_attr "type" "multi,push,multi")
2285 (set_attr "unit" "i387,*,*")
2286 (set_attr "mode" "SF,SI,SF")])
2288 (define_insn "*pushsf_rex64"
2289 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2290 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2293 /* Anything else should be already split before reg-stack. */
2294 gcc_assert (which_alternative == 1);
2295 return "push{q}\t%q1";
2297 [(set_attr "type" "multi,push,multi")
2298 (set_attr "unit" "i387,*,*")
2299 (set_attr "mode" "SF,DI,SF")])
2302 [(set (match_operand:SF 0 "push_operand" "")
2303 (match_operand:SF 1 "memory_operand" ""))]
2305 && MEM_P (operands[1])
2306 && constant_pool_reference_p (operands[1])"
2309 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2312 ;; %%% Kill this when call knows how to work this out.
2314 [(set (match_operand:SF 0 "push_operand" "")
2315 (match_operand:SF 1 "any_fp_register_operand" ""))]
2317 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2318 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2321 [(set (match_operand:SF 0 "push_operand" "")
2322 (match_operand:SF 1 "any_fp_register_operand" ""))]
2324 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2325 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2327 (define_insn "*movsf_1"
2328 [(set (match_operand:SF 0 "nonimmediate_operand"
2329 "=f,m,f,r ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r ")
2330 (match_operand:SF 1 "general_operand"
2331 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r ,*Ym"))]
2332 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2333 && (reload_in_progress || reload_completed
2334 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2335 || (!TARGET_SSE_MATH && optimize_size
2336 && standard_80387_constant_p (operands[1]))
2337 || GET_CODE (operands[1]) != CONST_DOUBLE
2338 || memory_operand (operands[0], SFmode))"
2340 switch (which_alternative)
2343 return output_387_reg_move (insn, operands);
2346 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2347 return "fstp%z0\t%y0";
2349 return "fst%z0\t%y0";
2352 return standard_80387_constant_opcode (operands[1]);
2356 return "mov{l}\t{%1, %0|%0, %1}";
2358 if (get_attr_mode (insn) == MODE_TI)
2359 return "pxor\t%0, %0";
2361 return "xorps\t%0, %0";
2363 if (get_attr_mode (insn) == MODE_V4SF)
2364 return "movaps\t{%1, %0|%0, %1}";
2366 return "movss\t{%1, %0|%0, %1}";
2368 return "movss\t{%1, %0|%0, %1}";
2371 case 12: case 13: case 14: case 15:
2372 return "movd\t{%1, %0|%0, %1}";
2375 return "movq\t{%1, %0|%0, %1}";
2381 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2383 (cond [(eq_attr "alternative" "3,4,9,10")
2385 (eq_attr "alternative" "5")
2387 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2389 (ne (symbol_ref "TARGET_SSE2")
2391 (eq (symbol_ref "optimize_size")
2394 (const_string "V4SF"))
2395 /* For architectures resolving dependencies on
2396 whole SSE registers use APS move to break dependency
2397 chains, otherwise use short move to avoid extra work.
2399 Do the same for architectures resolving dependencies on
2400 the parts. While in DF mode it is better to always handle
2401 just register parts, the SF mode is different due to lack
2402 of instructions to load just part of the register. It is
2403 better to maintain the whole registers in single format
2404 to avoid problems on using packed logical operations. */
2405 (eq_attr "alternative" "6")
2407 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2409 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2411 (const_string "V4SF")
2412 (const_string "SF"))
2413 (eq_attr "alternative" "11")
2414 (const_string "DI")]
2415 (const_string "SF")))])
2417 (define_insn "*swapsf"
2418 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2419 (match_operand:SF 1 "fp_register_operand" "+f"))
2422 "reload_completed || TARGET_80387"
2424 if (STACK_TOP_P (operands[0]))
2429 [(set_attr "type" "fxch")
2430 (set_attr "mode" "SF")])
2432 (define_expand "movdf"
2433 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2434 (match_operand:DF 1 "general_operand" ""))]
2436 "ix86_expand_move (DFmode, operands); DONE;")
2438 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2439 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2440 ;; On the average, pushdf using integers can be still shorter. Allow this
2441 ;; pattern for optimize_size too.
2443 (define_insn "*pushdf_nointeger"
2444 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2445 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2446 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2448 /* This insn should be already split before reg-stack. */
2451 [(set_attr "type" "multi")
2452 (set_attr "unit" "i387,*,*,*")
2453 (set_attr "mode" "DF,SI,SI,DF")])
2455 (define_insn "*pushdf_integer"
2456 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2457 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2458 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2460 /* This insn should be already split before reg-stack. */
2463 [(set_attr "type" "multi")
2464 (set_attr "unit" "i387,*,*")
2465 (set_attr "mode" "DF,SI,DF")])
2467 ;; %%% Kill this when call knows how to work this out.
2469 [(set (match_operand:DF 0 "push_operand" "")
2470 (match_operand:DF 1 "any_fp_register_operand" ""))]
2471 "!TARGET_64BIT && reload_completed"
2472 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2473 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2477 [(set (match_operand:DF 0 "push_operand" "")
2478 (match_operand:DF 1 "any_fp_register_operand" ""))]
2479 "TARGET_64BIT && reload_completed"
2480 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2481 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2485 [(set (match_operand:DF 0 "push_operand" "")
2486 (match_operand:DF 1 "general_operand" ""))]
2489 "ix86_split_long_move (operands); DONE;")
2491 ;; Moving is usually shorter when only FP registers are used. This separate
2492 ;; movdf pattern avoids the use of integer registers for FP operations
2493 ;; when optimizing for size.
2495 (define_insn "*movdf_nointeger"
2496 [(set (match_operand:DF 0 "nonimmediate_operand"
2497 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2498 (match_operand:DF 1 "general_operand"
2499 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2500 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2501 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2502 && (reload_in_progress || reload_completed
2503 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2504 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2505 && standard_80387_constant_p (operands[1]))
2506 || GET_CODE (operands[1]) != CONST_DOUBLE
2507 || memory_operand (operands[0], DFmode))"
2509 switch (which_alternative)
2512 return output_387_reg_move (insn, operands);
2515 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2516 return "fstp%z0\t%y0";
2518 return "fst%z0\t%y0";
2521 return standard_80387_constant_opcode (operands[1]);
2527 switch (get_attr_mode (insn))
2530 return "xorps\t%0, %0";
2532 return "xorpd\t%0, %0";
2534 return "pxor\t%0, %0";
2541 switch (get_attr_mode (insn))
2544 return "movaps\t{%1, %0|%0, %1}";
2546 return "movapd\t{%1, %0|%0, %1}";
2548 return "movdqa\t{%1, %0|%0, %1}";
2550 return "movq\t{%1, %0|%0, %1}";
2552 return "movsd\t{%1, %0|%0, %1}";
2554 return "movlpd\t{%1, %0|%0, %1}";
2556 return "movlps\t{%1, %0|%0, %1}";
2565 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2567 (cond [(eq_attr "alternative" "0,1,2")
2569 (eq_attr "alternative" "3,4")
2572 /* For SSE1, we have many fewer alternatives. */
2573 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2574 (cond [(eq_attr "alternative" "5,6")
2575 (const_string "V4SF")
2577 (const_string "V2SF"))
2579 /* xorps is one byte shorter. */
2580 (eq_attr "alternative" "5")
2581 (cond [(ne (symbol_ref "optimize_size")
2583 (const_string "V4SF")
2584 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2588 (const_string "V2DF"))
2590 /* For architectures resolving dependencies on
2591 whole SSE registers use APD move to break dependency
2592 chains, otherwise use short move to avoid extra work.
2594 movaps encodes one byte shorter. */
2595 (eq_attr "alternative" "6")
2597 [(ne (symbol_ref "optimize_size")
2599 (const_string "V4SF")
2600 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2602 (const_string "V2DF")
2604 (const_string "DF"))
2605 /* For architectures resolving dependencies on register
2606 parts we may avoid extra work to zero out upper part
2608 (eq_attr "alternative" "7")
2610 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2612 (const_string "V1DF")
2613 (const_string "DF"))
2615 (const_string "DF")))])
2617 (define_insn "*movdf_integer_rex64"
2618 [(set (match_operand:DF 0 "nonimmediate_operand"
2619 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2620 (match_operand:DF 1 "general_operand"
2621 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2622 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2623 && (reload_in_progress || reload_completed
2624 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2625 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2626 && standard_80387_constant_p (operands[1]))
2627 || GET_CODE (operands[1]) != CONST_DOUBLE
2628 || memory_operand (operands[0], DFmode))"
2630 switch (which_alternative)
2633 return output_387_reg_move (insn, operands);
2636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2637 return "fstp%z0\t%y0";
2639 return "fst%z0\t%y0";
2642 return standard_80387_constant_opcode (operands[1]);
2649 switch (get_attr_mode (insn))
2652 return "xorps\t%0, %0";
2654 return "xorpd\t%0, %0";
2656 return "pxor\t%0, %0";
2663 switch (get_attr_mode (insn))
2666 return "movaps\t{%1, %0|%0, %1}";
2668 return "movapd\t{%1, %0|%0, %1}";
2670 return "movdqa\t{%1, %0|%0, %1}";
2672 return "movq\t{%1, %0|%0, %1}";
2674 return "movsd\t{%1, %0|%0, %1}";
2676 return "movlpd\t{%1, %0|%0, %1}";
2678 return "movlps\t{%1, %0|%0, %1}";
2685 return "movd\t{%1, %0|%0, %1}";
2691 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2693 (cond [(eq_attr "alternative" "0,1,2")
2695 (eq_attr "alternative" "3,4,9,10")
2698 /* For SSE1, we have many fewer alternatives. */
2699 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700 (cond [(eq_attr "alternative" "5,6")
2701 (const_string "V4SF")
2703 (const_string "V2SF"))
2705 /* xorps is one byte shorter. */
2706 (eq_attr "alternative" "5")
2707 (cond [(ne (symbol_ref "optimize_size")
2709 (const_string "V4SF")
2710 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2714 (const_string "V2DF"))
2716 /* For architectures resolving dependencies on
2717 whole SSE registers use APD move to break dependency
2718 chains, otherwise use short move to avoid extra work.
2720 movaps encodes one byte shorter. */
2721 (eq_attr "alternative" "6")
2723 [(ne (symbol_ref "optimize_size")
2725 (const_string "V4SF")
2726 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2728 (const_string "V2DF")
2730 (const_string "DF"))
2731 /* For architectures resolving dependencies on register
2732 parts we may avoid extra work to zero out upper part
2734 (eq_attr "alternative" "7")
2736 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2738 (const_string "V1DF")
2739 (const_string "DF"))
2741 (const_string "DF")))])
2743 (define_insn "*movdf_integer"
2744 [(set (match_operand:DF 0 "nonimmediate_operand"
2745 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2746 (match_operand:DF 1 "general_operand"
2747 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2748 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2749 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2750 && (reload_in_progress || reload_completed
2751 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2752 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2753 && standard_80387_constant_p (operands[1]))
2754 || GET_CODE (operands[1]) != CONST_DOUBLE
2755 || memory_operand (operands[0], DFmode))"
2757 switch (which_alternative)
2760 return output_387_reg_move (insn, operands);
2763 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764 return "fstp%z0\t%y0";
2766 return "fst%z0\t%y0";
2769 return standard_80387_constant_opcode (operands[1]);
2776 switch (get_attr_mode (insn))
2779 return "xorps\t%0, %0";
2781 return "xorpd\t%0, %0";
2783 return "pxor\t%0, %0";
2790 switch (get_attr_mode (insn))
2793 return "movaps\t{%1, %0|%0, %1}";
2795 return "movapd\t{%1, %0|%0, %1}";
2797 return "movdqa\t{%1, %0|%0, %1}";
2799 return "movq\t{%1, %0|%0, %1}";
2801 return "movsd\t{%1, %0|%0, %1}";
2803 return "movlpd\t{%1, %0|%0, %1}";
2805 return "movlps\t{%1, %0|%0, %1}";
2814 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2816 (cond [(eq_attr "alternative" "0,1,2")
2818 (eq_attr "alternative" "3,4")
2821 /* For SSE1, we have many fewer alternatives. */
2822 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2823 (cond [(eq_attr "alternative" "5,6")
2824 (const_string "V4SF")
2826 (const_string "V2SF"))
2828 /* xorps is one byte shorter. */
2829 (eq_attr "alternative" "5")
2830 (cond [(ne (symbol_ref "optimize_size")
2832 (const_string "V4SF")
2833 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2837 (const_string "V2DF"))
2839 /* For architectures resolving dependencies on
2840 whole SSE registers use APD move to break dependency
2841 chains, otherwise use short move to avoid extra work.
2843 movaps encodes one byte shorter. */
2844 (eq_attr "alternative" "6")
2846 [(ne (symbol_ref "optimize_size")
2848 (const_string "V4SF")
2849 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2851 (const_string "V2DF")
2853 (const_string "DF"))
2854 /* For architectures resolving dependencies on register
2855 parts we may avoid extra work to zero out upper part
2857 (eq_attr "alternative" "7")
2859 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2861 (const_string "V1DF")
2862 (const_string "DF"))
2864 (const_string "DF")))])
2867 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2868 (match_operand:DF 1 "general_operand" ""))]
2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && ! (ANY_FP_REG_P (operands[0]) ||
2872 (GET_CODE (operands[0]) == SUBREG
2873 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874 && ! (ANY_FP_REG_P (operands[1]) ||
2875 (GET_CODE (operands[1]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2878 "ix86_split_long_move (operands); DONE;")
2880 (define_insn "*swapdf"
2881 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2882 (match_operand:DF 1 "fp_register_operand" "+f"))
2885 "reload_completed || TARGET_80387"
2887 if (STACK_TOP_P (operands[0]))
2892 [(set_attr "type" "fxch")
2893 (set_attr "mode" "DF")])
2895 (define_expand "movxf"
2896 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2897 (match_operand:XF 1 "general_operand" ""))]
2899 "ix86_expand_move (XFmode, operands); DONE;")
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2903 ;; Pushing using integer instructions is longer except for constants
2904 ;; and direct memory references.
2905 ;; (assuming that any given constant is pushed only once, but this ought to be
2906 ;; handled elsewhere).
2908 (define_insn "*pushxf_nointeger"
2909 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2910 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2913 /* This insn should be already split before reg-stack. */
2916 [(set_attr "type" "multi")
2917 (set_attr "unit" "i387,*,*")
2918 (set_attr "mode" "XF,SI,SI")])
2920 (define_insn "*pushxf_integer"
2921 [(set (match_operand:XF 0 "push_operand" "=<,<")
2922 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2925 /* This insn should be already split before reg-stack. */
2928 [(set_attr "type" "multi")
2929 (set_attr "unit" "i387,*")
2930 (set_attr "mode" "XF,SI")])
2933 [(set (match_operand 0 "push_operand" "")
2934 (match_operand 1 "general_operand" ""))]
2936 && (GET_MODE (operands[0]) == XFmode
2937 || GET_MODE (operands[0]) == DFmode)
2938 && !ANY_FP_REG_P (operands[1])"
2940 "ix86_split_long_move (operands); DONE;")
2943 [(set (match_operand:XF 0 "push_operand" "")
2944 (match_operand:XF 1 "any_fp_register_operand" ""))]
2946 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2947 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2948 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2951 [(set (match_operand:XF 0 "push_operand" "")
2952 (match_operand:XF 1 "any_fp_register_operand" ""))]
2954 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2955 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2956 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2958 ;; Do not use integer registers when optimizing for size
2959 (define_insn "*movxf_nointeger"
2960 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2961 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2963 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2964 && (reload_in_progress || reload_completed
2965 || (optimize_size && standard_80387_constant_p (operands[1]))
2966 || GET_CODE (operands[1]) != CONST_DOUBLE
2967 || memory_operand (operands[0], XFmode))"
2969 switch (which_alternative)
2972 return output_387_reg_move (insn, operands);
2975 /* There is no non-popping store to memory for XFmode. So if
2976 we need one, follow the store with a load. */
2977 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2978 return "fstp%z0\t%y0\;fld%z0\t%y0";
2980 return "fstp%z0\t%y0";
2983 return standard_80387_constant_opcode (operands[1]);
2991 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2992 (set_attr "mode" "XF,XF,XF,SI,SI")])
2994 (define_insn "*movxf_integer"
2995 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2996 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2998 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2999 && (reload_in_progress || reload_completed
3000 || (optimize_size && standard_80387_constant_p (operands[1]))
3001 || GET_CODE (operands[1]) != CONST_DOUBLE
3002 || memory_operand (operands[0], XFmode))"
3004 switch (which_alternative)
3007 return output_387_reg_move (insn, operands);
3010 /* There is no non-popping store to memory for XFmode. So if
3011 we need one, follow the store with a load. */
3012 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013 return "fstp%z0\t%y0\;fld%z0\t%y0";
3015 return "fstp%z0\t%y0";
3018 return standard_80387_constant_opcode (operands[1]);
3027 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3028 (set_attr "mode" "XF,XF,XF,SI,SI")])
3031 [(set (match_operand 0 "nonimmediate_operand" "")
3032 (match_operand 1 "general_operand" ""))]
3034 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3035 && GET_MODE (operands[0]) == XFmode
3036 && ! (ANY_FP_REG_P (operands[0]) ||
3037 (GET_CODE (operands[0]) == SUBREG
3038 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039 && ! (ANY_FP_REG_P (operands[1]) ||
3040 (GET_CODE (operands[1]) == SUBREG
3041 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3043 "ix86_split_long_move (operands); DONE;")
3046 [(set (match_operand 0 "register_operand" "")
3047 (match_operand 1 "memory_operand" ""))]
3049 && MEM_P (operands[1])
3050 && (GET_MODE (operands[0]) == XFmode
3051 || GET_MODE (operands[0]) == SFmode
3052 || GET_MODE (operands[0]) == DFmode)
3053 && constant_pool_reference_p (operands[1])"
3054 [(set (match_dup 0) (match_dup 1))]
3056 rtx c = avoid_constant_pool_reference (operands[1]);
3057 rtx r = operands[0];
3059 if (GET_CODE (r) == SUBREG)
3064 if (!standard_sse_constant_p (c))
3067 else if (FP_REG_P (r))
3069 if (!standard_80387_constant_p (c))
3072 else if (MMX_REG_P (r))
3079 [(set (match_operand 0 "register_operand" "")
3080 (float_extend (match_operand 1 "memory_operand" "")))]
3082 && MEM_P (operands[1])
3083 && (GET_MODE (operands[0]) == XFmode
3084 || GET_MODE (operands[0]) == SFmode
3085 || GET_MODE (operands[0]) == DFmode)
3086 && constant_pool_reference_p (operands[1])"
3087 [(set (match_dup 0) (match_dup 1))]
3089 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3090 rtx r = operands[0];
3092 if (GET_CODE (r) == SUBREG)
3097 if (!standard_sse_constant_p (c))
3100 else if (FP_REG_P (r))
3102 if (!standard_80387_constant_p (c))
3105 else if (MMX_REG_P (r))
3111 (define_insn "swapxf"
3112 [(set (match_operand:XF 0 "register_operand" "+f")
3113 (match_operand:XF 1 "register_operand" "+f"))
3118 if (STACK_TOP_P (operands[0]))
3123 [(set_attr "type" "fxch")
3124 (set_attr "mode" "XF")])
3126 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3128 [(set (match_operand:X87MODEF 0 "register_operand" "")
3129 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3130 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3131 && (standard_80387_constant_p (operands[1]) == 8
3132 || standard_80387_constant_p (operands[1]) == 9)"
3133 [(set (match_dup 0)(match_dup 1))
3135 (neg:X87MODEF (match_dup 0)))]
3139 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3140 if (real_isnegzero (&r))
3141 operands[1] = CONST0_RTX (<MODE>mode);
3143 operands[1] = CONST1_RTX (<MODE>mode);
3146 (define_expand "movtf"
3147 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3148 (match_operand:TF 1 "nonimmediate_operand" ""))]
3151 ix86_expand_move (TFmode, operands);
3155 (define_insn "*movtf_internal"
3156 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3157 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3159 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3161 switch (which_alternative)
3167 if (get_attr_mode (insn) == MODE_V4SF)
3168 return "xorps\t%0, %0";
3170 return "pxor\t%0, %0";
3173 if (get_attr_mode (insn) == MODE_V4SF)
3174 return "movaps\t{%1, %0|%0, %1}";
3176 return "movdqa\t{%1, %0|%0, %1}";
3181 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3183 (cond [(eq_attr "alternative" "2,3")
3185 (ne (symbol_ref "optimize_size")
3187 (const_string "V4SF")
3188 (const_string "TI"))
3189 (eq_attr "alternative" "4")
3191 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3193 (ne (symbol_ref "optimize_size")
3195 (const_string "V4SF")
3196 (const_string "TI"))]
3197 (const_string "DI")))])
3200 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201 (match_operand:TF 1 "general_operand" ""))]
3202 "reload_completed && !SSE_REG_P (operands[0])
3203 && !SSE_REG_P (operands[1])"
3205 "ix86_split_long_move (operands); DONE;")
3207 ;; Zero extension instructions
3209 (define_expand "zero_extendhisi2"
3210 [(set (match_operand:SI 0 "register_operand" "")
3211 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3214 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3216 operands[1] = force_reg (HImode, operands[1]);
3217 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3222 (define_insn "zero_extendhisi2_and"
3223 [(set (match_operand:SI 0 "register_operand" "=r")
3224 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3225 (clobber (reg:CC FLAGS_REG))]
3226 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3228 [(set_attr "type" "alu1")
3229 (set_attr "mode" "SI")])
3232 [(set (match_operand:SI 0 "register_operand" "")
3233 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3234 (clobber (reg:CC FLAGS_REG))]
3235 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3236 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3237 (clobber (reg:CC FLAGS_REG))])]
3240 (define_insn "*zero_extendhisi2_movzwl"
3241 [(set (match_operand:SI 0 "register_operand" "=r")
3242 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3244 "movz{wl|x}\t{%1, %0|%0, %1}"
3245 [(set_attr "type" "imovx")
3246 (set_attr "mode" "SI")])
3248 (define_expand "zero_extendqihi2"
3250 [(set (match_operand:HI 0 "register_operand" "")
3251 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252 (clobber (reg:CC FLAGS_REG))])]
3256 (define_insn "*zero_extendqihi2_and"
3257 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3258 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3259 (clobber (reg:CC FLAGS_REG))]
3260 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3262 [(set_attr "type" "alu1")
3263 (set_attr "mode" "HI")])
3265 (define_insn "*zero_extendqihi2_movzbw_and"
3266 [(set (match_operand:HI 0 "register_operand" "=r,r")
3267 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3268 (clobber (reg:CC FLAGS_REG))]
3269 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3271 [(set_attr "type" "imovx,alu1")
3272 (set_attr "mode" "HI")])
3274 ; zero extend to SImode here to avoid partial register stalls
3275 (define_insn "*zero_extendqihi2_movzbl"
3276 [(set (match_operand:HI 0 "register_operand" "=r")
3277 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3279 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "SI")])
3283 ;; For the movzbw case strip only the clobber
3285 [(set (match_operand:HI 0 "register_operand" "")
3286 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3287 (clobber (reg:CC FLAGS_REG))]
3289 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3290 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3291 [(set (match_operand:HI 0 "register_operand" "")
3292 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3294 ;; When source and destination does not overlap, clear destination
3295 ;; first and then do the movb
3297 [(set (match_operand:HI 0 "register_operand" "")
3298 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3299 (clobber (reg:CC FLAGS_REG))]
3301 && ANY_QI_REG_P (operands[0])
3302 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3303 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3304 [(set (match_dup 0) (const_int 0))
3305 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3306 "operands[2] = gen_lowpart (QImode, operands[0]);")
3308 ;; Rest is handled by single and.
3310 [(set (match_operand:HI 0 "register_operand" "")
3311 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3312 (clobber (reg:CC FLAGS_REG))]
3314 && true_regnum (operands[0]) == true_regnum (operands[1])"
3315 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3316 (clobber (reg:CC FLAGS_REG))])]
3319 (define_expand "zero_extendqisi2"
3321 [(set (match_operand:SI 0 "register_operand" "")
3322 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3323 (clobber (reg:CC FLAGS_REG))])]
3327 (define_insn "*zero_extendqisi2_and"
3328 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3329 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3330 (clobber (reg:CC FLAGS_REG))]
3331 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3333 [(set_attr "type" "alu1")
3334 (set_attr "mode" "SI")])
3336 (define_insn "*zero_extendqisi2_movzbw_and"
3337 [(set (match_operand:SI 0 "register_operand" "=r,r")
3338 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3339 (clobber (reg:CC FLAGS_REG))]
3340 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3342 [(set_attr "type" "imovx,alu1")
3343 (set_attr "mode" "SI")])
3345 (define_insn "*zero_extendqisi2_movzbw"
3346 [(set (match_operand:SI 0 "register_operand" "=r")
3347 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3349 "movz{bl|x}\t{%1, %0|%0, %1}"
3350 [(set_attr "type" "imovx")
3351 (set_attr "mode" "SI")])
3353 ;; For the movzbl case strip only the clobber
3355 [(set (match_operand:SI 0 "register_operand" "")
3356 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3357 (clobber (reg:CC FLAGS_REG))]
3359 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3360 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3362 (zero_extend:SI (match_dup 1)))])
3364 ;; When source and destination does not overlap, clear destination
3365 ;; first and then do the movb
3367 [(set (match_operand:SI 0 "register_operand" "")
3368 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3369 (clobber (reg:CC FLAGS_REG))]
3371 && ANY_QI_REG_P (operands[0])
3372 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3373 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3375 [(set (match_dup 0) (const_int 0))
3376 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3377 "operands[2] = gen_lowpart (QImode, operands[0]);")
3379 ;; Rest is handled by single and.
3381 [(set (match_operand:SI 0 "register_operand" "")
3382 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3383 (clobber (reg:CC FLAGS_REG))]
3385 && true_regnum (operands[0]) == true_regnum (operands[1])"
3386 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3387 (clobber (reg:CC FLAGS_REG))])]
3390 ;; %%% Kill me once multi-word ops are sane.
3391 (define_expand "zero_extendsidi2"
3392 [(set (match_operand:DI 0 "register_operand" "=r")
3393 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3398 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3403 (define_insn "zero_extendsidi2_32"
3404 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3406 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3407 (clobber (reg:CC FLAGS_REG))]
3413 movd\t{%1, %0|%0, %1}
3414 movd\t{%1, %0|%0, %1}
3415 movd\t{%1, %0|%0, %1}
3416 movd\t{%1, %0|%0, %1}"
3417 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3418 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3420 (define_insn "zero_extendsidi2_rex64"
3421 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3423 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3426 mov\t{%k1, %k0|%k0, %k1}
3428 movd\t{%1, %0|%0, %1}
3429 movd\t{%1, %0|%0, %1}
3430 movd\t{%1, %0|%0, %1}
3431 movd\t{%1, %0|%0, %1}"
3432 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3433 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3436 [(set (match_operand:DI 0 "memory_operand" "")
3437 (zero_extend:DI (match_dup 0)))]
3439 [(set (match_dup 4) (const_int 0))]
3440 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3443 [(set (match_operand:DI 0 "register_operand" "")
3444 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3445 (clobber (reg:CC FLAGS_REG))]
3446 "!TARGET_64BIT && reload_completed
3447 && true_regnum (operands[0]) == true_regnum (operands[1])"
3448 [(set (match_dup 4) (const_int 0))]
3449 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3452 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3453 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3454 (clobber (reg:CC FLAGS_REG))]
3455 "!TARGET_64BIT && reload_completed
3456 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3457 [(set (match_dup 3) (match_dup 1))
3458 (set (match_dup 4) (const_int 0))]
3459 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3461 (define_insn "zero_extendhidi2"
3462 [(set (match_operand:DI 0 "register_operand" "=r")
3463 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3465 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3466 [(set_attr "type" "imovx")
3467 (set_attr "mode" "DI")])
3469 (define_insn "zero_extendqidi2"
3470 [(set (match_operand:DI 0 "register_operand" "=r")
3471 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3473 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3474 [(set_attr "type" "imovx")
3475 (set_attr "mode" "DI")])
3477 ;; Sign extension instructions
3479 (define_expand "extendsidi2"
3480 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3481 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3482 (clobber (reg:CC FLAGS_REG))
3483 (clobber (match_scratch:SI 2 ""))])]
3488 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3493 (define_insn "*extendsidi2_1"
3494 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496 (clobber (reg:CC FLAGS_REG))
3497 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3501 (define_insn "extendsidi2_rex64"
3502 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3503 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3507 movs{lq|x}\t{%1,%0|%0, %1}"
3508 [(set_attr "type" "imovx")
3509 (set_attr "mode" "DI")
3510 (set_attr "prefix_0f" "0")
3511 (set_attr "modrm" "0,1")])
3513 (define_insn "extendhidi2"
3514 [(set (match_operand:DI 0 "register_operand" "=r")
3515 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3517 "movs{wq|x}\t{%1,%0|%0, %1}"
3518 [(set_attr "type" "imovx")
3519 (set_attr "mode" "DI")])
3521 (define_insn "extendqidi2"
3522 [(set (match_operand:DI 0 "register_operand" "=r")
3523 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3525 "movs{bq|x}\t{%1,%0|%0, %1}"
3526 [(set_attr "type" "imovx")
3527 (set_attr "mode" "DI")])
3529 ;; Extend to memory case when source register does die.
3531 [(set (match_operand:DI 0 "memory_operand" "")
3532 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533 (clobber (reg:CC FLAGS_REG))
3534 (clobber (match_operand:SI 2 "register_operand" ""))]
3536 && dead_or_set_p (insn, operands[1])
3537 && !reg_mentioned_p (operands[1], operands[0]))"
3538 [(set (match_dup 3) (match_dup 1))
3539 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3540 (clobber (reg:CC FLAGS_REG))])
3541 (set (match_dup 4) (match_dup 1))]
3542 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3544 ;; Extend to memory case when source register does not die.
3546 [(set (match_operand:DI 0 "memory_operand" "")
3547 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3548 (clobber (reg:CC FLAGS_REG))
3549 (clobber (match_operand:SI 2 "register_operand" ""))]
3553 split_di (&operands[0], 1, &operands[3], &operands[4]);
3555 emit_move_insn (operands[3], operands[1]);
3557 /* Generate a cltd if possible and doing so it profitable. */
3558 if (true_regnum (operands[1]) == 0
3559 && true_regnum (operands[2]) == 1
3560 && (optimize_size || TARGET_USE_CLTD))
3562 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3566 emit_move_insn (operands[2], operands[1]);
3567 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3569 emit_move_insn (operands[4], operands[2]);
3573 ;; Extend to register case. Optimize case where source and destination
3574 ;; registers match and cases where we can use cltd.
3576 [(set (match_operand:DI 0 "register_operand" "")
3577 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3578 (clobber (reg:CC FLAGS_REG))
3579 (clobber (match_scratch:SI 2 ""))]
3583 split_di (&operands[0], 1, &operands[3], &operands[4]);
3585 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3586 emit_move_insn (operands[3], operands[1]);
3588 /* Generate a cltd if possible and doing so it profitable. */
3589 if (true_regnum (operands[3]) == 0
3590 && (optimize_size || TARGET_USE_CLTD))
3592 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3596 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3597 emit_move_insn (operands[4], operands[1]);
3599 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3603 (define_insn "extendhisi2"
3604 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3605 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3608 switch (get_attr_prefix_0f (insn))
3611 return "{cwtl|cwde}";
3613 return "movs{wl|x}\t{%1,%0|%0, %1}";
3616 [(set_attr "type" "imovx")
3617 (set_attr "mode" "SI")
3618 (set (attr "prefix_0f")
3619 ;; movsx is short decodable while cwtl is vector decoded.
3620 (if_then_else (and (eq_attr "cpu" "!k6")
3621 (eq_attr "alternative" "0"))
3623 (const_string "1")))
3625 (if_then_else (eq_attr "prefix_0f" "0")
3627 (const_string "1")))])
3629 (define_insn "*extendhisi2_zext"
3630 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3632 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3635 switch (get_attr_prefix_0f (insn))
3638 return "{cwtl|cwde}";
3640 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3643 [(set_attr "type" "imovx")
3644 (set_attr "mode" "SI")
3645 (set (attr "prefix_0f")
3646 ;; movsx is short decodable while cwtl is vector decoded.
3647 (if_then_else (and (eq_attr "cpu" "!k6")
3648 (eq_attr "alternative" "0"))
3650 (const_string "1")))
3652 (if_then_else (eq_attr "prefix_0f" "0")
3654 (const_string "1")))])
3656 (define_insn "extendqihi2"
3657 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3658 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3661 switch (get_attr_prefix_0f (insn))
3664 return "{cbtw|cbw}";
3666 return "movs{bw|x}\t{%1,%0|%0, %1}";
3669 [(set_attr "type" "imovx")
3670 (set_attr "mode" "HI")
3671 (set (attr "prefix_0f")
3672 ;; movsx is short decodable while cwtl is vector decoded.
3673 (if_then_else (and (eq_attr "cpu" "!k6")
3674 (eq_attr "alternative" "0"))
3676 (const_string "1")))
3678 (if_then_else (eq_attr "prefix_0f" "0")
3680 (const_string "1")))])
3682 (define_insn "extendqisi2"
3683 [(set (match_operand:SI 0 "register_operand" "=r")
3684 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3686 "movs{bl|x}\t{%1,%0|%0, %1}"
3687 [(set_attr "type" "imovx")
3688 (set_attr "mode" "SI")])
3690 (define_insn "*extendqisi2_zext"
3691 [(set (match_operand:DI 0 "register_operand" "=r")
3693 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3695 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3696 [(set_attr "type" "imovx")
3697 (set_attr "mode" "SI")])
3699 ;; Conversions between float and double.
3701 ;; These are all no-ops in the model used for the 80387. So just
3704 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3705 (define_insn "*dummy_extendsfdf2"
3706 [(set (match_operand:DF 0 "push_operand" "=<")
3707 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3712 [(set (match_operand:DF 0 "push_operand" "")
3713 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3715 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3716 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3719 [(set (match_operand:DF 0 "push_operand" "")
3720 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3722 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3723 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3725 (define_insn "*dummy_extendsfxf2"
3726 [(set (match_operand:XF 0 "push_operand" "=<")
3727 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3732 [(set (match_operand:XF 0 "push_operand" "")
3733 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3735 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3736 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3737 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3740 [(set (match_operand:XF 0 "push_operand" "")
3741 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3743 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3744 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3745 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3748 [(set (match_operand:XF 0 "push_operand" "")
3749 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3751 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3752 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3753 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3756 [(set (match_operand:XF 0 "push_operand" "")
3757 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3759 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3760 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3761 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3763 (define_expand "extendsfdf2"
3764 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3765 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3766 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3768 /* ??? Needed for compress_float_constant since all fp constants
3769 are LEGITIMATE_CONSTANT_P. */
3770 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3772 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3773 && standard_80387_constant_p (operands[1]) > 0)
3775 operands[1] = simplify_const_unary_operation
3776 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3777 emit_move_insn_1 (operands[0], operands[1]);
3780 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3784 (define_insn "*extendsfdf2_mixed"
3785 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3787 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3788 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3790 switch (which_alternative)
3793 return output_387_reg_move (insn, operands);
3796 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797 return "fstp%z0\t%y0";
3799 return "fst%z0\t%y0";
3802 return "cvtss2sd\t{%1, %0|%0, %1}";
3808 [(set_attr "type" "fmov,fmov,ssecvt")
3809 (set_attr "mode" "SF,XF,DF")])
3811 (define_insn "*extendsfdf2_sse"
3812 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3813 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3814 "TARGET_SSE2 && TARGET_SSE_MATH"
3815 "cvtss2sd\t{%1, %0|%0, %1}"
3816 [(set_attr "type" "ssecvt")
3817 (set_attr "mode" "DF")])
3819 (define_insn "*extendsfdf2_i387"
3820 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3821 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3824 switch (which_alternative)
3827 return output_387_reg_move (insn, operands);
3830 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3831 return "fstp%z0\t%y0";
3833 return "fst%z0\t%y0";
3839 [(set_attr "type" "fmov")
3840 (set_attr "mode" "SF,XF")])
3842 (define_expand "extendsfxf2"
3843 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3844 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3847 /* ??? Needed for compress_float_constant since all fp constants
3848 are LEGITIMATE_CONSTANT_P. */
3849 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3851 if (standard_80387_constant_p (operands[1]) > 0)
3853 operands[1] = simplify_const_unary_operation
3854 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3855 emit_move_insn_1 (operands[0], operands[1]);
3858 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3862 (define_insn "*extendsfxf2_i387"
3863 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3864 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3867 switch (which_alternative)
3870 return output_387_reg_move (insn, operands);
3873 /* There is no non-popping store to memory for XFmode. So if
3874 we need one, follow the store with a load. */
3875 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876 return "fstp%z0\t%y0";
3878 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3884 [(set_attr "type" "fmov")
3885 (set_attr "mode" "SF,XF")])
3887 (define_expand "extenddfxf2"
3888 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3889 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3892 /* ??? Needed for compress_float_constant since all fp constants
3893 are LEGITIMATE_CONSTANT_P. */
3894 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3896 if (standard_80387_constant_p (operands[1]) > 0)
3898 operands[1] = simplify_const_unary_operation
3899 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3900 emit_move_insn_1 (operands[0], operands[1]);
3903 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3907 (define_insn "*extenddfxf2_i387"
3908 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3909 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3912 switch (which_alternative)
3915 return output_387_reg_move (insn, operands);
3918 /* There is no non-popping store to memory for XFmode. So if
3919 we need one, follow the store with a load. */
3920 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3923 return "fstp%z0\t%y0";
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "DF,XF")])
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case. Otherwise this is just like a simple move
3935 ;; insn. So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3938 ;; Conversion from DFmode to SFmode.
3940 (define_expand "truncdfsf2"
3941 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3943 (match_operand:DF 1 "nonimmediate_operand" "")))]
3944 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3946 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3948 else if (flag_unsafe_math_optimizations)
3952 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3953 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3958 (define_expand "truncdfsf2_with_temp"
3959 [(parallel [(set (match_operand:SF 0 "" "")
3960 (float_truncate:SF (match_operand:DF 1 "" "")))
3961 (clobber (match_operand:SF 2 "" ""))])]
3964 (define_insn "*truncdfsf_fast_mixed"
3965 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3967 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3968 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3970 switch (which_alternative)
3973 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974 return "fstp%z0\t%y0";
3976 return "fst%z0\t%y0";
3978 return output_387_reg_move (insn, operands);
3980 return "cvtsd2ss\t{%1, %0|%0, %1}";
3985 [(set_attr "type" "fmov,fmov,ssecvt")
3986 (set_attr "mode" "SF")])
3988 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3989 ;; because nothing we do here is unsafe.
3990 (define_insn "*truncdfsf_fast_sse"
3991 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3993 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3994 "TARGET_SSE2 && TARGET_SSE_MATH"
3995 "cvtsd2ss\t{%1, %0|%0, %1}"
3996 [(set_attr "type" "ssecvt")
3997 (set_attr "mode" "SF")])
3999 (define_insn "*truncdfsf_fast_i387"
4000 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4002 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4003 "TARGET_80387 && flag_unsafe_math_optimizations"
4004 "* return output_387_reg_move (insn, operands);"
4005 [(set_attr "type" "fmov")
4006 (set_attr "mode" "SF")])
4008 (define_insn "*truncdfsf_mixed"
4009 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4011 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4012 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4013 "TARGET_MIX_SSE_I387"
4015 switch (which_alternative)
4018 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4019 return "fstp%z0\t%y0";
4021 return "fst%z0\t%y0";
4025 return "cvtsd2ss\t{%1, %0|%0, %1}";
4030 [(set_attr "type" "fmov,multi,ssecvt")
4031 (set_attr "unit" "*,i387,*")
4032 (set_attr "mode" "SF")])
4034 (define_insn "*truncdfsf_i387"
4035 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4037 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4038 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4041 switch (which_alternative)
4044 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045 return "fstp%z0\t%y0";
4047 return "fst%z0\t%y0";
4054 [(set_attr "type" "fmov,multi")
4055 (set_attr "unit" "*,i387")
4056 (set_attr "mode" "SF")])
4058 (define_insn "*truncdfsf2_i387_1"
4059 [(set (match_operand:SF 0 "memory_operand" "=m")
4061 (match_operand:DF 1 "register_operand" "f")))]
4063 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4064 && !TARGET_MIX_SSE_I387"
4066 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067 return "fstp%z0\t%y0";
4069 return "fst%z0\t%y0";
4071 [(set_attr "type" "fmov")
4072 (set_attr "mode" "SF")])
4075 [(set (match_operand:SF 0 "register_operand" "")
4077 (match_operand:DF 1 "fp_register_operand" "")))
4078 (clobber (match_operand 2 "" ""))]
4080 [(set (match_dup 2) (match_dup 1))
4081 (set (match_dup 0) (match_dup 2))]
4083 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4086 ;; Conversion from XFmode to SFmode.
4088 (define_expand "truncxfsf2"
4089 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4091 (match_operand:XF 1 "register_operand" "")))
4092 (clobber (match_dup 2))])]
4095 if (flag_unsafe_math_optimizations)
4097 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4098 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4099 if (reg != operands[0])
4100 emit_move_insn (operands[0], reg);
4104 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4107 (define_insn "*truncxfsf2_mixed"
4108 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4110 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4111 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4114 gcc_assert (!which_alternative);
4115 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4116 return "fstp%z0\t%y0";
4118 return "fst%z0\t%y0";
4120 [(set_attr "type" "fmov,multi,multi,multi")
4121 (set_attr "unit" "*,i387,i387,i387")
4122 (set_attr "mode" "SF")])
4124 (define_insn "truncxfsf2_i387_noop"
4125 [(set (match_operand:SF 0 "register_operand" "=f")
4126 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4127 "TARGET_80387 && flag_unsafe_math_optimizations"
4128 "* return output_387_reg_move (insn, operands);"
4129 [(set_attr "type" "fmov")
4130 (set_attr "mode" "SF")])
4132 (define_insn "*truncxfsf2_i387"
4133 [(set (match_operand:SF 0 "memory_operand" "=m")
4135 (match_operand:XF 1 "register_operand" "f")))]
4138 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139 return "fstp%z0\t%y0";
4141 return "fst%z0\t%y0";
4143 [(set_attr "type" "fmov")
4144 (set_attr "mode" "SF")])
4147 [(set (match_operand:SF 0 "register_operand" "")
4149 (match_operand:XF 1 "register_operand" "")))
4150 (clobber (match_operand:SF 2 "memory_operand" ""))]
4151 "TARGET_80387 && reload_completed"
4152 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4153 (set (match_dup 0) (match_dup 2))]
4157 [(set (match_operand:SF 0 "memory_operand" "")
4159 (match_operand:XF 1 "register_operand" "")))
4160 (clobber (match_operand:SF 2 "memory_operand" ""))]
4162 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4165 ;; Conversion from XFmode to DFmode.
4167 (define_expand "truncxfdf2"
4168 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4170 (match_operand:XF 1 "register_operand" "")))
4171 (clobber (match_dup 2))])]
4174 if (flag_unsafe_math_optimizations)
4176 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4177 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4178 if (reg != operands[0])
4179 emit_move_insn (operands[0], reg);
4183 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4186 (define_insn "*truncxfdf2_mixed"
4187 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4189 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4190 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4193 gcc_assert (!which_alternative);
4194 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4195 return "fstp%z0\t%y0";
4197 return "fst%z0\t%y0";
4199 [(set_attr "type" "fmov,multi,multi,multi")
4200 (set_attr "unit" "*,i387,i387,i387")
4201 (set_attr "mode" "DF")])
4203 (define_insn "truncxfdf2_i387_noop"
4204 [(set (match_operand:DF 0 "register_operand" "=f")
4205 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4206 "TARGET_80387 && flag_unsafe_math_optimizations"
4207 "* return output_387_reg_move (insn, operands);"
4208 [(set_attr "type" "fmov")
4209 (set_attr "mode" "DF")])
4211 (define_insn "*truncxfdf2_i387"
4212 [(set (match_operand:DF 0 "memory_operand" "=m")
4214 (match_operand:XF 1 "register_operand" "f")))]
4217 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4218 return "fstp%z0\t%y0";
4220 return "fst%z0\t%y0";
4222 [(set_attr "type" "fmov")
4223 (set_attr "mode" "DF")])
4226 [(set (match_operand:DF 0 "register_operand" "")
4228 (match_operand:XF 1 "register_operand" "")))
4229 (clobber (match_operand:DF 2 "memory_operand" ""))]
4230 "TARGET_80387 && reload_completed"
4231 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4232 (set (match_dup 0) (match_dup 2))]
4236 [(set (match_operand:DF 0 "memory_operand" "")
4238 (match_operand:XF 1 "register_operand" "")))
4239 (clobber (match_operand:DF 2 "memory_operand" ""))]
4241 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4244 ;; Signed conversion to DImode.
4246 (define_expand "fix_truncxfdi2"
4247 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248 (fix:DI (match_operand:XF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4254 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4259 (define_expand "fix_trunc<mode>di2"
4260 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4262 (clobber (reg:CC FLAGS_REG))])]
4263 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4266 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4268 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4271 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4273 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275 if (out != operands[0])
4276 emit_move_insn (operands[0], out);
4281 ;; Signed conversion to SImode.
4283 (define_expand "fix_truncxfsi2"
4284 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285 (fix:SI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4291 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4296 (define_expand "fix_trunc<mode>si2"
4297 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4303 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4305 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4308 if (SSE_FLOAT_MODE_P (<MODE>mode))
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4318 ;; Signed conversion to HImode.
4320 (define_expand "fix_trunc<mode>hi2"
4321 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4329 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4334 ;; Unsigned conversion to SImode.
4336 (define_expand "fixuns_trunc<mode>si2"
4337 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4338 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))]
4339 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4340 && TARGET_KEEPS_VECTOR_ALIGNED_STACK && !optimize_size"
4342 ix86_expand_convert_uns_si_sse (operands[0], operands[1]);
4346 ;; Unsigned conversion to HImode.
4347 ;; Without these patterns, we'll try the unsigned SI conversion which
4348 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4350 (define_expand "fixuns_truncsfhi2"
4352 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4353 (set (match_operand:HI 0 "nonimmediate_operand" "")
4354 (subreg:HI (match_dup 2) 0))]
4356 "operands[2] = gen_reg_rtx (SImode);")
4358 (define_expand "fixuns_truncdfhi2"
4360 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4361 (set (match_operand:HI 0 "nonimmediate_operand" "")
4362 (subreg:HI (match_dup 2) 0))]
4364 "operands[2] = gen_reg_rtx (SImode);")
4366 ;; When SSE is available, it is always faster to use it!
4367 (define_insn "fix_truncsfdi_sse"
4368 [(set (match_operand:DI 0 "register_operand" "=r,r")
4369 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4370 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4371 "cvttss2si{q}\t{%1, %0|%0, %1}"
4372 [(set_attr "type" "sseicvt")
4373 (set_attr "mode" "SF")
4374 (set_attr "athlon_decode" "double,vector")
4375 (set_attr "amdfam10_decode" "double,double")])
4377 (define_insn "fix_truncdfdi_sse"
4378 [(set (match_operand:DI 0 "register_operand" "=r,r")
4379 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4380 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4381 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4382 [(set_attr "type" "sseicvt")
4383 (set_attr "mode" "DF")
4384 (set_attr "athlon_decode" "double,vector")
4385 (set_attr "amdfam10_decode" "double,double")])
4387 (define_insn "fix_truncsfsi_sse"
4388 [(set (match_operand:SI 0 "register_operand" "=r,r")
4389 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4390 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4391 "cvttss2si\t{%1, %0|%0, %1}"
4392 [(set_attr "type" "sseicvt")
4393 (set_attr "mode" "DF")
4394 (set_attr "athlon_decode" "double,vector")
4395 (set_attr "amdfam10_decode" "double,double")])
4397 (define_insn "fix_truncdfsi_sse"
4398 [(set (match_operand:SI 0 "register_operand" "=r,r")
4399 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4400 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4401 "cvttsd2si\t{%1, %0|%0, %1}"
4402 [(set_attr "type" "sseicvt")
4403 (set_attr "mode" "DF")
4404 (set_attr "athlon_decode" "double,vector")
4405 (set_attr "amdfam10_decode" "double,double")])
4407 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4409 [(set (match_operand:DF 0 "register_operand" "")
4410 (match_operand:DF 1 "memory_operand" ""))
4411 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4412 (fix:SSEMODEI24 (match_dup 0)))]
4414 && peep2_reg_dead_p (2, operands[0])"
4415 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4419 [(set (match_operand:SF 0 "register_operand" "")
4420 (match_operand:SF 1 "memory_operand" ""))
4421 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422 (fix:SSEMODEI24 (match_dup 0)))]
4424 && peep2_reg_dead_p (2, operands[0])"
4425 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4428 ;; Avoid vector decoded forms of the instruction.
4430 [(match_scratch:DF 2 "Y")
4431 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4434 [(set (match_dup 2) (match_dup 1))
4435 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4439 [(match_scratch:SF 2 "x")
4440 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4441 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4442 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4443 [(set (match_dup 2) (match_dup 1))
4444 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4447 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4448 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4449 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4451 && FLOAT_MODE_P (GET_MODE (operands[1]))
4452 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4453 && (TARGET_64BIT || <MODE>mode != DImode))
4455 && !(reload_completed || reload_in_progress)"
4460 if (memory_operand (operands[0], VOIDmode))
4461 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4464 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4465 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4471 [(set_attr "type" "fisttp")
4472 (set_attr "mode" "<MODE>")])
4474 (define_insn "fix_trunc<mode>_i387_fisttp"
4475 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4476 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4477 (clobber (match_scratch:XF 2 "=&1f"))]
4479 && FLOAT_MODE_P (GET_MODE (operands[1]))
4480 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4481 && (TARGET_64BIT || <MODE>mode != DImode))
4482 && TARGET_SSE_MATH)"
4483 "* return output_fix_trunc (insn, operands, 1);"
4484 [(set_attr "type" "fisttp")
4485 (set_attr "mode" "<MODE>")])
4487 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4488 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4489 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4490 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4491 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4493 && FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && (TARGET_64BIT || <MODE>mode != DImode))
4496 && TARGET_SSE_MATH)"
4498 [(set_attr "type" "fisttp")
4499 (set_attr "mode" "<MODE>")])
4502 [(set (match_operand:X87MODEI 0 "register_operand" "")
4503 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4504 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4505 (clobber (match_scratch 3 ""))]
4507 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4508 (clobber (match_dup 3))])
4509 (set (match_dup 0) (match_dup 2))]
4513 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4514 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4515 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4516 (clobber (match_scratch 3 ""))]
4518 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4519 (clobber (match_dup 3))])]
4522 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4523 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4524 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4525 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4526 ;; function in i386.c.
4527 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4528 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4529 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4530 (clobber (reg:CC FLAGS_REG))]
4531 "TARGET_80387 && !TARGET_FISTTP
4532 && FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && (TARGET_64BIT || <MODE>mode != DImode))
4535 && !(reload_completed || reload_in_progress)"
4540 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4542 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4543 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4544 if (memory_operand (operands[0], VOIDmode))
4545 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4546 operands[2], operands[3]));
4549 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4550 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4551 operands[2], operands[3],
4556 [(set_attr "type" "fistp")
4557 (set_attr "i387_cw" "trunc")
4558 (set_attr "mode" "<MODE>")])
4560 (define_insn "fix_truncdi_i387"
4561 [(set (match_operand:DI 0 "memory_operand" "=m")
4562 (fix:DI (match_operand 1 "register_operand" "f")))
4563 (use (match_operand:HI 2 "memory_operand" "m"))
4564 (use (match_operand:HI 3 "memory_operand" "m"))
4565 (clobber (match_scratch:XF 4 "=&1f"))]
4566 "TARGET_80387 && !TARGET_FISTTP
4567 && FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4569 "* return output_fix_trunc (insn, operands, 0);"
4570 [(set_attr "type" "fistp")
4571 (set_attr "i387_cw" "trunc")
4572 (set_attr "mode" "DI")])
4574 (define_insn "fix_truncdi_i387_with_temp"
4575 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4576 (fix:DI (match_operand 1 "register_operand" "f,f")))
4577 (use (match_operand:HI 2 "memory_operand" "m,m"))
4578 (use (match_operand:HI 3 "memory_operand" "m,m"))
4579 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4580 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4581 "TARGET_80387 && !TARGET_FISTTP
4582 && FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4585 [(set_attr "type" "fistp")
4586 (set_attr "i387_cw" "trunc")
4587 (set_attr "mode" "DI")])
4590 [(set (match_operand:DI 0 "register_operand" "")
4591 (fix:DI (match_operand 1 "register_operand" "")))
4592 (use (match_operand:HI 2 "memory_operand" ""))
4593 (use (match_operand:HI 3 "memory_operand" ""))
4594 (clobber (match_operand:DI 4 "memory_operand" ""))
4595 (clobber (match_scratch 5 ""))]
4597 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4600 (clobber (match_dup 5))])
4601 (set (match_dup 0) (match_dup 4))]
4605 [(set (match_operand:DI 0 "memory_operand" "")
4606 (fix:DI (match_operand 1 "register_operand" "")))
4607 (use (match_operand:HI 2 "memory_operand" ""))
4608 (use (match_operand:HI 3 "memory_operand" ""))
4609 (clobber (match_operand:DI 4 "memory_operand" ""))
4610 (clobber (match_scratch 5 ""))]
4612 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4615 (clobber (match_dup 5))])]
4618 (define_insn "fix_trunc<mode>_i387"
4619 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4620 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4621 (use (match_operand:HI 2 "memory_operand" "m"))
4622 (use (match_operand:HI 3 "memory_operand" "m"))]
4623 "TARGET_80387 && !TARGET_FISTTP
4624 && FLOAT_MODE_P (GET_MODE (operands[1]))
4625 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4626 "* return output_fix_trunc (insn, operands, 0);"
4627 [(set_attr "type" "fistp")
4628 (set_attr "i387_cw" "trunc")
4629 (set_attr "mode" "<MODE>")])
4631 (define_insn "fix_trunc<mode>_i387_with_temp"
4632 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4633 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4634 (use (match_operand:HI 2 "memory_operand" "m,m"))
4635 (use (match_operand:HI 3 "memory_operand" "m,m"))
4636 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4637 "TARGET_80387 && !TARGET_FISTTP
4638 && FLOAT_MODE_P (GET_MODE (operands[1]))
4639 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4641 [(set_attr "type" "fistp")
4642 (set_attr "i387_cw" "trunc")
4643 (set_attr "mode" "<MODE>")])
4646 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4647 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4648 (use (match_operand:HI 2 "memory_operand" ""))
4649 (use (match_operand:HI 3 "memory_operand" ""))
4650 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4652 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4654 (use (match_dup 3))])
4655 (set (match_dup 0) (match_dup 4))]
4659 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4660 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4661 (use (match_operand:HI 2 "memory_operand" ""))
4662 (use (match_operand:HI 3 "memory_operand" ""))
4663 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4665 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4667 (use (match_dup 3))])]
4670 (define_insn "x86_fnstcw_1"
4671 [(set (match_operand:HI 0 "memory_operand" "=m")
4672 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4675 [(set_attr "length" "2")
4676 (set_attr "mode" "HI")
4677 (set_attr "unit" "i387")])
4679 (define_insn "x86_fldcw_1"
4680 [(set (reg:HI FPCR_REG)
4681 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4684 [(set_attr "length" "2")
4685 (set_attr "mode" "HI")
4686 (set_attr "unit" "i387")
4687 (set_attr "athlon_decode" "vector")
4688 (set_attr "amdfam10_decode" "vector")])
4690 ;; Conversion between fixed point and floating point.
4692 ;; Even though we only accept memory inputs, the backend _really_
4693 ;; wants to be able to do this between registers.
4695 (define_expand "floathisf2"
4696 [(set (match_operand:SF 0 "register_operand" "")
4697 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4698 "TARGET_80387 || TARGET_SSE_MATH"
4700 if (TARGET_SSE_MATH)
4702 emit_insn (gen_floatsisf2 (operands[0],
4703 convert_to_mode (SImode, operands[1], 0)));
4708 (define_insn "*floathisf2_i387"
4709 [(set (match_operand:SF 0 "register_operand" "=f,f")
4710 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4711 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4715 [(set_attr "type" "fmov,multi")
4716 (set_attr "mode" "SF")
4717 (set_attr "unit" "*,i387")
4718 (set_attr "fp_int_src" "true")])
4720 (define_expand "floatsisf2"
4721 [(set (match_operand:SF 0 "register_operand" "")
4722 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4723 "TARGET_80387 || TARGET_SSE_MATH"
4726 (define_insn "*floatsisf2_mixed"
4727 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4728 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4729 "TARGET_MIX_SSE_I387"
4733 cvtsi2ss\t{%1, %0|%0, %1}
4734 cvtsi2ss\t{%1, %0|%0, %1}"
4735 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4736 (set_attr "mode" "SF")
4737 (set_attr "unit" "*,i387,*,*")
4738 (set_attr "athlon_decode" "*,*,vector,double")
4739 (set_attr "amdfam10_decode" "*,*,vector,double")
4740 (set_attr "fp_int_src" "true")])
4742 (define_insn "*floatsisf2_sse"
4743 [(set (match_operand:SF 0 "register_operand" "=x,x")
4744 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4746 "cvtsi2ss\t{%1, %0|%0, %1}"
4747 [(set_attr "type" "sseicvt")
4748 (set_attr "mode" "SF")
4749 (set_attr "athlon_decode" "vector,double")
4750 (set_attr "amdfam10_decode" "vector,double")
4751 (set_attr "fp_int_src" "true")])
4753 (define_insn "*floatsisf2_i387"
4754 [(set (match_operand:SF 0 "register_operand" "=f,f")
4755 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4760 [(set_attr "type" "fmov,multi")
4761 (set_attr "mode" "SF")
4762 (set_attr "unit" "*,i387")
4763 (set_attr "fp_int_src" "true")])
4765 (define_expand "floatdisf2"
4766 [(set (match_operand:SF 0 "register_operand" "")
4767 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4768 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4771 (define_insn "*floatdisf2_mixed"
4772 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4773 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4774 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4778 cvtsi2ss{q}\t{%1, %0|%0, %1}
4779 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4780 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4781 (set_attr "mode" "SF")
4782 (set_attr "unit" "*,i387,*,*")
4783 (set_attr "athlon_decode" "*,*,vector,double")
4784 (set_attr "amdfam10_decode" "*,*,vector,double")
4785 (set_attr "fp_int_src" "true")])
4787 (define_insn "*floatdisf2_sse"
4788 [(set (match_operand:SF 0 "register_operand" "=x,x")
4789 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4790 "TARGET_64BIT && TARGET_SSE_MATH"
4791 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4792 [(set_attr "type" "sseicvt")
4793 (set_attr "mode" "SF")
4794 (set_attr "athlon_decode" "vector,double")
4795 (set_attr "amdfam10_decode" "vector,double")
4796 (set_attr "fp_int_src" "true")])
4798 (define_insn "*floatdisf2_i387"
4799 [(set (match_operand:SF 0 "register_operand" "=f,f")
4800 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4805 [(set_attr "type" "fmov,multi")
4806 (set_attr "mode" "SF")
4807 (set_attr "unit" "*,i387")
4808 (set_attr "fp_int_src" "true")])
4810 (define_expand "floathidf2"
4811 [(set (match_operand:DF 0 "register_operand" "")
4812 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4813 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4815 if (TARGET_SSE2 && TARGET_SSE_MATH)
4817 emit_insn (gen_floatsidf2 (operands[0],
4818 convert_to_mode (SImode, operands[1], 0)));
4823 (define_insn "*floathidf2_i387"
4824 [(set (match_operand:DF 0 "register_operand" "=f,f")
4825 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4826 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4830 [(set_attr "type" "fmov,multi")
4831 (set_attr "mode" "DF")
4832 (set_attr "unit" "*,i387")
4833 (set_attr "fp_int_src" "true")])
4835 (define_expand "floatsidf2"
4836 [(set (match_operand:DF 0 "register_operand" "")
4837 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4838 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4841 (define_insn "*floatsidf2_mixed"
4842 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4843 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4844 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4848 cvtsi2sd\t{%1, %0|%0, %1}
4849 cvtsi2sd\t{%1, %0|%0, %1}"
4850 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4851 (set_attr "mode" "DF")
4852 (set_attr "unit" "*,i387,*,*")
4853 (set_attr "athlon_decode" "*,*,double,direct")
4854 (set_attr "amdfam10_decode" "*,*,vector,double")
4855 (set_attr "fp_int_src" "true")])
4857 (define_insn "*floatsidf2_sse"
4858 [(set (match_operand:DF 0 "register_operand" "=x,x")
4859 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4860 "TARGET_SSE2 && TARGET_SSE_MATH"
4861 "cvtsi2sd\t{%1, %0|%0, %1}"
4862 [(set_attr "type" "sseicvt")
4863 (set_attr "mode" "DF")
4864 (set_attr "athlon_decode" "double,direct")
4865 (set_attr "amdfam10_decode" "vector,double")
4866 (set_attr "fp_int_src" "true")])
4868 (define_insn "*floatsidf2_i387"
4869 [(set (match_operand:DF 0 "register_operand" "=f,f")
4870 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4875 [(set_attr "type" "fmov,multi")
4876 (set_attr "mode" "DF")
4877 (set_attr "unit" "*,i387")
4878 (set_attr "fp_int_src" "true")])
4880 (define_expand "floatdidf2"
4881 [(set (match_operand:DF 0 "register_operand" "")
4882 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4883 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4885 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4887 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4892 (define_insn "*floatdidf2_mixed"
4893 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4894 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4895 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4899 cvtsi2sd{q}\t{%1, %0|%0, %1}
4900 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4901 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4902 (set_attr "mode" "DF")
4903 (set_attr "unit" "*,i387,*,*")
4904 (set_attr "athlon_decode" "*,*,double,direct")
4905 (set_attr "amdfam10_decode" "*,*,vector,double")
4906 (set_attr "fp_int_src" "true")])
4908 (define_insn "*floatdidf2_sse"
4909 [(set (match_operand:DF 0 "register_operand" "=x,x")
4910 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4911 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4912 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4913 [(set_attr "type" "sseicvt")
4914 (set_attr "mode" "DF")
4915 (set_attr "athlon_decode" "double,direct")
4916 (set_attr "amdfam10_decode" "vector,double")
4917 (set_attr "fp_int_src" "true")])
4919 (define_insn "*floatdidf2_i387"
4920 [(set (match_operand:DF 0 "register_operand" "=f,f")
4921 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4926 [(set_attr "type" "fmov,multi")
4927 (set_attr "mode" "DF")
4928 (set_attr "unit" "*,i387")
4929 (set_attr "fp_int_src" "true")])
4931 (define_insn "floathixf2"
4932 [(set (match_operand:XF 0 "register_operand" "=f,f")
4933 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4938 [(set_attr "type" "fmov,multi")
4939 (set_attr "mode" "XF")
4940 (set_attr "unit" "*,i387")
4941 (set_attr "fp_int_src" "true")])
4943 (define_insn "floatsixf2"
4944 [(set (match_operand:XF 0 "register_operand" "=f,f")
4945 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4950 [(set_attr "type" "fmov,multi")
4951 (set_attr "mode" "XF")
4952 (set_attr "unit" "*,i387")
4953 (set_attr "fp_int_src" "true")])
4955 (define_insn "floatdixf2"
4956 [(set (match_operand:XF 0 "register_operand" "=f,f")
4957 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4962 [(set_attr "type" "fmov,multi")
4963 (set_attr "mode" "XF")
4964 (set_attr "unit" "*,i387")
4965 (set_attr "fp_int_src" "true")])
4967 ;; %%% Kill these when reload knows how to do it.
4969 [(set (match_operand 0 "fp_register_operand" "")
4970 (float (match_operand 1 "register_operand" "")))]
4973 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4976 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4977 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4978 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4979 ix86_free_from_memory (GET_MODE (operands[1]));
4983 (define_expand "floatunssisf2"
4984 [(use (match_operand:SF 0 "register_operand" ""))
4985 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4988 if (TARGET_SSE_MATH && TARGET_SSE2)
4989 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4991 x86_emit_floatuns (operands);
4995 (define_expand "floatunssidf2"
4996 [(use (match_operand:DF 0 "register_operand" ""))
4997 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4998 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4999 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5001 (define_expand "floatunsdisf2"
5002 [(use (match_operand:SF 0 "register_operand" ""))
5003 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5004 "TARGET_64BIT && TARGET_SSE_MATH"
5005 "x86_emit_floatuns (operands); DONE;")
5007 (define_expand "floatunsdidf2"
5008 [(use (match_operand:DF 0 "register_operand" ""))
5009 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5010 "TARGET_SSE_MATH && TARGET_SSE2
5011 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5014 x86_emit_floatuns (operands);
5016 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5020 ;; SSE extract/set expanders
5025 ;; %%% splits for addditi3
5027 (define_expand "addti3"
5028 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5029 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5030 (match_operand:TI 2 "x86_64_general_operand" "")))
5031 (clobber (reg:CC FLAGS_REG))]
5033 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5035 (define_insn "*addti3_1"
5036 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5037 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5038 (match_operand:TI 2 "general_operand" "roiF,riF")))
5039 (clobber (reg:CC FLAGS_REG))]
5040 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5044 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5045 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5046 (match_operand:TI 2 "general_operand" "")))
5047 (clobber (reg:CC FLAGS_REG))]
5048 "TARGET_64BIT && reload_completed"
5049 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5051 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5052 (parallel [(set (match_dup 3)
5053 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5056 (clobber (reg:CC FLAGS_REG))])]
5057 "split_ti (operands+0, 1, operands+0, operands+3);
5058 split_ti (operands+1, 1, operands+1, operands+4);
5059 split_ti (operands+2, 1, operands+2, operands+5);")
5061 ;; %%% splits for addsidi3
5062 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5063 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5064 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5066 (define_expand "adddi3"
5067 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5068 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5069 (match_operand:DI 2 "x86_64_general_operand" "")))
5070 (clobber (reg:CC FLAGS_REG))]
5072 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5074 (define_insn "*adddi3_1"
5075 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5076 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5077 (match_operand:DI 2 "general_operand" "roiF,riF")))
5078 (clobber (reg:CC FLAGS_REG))]
5079 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5083 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5084 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5085 (match_operand:DI 2 "general_operand" "")))
5086 (clobber (reg:CC FLAGS_REG))]
5087 "!TARGET_64BIT && reload_completed"
5088 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5090 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5091 (parallel [(set (match_dup 3)
5092 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5095 (clobber (reg:CC FLAGS_REG))])]
5096 "split_di (operands+0, 1, operands+0, operands+3);
5097 split_di (operands+1, 1, operands+1, operands+4);
5098 split_di (operands+2, 1, operands+2, operands+5);")
5100 (define_insn "adddi3_carry_rex64"
5101 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5102 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5103 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5104 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5105 (clobber (reg:CC FLAGS_REG))]
5106 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5107 "adc{q}\t{%2, %0|%0, %2}"
5108 [(set_attr "type" "alu")
5109 (set_attr "pent_pair" "pu")
5110 (set_attr "mode" "DI")])
5112 (define_insn "*adddi3_cc_rex64"
5113 [(set (reg:CC FLAGS_REG)
5114 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5115 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5117 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5118 (plus:DI (match_dup 1) (match_dup 2)))]
5119 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120 "add{q}\t{%2, %0|%0, %2}"
5121 [(set_attr "type" "alu")
5122 (set_attr "mode" "DI")])
5124 (define_insn "addqi3_carry"
5125 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5126 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5127 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5128 (match_operand:QI 2 "general_operand" "qi,qm")))
5129 (clobber (reg:CC FLAGS_REG))]
5130 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5131 "adc{b}\t{%2, %0|%0, %2}"
5132 [(set_attr "type" "alu")
5133 (set_attr "pent_pair" "pu")
5134 (set_attr "mode" "QI")])
5136 (define_insn "addhi3_carry"
5137 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5138 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5139 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5140 (match_operand:HI 2 "general_operand" "ri,rm")))
5141 (clobber (reg:CC FLAGS_REG))]
5142 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5143 "adc{w}\t{%2, %0|%0, %2}"
5144 [(set_attr "type" "alu")
5145 (set_attr "pent_pair" "pu")
5146 (set_attr "mode" "HI")])
5148 (define_insn "addsi3_carry"
5149 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5150 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5151 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5152 (match_operand:SI 2 "general_operand" "ri,rm")))
5153 (clobber (reg:CC FLAGS_REG))]
5154 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5155 "adc{l}\t{%2, %0|%0, %2}"
5156 [(set_attr "type" "alu")
5157 (set_attr "pent_pair" "pu")
5158 (set_attr "mode" "SI")])
5160 (define_insn "*addsi3_carry_zext"
5161 [(set (match_operand:DI 0 "register_operand" "=r")
5163 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5164 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5165 (match_operand:SI 2 "general_operand" "rim"))))
5166 (clobber (reg:CC FLAGS_REG))]
5167 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5168 "adc{l}\t{%2, %k0|%k0, %2}"
5169 [(set_attr "type" "alu")
5170 (set_attr "pent_pair" "pu")
5171 (set_attr "mode" "SI")])
5173 (define_insn "*addsi3_cc"
5174 [(set (reg:CC FLAGS_REG)
5175 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5176 (match_operand:SI 2 "general_operand" "ri,rm")]
5178 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5179 (plus:SI (match_dup 1) (match_dup 2)))]
5180 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5181 "add{l}\t{%2, %0|%0, %2}"
5182 [(set_attr "type" "alu")
5183 (set_attr "mode" "SI")])
5185 (define_insn "addqi3_cc"
5186 [(set (reg:CC FLAGS_REG)
5187 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5188 (match_operand:QI 2 "general_operand" "qi,qm")]
5190 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5191 (plus:QI (match_dup 1) (match_dup 2)))]
5192 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5193 "add{b}\t{%2, %0|%0, %2}"
5194 [(set_attr "type" "alu")
5195 (set_attr "mode" "QI")])
5197 (define_expand "addsi3"
5198 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5199 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5200 (match_operand:SI 2 "general_operand" "")))
5201 (clobber (reg:CC FLAGS_REG))])]
5203 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5205 (define_insn "*lea_1"
5206 [(set (match_operand:SI 0 "register_operand" "=r")
5207 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5209 "lea{l}\t{%a1, %0|%0, %a1}"
5210 [(set_attr "type" "lea")
5211 (set_attr "mode" "SI")])
5213 (define_insn "*lea_1_rex64"
5214 [(set (match_operand:SI 0 "register_operand" "=r")
5215 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5217 "lea{l}\t{%a1, %0|%0, %a1}"
5218 [(set_attr "type" "lea")
5219 (set_attr "mode" "SI")])
5221 (define_insn "*lea_1_zext"
5222 [(set (match_operand:DI 0 "register_operand" "=r")
5224 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5226 "lea{l}\t{%a1, %k0|%k0, %a1}"
5227 [(set_attr "type" "lea")
5228 (set_attr "mode" "SI")])
5230 (define_insn "*lea_2_rex64"
5231 [(set (match_operand:DI 0 "register_operand" "=r")
5232 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5234 "lea{q}\t{%a1, %0|%0, %a1}"
5235 [(set_attr "type" "lea")
5236 (set_attr "mode" "DI")])
5238 ;; The lea patterns for non-Pmodes needs to be matched by several
5239 ;; insns converted to real lea by splitters.
5241 (define_insn_and_split "*lea_general_1"
5242 [(set (match_operand 0 "register_operand" "=r")
5243 (plus (plus (match_operand 1 "index_register_operand" "l")
5244 (match_operand 2 "register_operand" "r"))
5245 (match_operand 3 "immediate_operand" "i")))]
5246 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5247 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5248 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5249 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5250 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5251 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5252 || GET_MODE (operands[3]) == VOIDmode)"
5254 "&& reload_completed"
5258 operands[0] = gen_lowpart (SImode, operands[0]);
5259 operands[1] = gen_lowpart (Pmode, operands[1]);
5260 operands[2] = gen_lowpart (Pmode, operands[2]);
5261 operands[3] = gen_lowpart (Pmode, operands[3]);
5262 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5264 if (Pmode != SImode)
5265 pat = gen_rtx_SUBREG (SImode, pat, 0);
5266 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5269 [(set_attr "type" "lea")
5270 (set_attr "mode" "SI")])
5272 (define_insn_and_split "*lea_general_1_zext"
5273 [(set (match_operand:DI 0 "register_operand" "=r")
5275 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5276 (match_operand:SI 2 "register_operand" "r"))
5277 (match_operand:SI 3 "immediate_operand" "i"))))]
5280 "&& reload_completed"
5282 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5284 (match_dup 3)) 0)))]
5286 operands[1] = gen_lowpart (Pmode, operands[1]);
5287 operands[2] = gen_lowpart (Pmode, operands[2]);
5288 operands[3] = gen_lowpart (Pmode, operands[3]);
5290 [(set_attr "type" "lea")
5291 (set_attr "mode" "SI")])
5293 (define_insn_and_split "*lea_general_2"
5294 [(set (match_operand 0 "register_operand" "=r")
5295 (plus (mult (match_operand 1 "index_register_operand" "l")
5296 (match_operand 2 "const248_operand" "i"))
5297 (match_operand 3 "nonmemory_operand" "ri")))]
5298 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5299 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5300 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5301 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5302 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5303 || GET_MODE (operands[3]) == VOIDmode)"
5305 "&& reload_completed"
5309 operands[0] = gen_lowpart (SImode, operands[0]);
5310 operands[1] = gen_lowpart (Pmode, operands[1]);
5311 operands[3] = gen_lowpart (Pmode, operands[3]);
5312 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5314 if (Pmode != SImode)
5315 pat = gen_rtx_SUBREG (SImode, pat, 0);
5316 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5319 [(set_attr "type" "lea")
5320 (set_attr "mode" "SI")])
5322 (define_insn_and_split "*lea_general_2_zext"
5323 [(set (match_operand:DI 0 "register_operand" "=r")
5325 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5326 (match_operand:SI 2 "const248_operand" "n"))
5327 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5330 "&& reload_completed"
5332 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5334 (match_dup 3)) 0)))]
5336 operands[1] = gen_lowpart (Pmode, operands[1]);
5337 operands[3] = gen_lowpart (Pmode, operands[3]);
5339 [(set_attr "type" "lea")
5340 (set_attr "mode" "SI")])
5342 (define_insn_and_split "*lea_general_3"
5343 [(set (match_operand 0 "register_operand" "=r")
5344 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5345 (match_operand 2 "const248_operand" "i"))
5346 (match_operand 3 "register_operand" "r"))
5347 (match_operand 4 "immediate_operand" "i")))]
5348 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5349 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5350 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5351 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5352 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5354 "&& reload_completed"
5358 operands[0] = gen_lowpart (SImode, operands[0]);
5359 operands[1] = gen_lowpart (Pmode, operands[1]);
5360 operands[3] = gen_lowpart (Pmode, operands[3]);
5361 operands[4] = gen_lowpart (Pmode, operands[4]);
5362 pat = gen_rtx_PLUS (Pmode,
5363 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5367 if (Pmode != SImode)
5368 pat = gen_rtx_SUBREG (SImode, pat, 0);
5369 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5372 [(set_attr "type" "lea")
5373 (set_attr "mode" "SI")])
5375 (define_insn_and_split "*lea_general_3_zext"
5376 [(set (match_operand:DI 0 "register_operand" "=r")
5378 (plus:SI (plus:SI (mult:SI
5379 (match_operand:SI 1 "index_register_operand" "l")
5380 (match_operand:SI 2 "const248_operand" "n"))
5381 (match_operand:SI 3 "register_operand" "r"))
5382 (match_operand:SI 4 "immediate_operand" "i"))))]
5385 "&& reload_completed"
5387 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5390 (match_dup 4)) 0)))]
5392 operands[1] = gen_lowpart (Pmode, operands[1]);
5393 operands[3] = gen_lowpart (Pmode, operands[3]);
5394 operands[4] = gen_lowpart (Pmode, operands[4]);
5396 [(set_attr "type" "lea")
5397 (set_attr "mode" "SI")])
5399 (define_insn "*adddi_1_rex64"
5400 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5401 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5402 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5403 (clobber (reg:CC FLAGS_REG))]
5404 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5406 switch (get_attr_type (insn))
5409 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5410 return "lea{q}\t{%a2, %0|%0, %a2}";
5413 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5414 if (operands[2] == const1_rtx)
5415 return "inc{q}\t%0";
5418 gcc_assert (operands[2] == constm1_rtx);
5419 return "dec{q}\t%0";
5423 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5425 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5426 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5427 if (CONST_INT_P (operands[2])
5428 /* Avoid overflows. */
5429 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5430 && (INTVAL (operands[2]) == 128
5431 || (INTVAL (operands[2]) < 0
5432 && INTVAL (operands[2]) != -128)))
5434 operands[2] = GEN_INT (-INTVAL (operands[2]));
5435 return "sub{q}\t{%2, %0|%0, %2}";
5437 return "add{q}\t{%2, %0|%0, %2}";
5441 (cond [(eq_attr "alternative" "2")
5442 (const_string "lea")
5443 ; Current assemblers are broken and do not allow @GOTOFF in
5444 ; ought but a memory context.
5445 (match_operand:DI 2 "pic_symbolic_operand" "")
5446 (const_string "lea")
5447 (match_operand:DI 2 "incdec_operand" "")
5448 (const_string "incdec")
5450 (const_string "alu")))
5451 (set_attr "mode" "DI")])
5453 ;; Convert lea to the lea pattern to avoid flags dependency.
5455 [(set (match_operand:DI 0 "register_operand" "")
5456 (plus:DI (match_operand:DI 1 "register_operand" "")
5457 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5458 (clobber (reg:CC FLAGS_REG))]
5459 "TARGET_64BIT && reload_completed
5460 && true_regnum (operands[0]) != true_regnum (operands[1])"
5462 (plus:DI (match_dup 1)
5466 (define_insn "*adddi_2_rex64"
5467 [(set (reg FLAGS_REG)
5469 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5470 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5472 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5473 (plus:DI (match_dup 1) (match_dup 2)))]
5474 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5475 && ix86_binary_operator_ok (PLUS, DImode, operands)
5476 /* Current assemblers are broken and do not allow @GOTOFF in
5477 ought but a memory context. */
5478 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5480 switch (get_attr_type (insn))
5483 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5484 if (operands[2] == const1_rtx)
5485 return "inc{q}\t%0";
5488 gcc_assert (operands[2] == constm1_rtx);
5489 return "dec{q}\t%0";
5493 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5494 /* ???? We ought to handle there the 32bit case too
5495 - do we need new constraint? */
5496 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5497 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5498 if (CONST_INT_P (operands[2])
5499 /* Avoid overflows. */
5500 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5501 && (INTVAL (operands[2]) == 128
5502 || (INTVAL (operands[2]) < 0
5503 && INTVAL (operands[2]) != -128)))
5505 operands[2] = GEN_INT (-INTVAL (operands[2]));
5506 return "sub{q}\t{%2, %0|%0, %2}";
5508 return "add{q}\t{%2, %0|%0, %2}";
5512 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5513 (const_string "incdec")
5514 (const_string "alu")))
5515 (set_attr "mode" "DI")])
5517 (define_insn "*adddi_3_rex64"
5518 [(set (reg FLAGS_REG)
5519 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5520 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5521 (clobber (match_scratch:DI 0 "=r"))]
5523 && ix86_match_ccmode (insn, CCZmode)
5524 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5525 /* Current assemblers are broken and do not allow @GOTOFF in
5526 ought but a memory context. */
5527 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5529 switch (get_attr_type (insn))
5532 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5533 if (operands[2] == const1_rtx)
5534 return "inc{q}\t%0";
5537 gcc_assert (operands[2] == constm1_rtx);
5538 return "dec{q}\t%0";
5542 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5543 /* ???? We ought to handle there the 32bit case too
5544 - do we need new constraint? */
5545 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5546 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5547 if (CONST_INT_P (operands[2])
5548 /* Avoid overflows. */
5549 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5550 && (INTVAL (operands[2]) == 128
5551 || (INTVAL (operands[2]) < 0
5552 && INTVAL (operands[2]) != -128)))
5554 operands[2] = GEN_INT (-INTVAL (operands[2]));
5555 return "sub{q}\t{%2, %0|%0, %2}";
5557 return "add{q}\t{%2, %0|%0, %2}";
5561 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5562 (const_string "incdec")
5563 (const_string "alu")))
5564 (set_attr "mode" "DI")])
5566 ; For comparisons against 1, -1 and 128, we may generate better code
5567 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5568 ; is matched then. We can't accept general immediate, because for
5569 ; case of overflows, the result is messed up.
5570 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5572 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5573 ; only for comparisons not depending on it.
5574 (define_insn "*adddi_4_rex64"
5575 [(set (reg FLAGS_REG)
5576 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5577 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5578 (clobber (match_scratch:DI 0 "=rm"))]
5580 && ix86_match_ccmode (insn, CCGCmode)"
5582 switch (get_attr_type (insn))
5585 if (operands[2] == constm1_rtx)
5586 return "inc{q}\t%0";
5589 gcc_assert (operands[2] == const1_rtx);
5590 return "dec{q}\t%0";
5594 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5595 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5596 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5597 if ((INTVAL (operands[2]) == -128
5598 || (INTVAL (operands[2]) > 0
5599 && INTVAL (operands[2]) != 128))
5600 /* Avoid overflows. */
5601 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5602 return "sub{q}\t{%2, %0|%0, %2}";
5603 operands[2] = GEN_INT (-INTVAL (operands[2]));
5604 return "add{q}\t{%2, %0|%0, %2}";
5608 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5609 (const_string "incdec")
5610 (const_string "alu")))
5611 (set_attr "mode" "DI")])
5613 (define_insn "*adddi_5_rex64"
5614 [(set (reg FLAGS_REG)
5616 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5617 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5619 (clobber (match_scratch:DI 0 "=r"))]
5621 && ix86_match_ccmode (insn, CCGOCmode)
5622 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5623 /* Current assemblers are broken and do not allow @GOTOFF in
5624 ought but a memory context. */
5625 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5627 switch (get_attr_type (insn))
5630 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631 if (operands[2] == const1_rtx)
5632 return "inc{q}\t%0";
5635 gcc_assert (operands[2] == constm1_rtx);
5636 return "dec{q}\t%0";
5640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5642 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5643 if (CONST_INT_P (operands[2])
5644 /* Avoid overflows. */
5645 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5646 && (INTVAL (operands[2]) == 128
5647 || (INTVAL (operands[2]) < 0
5648 && INTVAL (operands[2]) != -128)))
5650 operands[2] = GEN_INT (-INTVAL (operands[2]));
5651 return "sub{q}\t{%2, %0|%0, %2}";
5653 return "add{q}\t{%2, %0|%0, %2}";
5657 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5658 (const_string "incdec")
5659 (const_string "alu")))
5660 (set_attr "mode" "DI")])
5663 (define_insn "*addsi_1"
5664 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5665 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5666 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5667 (clobber (reg:CC FLAGS_REG))]
5668 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5670 switch (get_attr_type (insn))
5673 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5674 return "lea{l}\t{%a2, %0|%0, %a2}";
5677 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5678 if (operands[2] == const1_rtx)
5679 return "inc{l}\t%0";
5682 gcc_assert (operands[2] == constm1_rtx);
5683 return "dec{l}\t%0";
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5690 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5691 if (CONST_INT_P (operands[2])
5692 && (INTVAL (operands[2]) == 128
5693 || (INTVAL (operands[2]) < 0
5694 && INTVAL (operands[2]) != -128)))
5696 operands[2] = GEN_INT (-INTVAL (operands[2]));
5697 return "sub{l}\t{%2, %0|%0, %2}";
5699 return "add{l}\t{%2, %0|%0, %2}";
5703 (cond [(eq_attr "alternative" "2")
5704 (const_string "lea")
5705 ; Current assemblers are broken and do not allow @GOTOFF in
5706 ; ought but a memory context.
5707 (match_operand:SI 2 "pic_symbolic_operand" "")
5708 (const_string "lea")
5709 (match_operand:SI 2 "incdec_operand" "")
5710 (const_string "incdec")
5712 (const_string "alu")))
5713 (set_attr "mode" "SI")])
5715 ;; Convert lea to the lea pattern to avoid flags dependency.
5717 [(set (match_operand 0 "register_operand" "")
5718 (plus (match_operand 1 "register_operand" "")
5719 (match_operand 2 "nonmemory_operand" "")))
5720 (clobber (reg:CC FLAGS_REG))]
5722 && true_regnum (operands[0]) != true_regnum (operands[1])"
5726 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5727 may confuse gen_lowpart. */
5728 if (GET_MODE (operands[0]) != Pmode)
5730 operands[1] = gen_lowpart (Pmode, operands[1]);
5731 operands[2] = gen_lowpart (Pmode, operands[2]);
5733 operands[0] = gen_lowpart (SImode, operands[0]);
5734 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5735 if (Pmode != SImode)
5736 pat = gen_rtx_SUBREG (SImode, pat, 0);
5737 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5741 ;; It may seem that nonimmediate operand is proper one for operand 1.
5742 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5743 ;; we take care in ix86_binary_operator_ok to not allow two memory
5744 ;; operands so proper swapping will be done in reload. This allow
5745 ;; patterns constructed from addsi_1 to match.
5746 (define_insn "addsi_1_zext"
5747 [(set (match_operand:DI 0 "register_operand" "=r,r")
5749 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5750 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5751 (clobber (reg:CC FLAGS_REG))]
5752 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5754 switch (get_attr_type (insn))
5757 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5758 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5761 if (operands[2] == const1_rtx)
5762 return "inc{l}\t%k0";
5765 gcc_assert (operands[2] == constm1_rtx);
5766 return "dec{l}\t%k0";
5770 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5771 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5772 if (CONST_INT_P (operands[2])
5773 && (INTVAL (operands[2]) == 128
5774 || (INTVAL (operands[2]) < 0
5775 && INTVAL (operands[2]) != -128)))
5777 operands[2] = GEN_INT (-INTVAL (operands[2]));
5778 return "sub{l}\t{%2, %k0|%k0, %2}";
5780 return "add{l}\t{%2, %k0|%k0, %2}";
5784 (cond [(eq_attr "alternative" "1")
5785 (const_string "lea")
5786 ; Current assemblers are broken and do not allow @GOTOFF in
5787 ; ought but a memory context.
5788 (match_operand:SI 2 "pic_symbolic_operand" "")
5789 (const_string "lea")
5790 (match_operand:SI 2 "incdec_operand" "")
5791 (const_string "incdec")
5793 (const_string "alu")))
5794 (set_attr "mode" "SI")])
5796 ;; Convert lea to the lea pattern to avoid flags dependency.
5798 [(set (match_operand:DI 0 "register_operand" "")
5800 (plus:SI (match_operand:SI 1 "register_operand" "")
5801 (match_operand:SI 2 "nonmemory_operand" ""))))
5802 (clobber (reg:CC FLAGS_REG))]
5803 "TARGET_64BIT && reload_completed
5804 && true_regnum (operands[0]) != true_regnum (operands[1])"
5806 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5808 operands[1] = gen_lowpart (Pmode, operands[1]);
5809 operands[2] = gen_lowpart (Pmode, operands[2]);
5812 (define_insn "*addsi_2"
5813 [(set (reg FLAGS_REG)
5815 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5816 (match_operand:SI 2 "general_operand" "rmni,rni"))
5818 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5819 (plus:SI (match_dup 1) (match_dup 2)))]
5820 "ix86_match_ccmode (insn, CCGOCmode)
5821 && ix86_binary_operator_ok (PLUS, SImode, operands)
5822 /* Current assemblers are broken and do not allow @GOTOFF in
5823 ought but a memory context. */
5824 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5826 switch (get_attr_type (insn))
5829 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5830 if (operands[2] == const1_rtx)
5831 return "inc{l}\t%0";
5834 gcc_assert (operands[2] == constm1_rtx);
5835 return "dec{l}\t%0";
5839 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5840 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5842 if (CONST_INT_P (operands[2])
5843 && (INTVAL (operands[2]) == 128
5844 || (INTVAL (operands[2]) < 0
5845 && INTVAL (operands[2]) != -128)))
5847 operands[2] = GEN_INT (-INTVAL (operands[2]));
5848 return "sub{l}\t{%2, %0|%0, %2}";
5850 return "add{l}\t{%2, %0|%0, %2}";
5854 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5855 (const_string "incdec")
5856 (const_string "alu")))
5857 (set_attr "mode" "SI")])
5859 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5860 (define_insn "*addsi_2_zext"
5861 [(set (reg FLAGS_REG)
5863 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5864 (match_operand:SI 2 "general_operand" "rmni"))
5866 (set (match_operand:DI 0 "register_operand" "=r")
5867 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5868 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5869 && ix86_binary_operator_ok (PLUS, SImode, operands)
5870 /* Current assemblers are broken and do not allow @GOTOFF in
5871 ought but a memory context. */
5872 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5874 switch (get_attr_type (insn))
5877 if (operands[2] == const1_rtx)
5878 return "inc{l}\t%k0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{l}\t%k0";
5886 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5888 if (CONST_INT_P (operands[2])
5889 && (INTVAL (operands[2]) == 128
5890 || (INTVAL (operands[2]) < 0
5891 && INTVAL (operands[2]) != -128)))
5893 operands[2] = GEN_INT (-INTVAL (operands[2]));
5894 return "sub{l}\t{%2, %k0|%k0, %2}";
5896 return "add{l}\t{%2, %k0|%k0, %2}";
5900 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "SI")])
5905 (define_insn "*addsi_3"
5906 [(set (reg FLAGS_REG)
5907 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5908 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5909 (clobber (match_scratch:SI 0 "=r"))]
5910 "ix86_match_ccmode (insn, CCZmode)
5911 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5912 /* Current assemblers are broken and do not allow @GOTOFF in
5913 ought but a memory context. */
5914 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5916 switch (get_attr_type (insn))
5919 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920 if (operands[2] == const1_rtx)
5921 return "inc{l}\t%0";
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return "dec{l}\t%0";
5929 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5930 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5931 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5932 if (CONST_INT_P (operands[2])
5933 && (INTVAL (operands[2]) == 128
5934 || (INTVAL (operands[2]) < 0
5935 && INTVAL (operands[2]) != -128)))
5937 operands[2] = GEN_INT (-INTVAL (operands[2]));
5938 return "sub{l}\t{%2, %0|%0, %2}";
5940 return "add{l}\t{%2, %0|%0, %2}";
5944 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set_attr "mode" "SI")])
5949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5950 (define_insn "*addsi_3_zext"
5951 [(set (reg FLAGS_REG)
5952 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5953 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5954 (set (match_operand:DI 0 "register_operand" "=r")
5955 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5956 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5957 && ix86_binary_operator_ok (PLUS, SImode, operands)
5958 /* Current assemblers are broken and do not allow @GOTOFF in
5959 ought but a memory context. */
5960 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5962 switch (get_attr_type (insn))
5965 if (operands[2] == const1_rtx)
5966 return "inc{l}\t%k0";
5969 gcc_assert (operands[2] == constm1_rtx);
5970 return "dec{l}\t%k0";
5974 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5976 if (CONST_INT_P (operands[2])
5977 && (INTVAL (operands[2]) == 128
5978 || (INTVAL (operands[2]) < 0
5979 && INTVAL (operands[2]) != -128)))
5981 operands[2] = GEN_INT (-INTVAL (operands[2]));
5982 return "sub{l}\t{%2, %k0|%k0, %2}";
5984 return "add{l}\t{%2, %k0|%k0, %2}";
5988 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5989 (const_string "incdec")
5990 (const_string "alu")))
5991 (set_attr "mode" "SI")])
5993 ; For comparisons against 1, -1 and 128, we may generate better code
5994 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5995 ; is matched then. We can't accept general immediate, because for
5996 ; case of overflows, the result is messed up.
5997 ; This pattern also don't hold of 0x80000000, since the value overflows
5999 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6000 ; only for comparisons not depending on it.
6001 (define_insn "*addsi_4"
6002 [(set (reg FLAGS_REG)
6003 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6004 (match_operand:SI 2 "const_int_operand" "n")))
6005 (clobber (match_scratch:SI 0 "=rm"))]
6006 "ix86_match_ccmode (insn, CCGCmode)
6007 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6009 switch (get_attr_type (insn))
6012 if (operands[2] == constm1_rtx)
6013 return "inc{l}\t%0";
6016 gcc_assert (operands[2] == const1_rtx);
6017 return "dec{l}\t%0";
6021 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6022 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6023 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6024 if ((INTVAL (operands[2]) == -128
6025 || (INTVAL (operands[2]) > 0
6026 && INTVAL (operands[2]) != 128)))
6027 return "sub{l}\t{%2, %0|%0, %2}";
6028 operands[2] = GEN_INT (-INTVAL (operands[2]));
6029 return "add{l}\t{%2, %0|%0, %2}";
6033 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6034 (const_string "incdec")
6035 (const_string "alu")))
6036 (set_attr "mode" "SI")])
6038 (define_insn "*addsi_5"
6039 [(set (reg FLAGS_REG)
6041 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6042 (match_operand:SI 2 "general_operand" "rmni"))
6044 (clobber (match_scratch:SI 0 "=r"))]
6045 "ix86_match_ccmode (insn, CCGOCmode)
6046 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6047 /* Current assemblers are broken and do not allow @GOTOFF in
6048 ought but a memory context. */
6049 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6051 switch (get_attr_type (insn))
6054 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6055 if (operands[2] == const1_rtx)
6056 return "inc{l}\t%0";
6059 gcc_assert (operands[2] == constm1_rtx);
6060 return "dec{l}\t%0";
6064 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6065 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6066 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6067 if (CONST_INT_P (operands[2])
6068 && (INTVAL (operands[2]) == 128
6069 || (INTVAL (operands[2]) < 0
6070 && INTVAL (operands[2]) != -128)))
6072 operands[2] = GEN_INT (-INTVAL (operands[2]));
6073 return "sub{l}\t{%2, %0|%0, %2}";
6075 return "add{l}\t{%2, %0|%0, %2}";
6079 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6080 (const_string "incdec")
6081 (const_string "alu")))
6082 (set_attr "mode" "SI")])
6084 (define_expand "addhi3"
6085 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6086 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6087 (match_operand:HI 2 "general_operand" "")))
6088 (clobber (reg:CC FLAGS_REG))])]
6089 "TARGET_HIMODE_MATH"
6090 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6092 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6093 ;; type optimizations enabled by define-splits. This is not important
6094 ;; for PII, and in fact harmful because of partial register stalls.
6096 (define_insn "*addhi_1_lea"
6097 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6098 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6099 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6100 (clobber (reg:CC FLAGS_REG))]
6101 "!TARGET_PARTIAL_REG_STALL
6102 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6104 switch (get_attr_type (insn))
6109 if (operands[2] == const1_rtx)
6110 return "inc{w}\t%0";
6113 gcc_assert (operands[2] == constm1_rtx);
6114 return "dec{w}\t%0";
6118 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6119 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6120 if (CONST_INT_P (operands[2])
6121 && (INTVAL (operands[2]) == 128
6122 || (INTVAL (operands[2]) < 0
6123 && INTVAL (operands[2]) != -128)))
6125 operands[2] = GEN_INT (-INTVAL (operands[2]));
6126 return "sub{w}\t{%2, %0|%0, %2}";
6128 return "add{w}\t{%2, %0|%0, %2}";
6132 (if_then_else (eq_attr "alternative" "2")
6133 (const_string "lea")
6134 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135 (const_string "incdec")
6136 (const_string "alu"))))
6137 (set_attr "mode" "HI,HI,SI")])
6139 (define_insn "*addhi_1"
6140 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6141 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6142 (match_operand:HI 2 "general_operand" "ri,rm")))
6143 (clobber (reg:CC FLAGS_REG))]
6144 "TARGET_PARTIAL_REG_STALL
6145 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6147 switch (get_attr_type (insn))
6150 if (operands[2] == const1_rtx)
6151 return "inc{w}\t%0";
6154 gcc_assert (operands[2] == constm1_rtx);
6155 return "dec{w}\t%0";
6159 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6160 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6161 if (CONST_INT_P (operands[2])
6162 && (INTVAL (operands[2]) == 128
6163 || (INTVAL (operands[2]) < 0
6164 && INTVAL (operands[2]) != -128)))
6166 operands[2] = GEN_INT (-INTVAL (operands[2]));
6167 return "sub{w}\t{%2, %0|%0, %2}";
6169 return "add{w}\t{%2, %0|%0, %2}";
6173 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6174 (const_string "incdec")
6175 (const_string "alu")))
6176 (set_attr "mode" "HI")])
6178 (define_insn "*addhi_2"
6179 [(set (reg FLAGS_REG)
6181 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6182 (match_operand:HI 2 "general_operand" "rmni,rni"))
6184 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6185 (plus:HI (match_dup 1) (match_dup 2)))]
6186 "ix86_match_ccmode (insn, CCGOCmode)
6187 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6189 switch (get_attr_type (insn))
6192 if (operands[2] == const1_rtx)
6193 return "inc{w}\t%0";
6196 gcc_assert (operands[2] == constm1_rtx);
6197 return "dec{w}\t%0";
6201 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6202 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6203 if (CONST_INT_P (operands[2])
6204 && (INTVAL (operands[2]) == 128
6205 || (INTVAL (operands[2]) < 0
6206 && INTVAL (operands[2]) != -128)))
6208 operands[2] = GEN_INT (-INTVAL (operands[2]));
6209 return "sub{w}\t{%2, %0|%0, %2}";
6211 return "add{w}\t{%2, %0|%0, %2}";
6215 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6216 (const_string "incdec")
6217 (const_string "alu")))
6218 (set_attr "mode" "HI")])
6220 (define_insn "*addhi_3"
6221 [(set (reg FLAGS_REG)
6222 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6223 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6224 (clobber (match_scratch:HI 0 "=r"))]
6225 "ix86_match_ccmode (insn, CCZmode)
6226 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6228 switch (get_attr_type (insn))
6231 if (operands[2] == const1_rtx)
6232 return "inc{w}\t%0";
6235 gcc_assert (operands[2] == constm1_rtx);
6236 return "dec{w}\t%0";
6240 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6242 if (CONST_INT_P (operands[2])
6243 && (INTVAL (operands[2]) == 128
6244 || (INTVAL (operands[2]) < 0
6245 && INTVAL (operands[2]) != -128)))
6247 operands[2] = GEN_INT (-INTVAL (operands[2]));
6248 return "sub{w}\t{%2, %0|%0, %2}";
6250 return "add{w}\t{%2, %0|%0, %2}";
6254 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255 (const_string "incdec")
6256 (const_string "alu")))
6257 (set_attr "mode" "HI")])
6259 ; See comments above addsi_4 for details.
6260 (define_insn "*addhi_4"
6261 [(set (reg FLAGS_REG)
6262 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6263 (match_operand:HI 2 "const_int_operand" "n")))
6264 (clobber (match_scratch:HI 0 "=rm"))]
6265 "ix86_match_ccmode (insn, CCGCmode)
6266 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6268 switch (get_attr_type (insn))
6271 if (operands[2] == constm1_rtx)
6272 return "inc{w}\t%0";
6275 gcc_assert (operands[2] == const1_rtx);
6276 return "dec{w}\t%0";
6280 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6281 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6282 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6283 if ((INTVAL (operands[2]) == -128
6284 || (INTVAL (operands[2]) > 0
6285 && INTVAL (operands[2]) != 128)))
6286 return "sub{w}\t{%2, %0|%0, %2}";
6287 operands[2] = GEN_INT (-INTVAL (operands[2]));
6288 return "add{w}\t{%2, %0|%0, %2}";
6292 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6293 (const_string "incdec")
6294 (const_string "alu")))
6295 (set_attr "mode" "SI")])
6298 (define_insn "*addhi_5"
6299 [(set (reg FLAGS_REG)
6301 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6302 (match_operand:HI 2 "general_operand" "rmni"))
6304 (clobber (match_scratch:HI 0 "=r"))]
6305 "ix86_match_ccmode (insn, CCGOCmode)
6306 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6308 switch (get_attr_type (insn))
6311 if (operands[2] == const1_rtx)
6312 return "inc{w}\t%0";
6315 gcc_assert (operands[2] == constm1_rtx);
6316 return "dec{w}\t%0";
6320 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6321 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6322 if (CONST_INT_P (operands[2])
6323 && (INTVAL (operands[2]) == 128
6324 || (INTVAL (operands[2]) < 0
6325 && INTVAL (operands[2]) != -128)))
6327 operands[2] = GEN_INT (-INTVAL (operands[2]));
6328 return "sub{w}\t{%2, %0|%0, %2}";
6330 return "add{w}\t{%2, %0|%0, %2}";
6334 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6335 (const_string "incdec")
6336 (const_string "alu")))
6337 (set_attr "mode" "HI")])
6339 (define_expand "addqi3"
6340 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6341 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6342 (match_operand:QI 2 "general_operand" "")))
6343 (clobber (reg:CC FLAGS_REG))])]
6344 "TARGET_QIMODE_MATH"
6345 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6347 ;; %%% Potential partial reg stall on alternative 2. What to do?
6348 (define_insn "*addqi_1_lea"
6349 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6350 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6351 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6352 (clobber (reg:CC FLAGS_REG))]
6353 "!TARGET_PARTIAL_REG_STALL
6354 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6356 int widen = (which_alternative == 2);
6357 switch (get_attr_type (insn))
6362 if (operands[2] == const1_rtx)
6363 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6366 gcc_assert (operands[2] == constm1_rtx);
6367 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6371 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6372 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6373 if (CONST_INT_P (operands[2])
6374 && (INTVAL (operands[2]) == 128
6375 || (INTVAL (operands[2]) < 0
6376 && INTVAL (operands[2]) != -128)))
6378 operands[2] = GEN_INT (-INTVAL (operands[2]));
6380 return "sub{l}\t{%2, %k0|%k0, %2}";
6382 return "sub{b}\t{%2, %0|%0, %2}";
6385 return "add{l}\t{%k2, %k0|%k0, %k2}";
6387 return "add{b}\t{%2, %0|%0, %2}";
6391 (if_then_else (eq_attr "alternative" "3")
6392 (const_string "lea")
6393 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6394 (const_string "incdec")
6395 (const_string "alu"))))
6396 (set_attr "mode" "QI,QI,SI,SI")])
6398 (define_insn "*addqi_1"
6399 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6400 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6401 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6402 (clobber (reg:CC FLAGS_REG))]
6403 "TARGET_PARTIAL_REG_STALL
6404 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6406 int widen = (which_alternative == 2);
6407 switch (get_attr_type (insn))
6410 if (operands[2] == const1_rtx)
6411 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6414 gcc_assert (operands[2] == constm1_rtx);
6415 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6419 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6420 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6421 if (CONST_INT_P (operands[2])
6422 && (INTVAL (operands[2]) == 128
6423 || (INTVAL (operands[2]) < 0
6424 && INTVAL (operands[2]) != -128)))
6426 operands[2] = GEN_INT (-INTVAL (operands[2]));
6428 return "sub{l}\t{%2, %k0|%k0, %2}";
6430 return "sub{b}\t{%2, %0|%0, %2}";
6433 return "add{l}\t{%k2, %k0|%k0, %k2}";
6435 return "add{b}\t{%2, %0|%0, %2}";
6439 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6440 (const_string "incdec")
6441 (const_string "alu")))
6442 (set_attr "mode" "QI,QI,SI")])
6444 (define_insn "*addqi_1_slp"
6445 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6446 (plus:QI (match_dup 0)
6447 (match_operand:QI 1 "general_operand" "qn,qnm")))
6448 (clobber (reg:CC FLAGS_REG))]
6449 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6450 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6452 switch (get_attr_type (insn))
6455 if (operands[1] == const1_rtx)
6456 return "inc{b}\t%0";
6459 gcc_assert (operands[1] == constm1_rtx);
6460 return "dec{b}\t%0";
6464 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6465 if (CONST_INT_P (operands[1])
6466 && INTVAL (operands[1]) < 0)
6468 operands[1] = GEN_INT (-INTVAL (operands[1]));
6469 return "sub{b}\t{%1, %0|%0, %1}";
6471 return "add{b}\t{%1, %0|%0, %1}";
6475 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6476 (const_string "incdec")
6477 (const_string "alu1")))
6478 (set (attr "memory")
6479 (if_then_else (match_operand 1 "memory_operand" "")
6480 (const_string "load")
6481 (const_string "none")))
6482 (set_attr "mode" "QI")])
6484 (define_insn "*addqi_2"
6485 [(set (reg FLAGS_REG)
6487 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6488 (match_operand:QI 2 "general_operand" "qmni,qni"))
6490 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6491 (plus:QI (match_dup 1) (match_dup 2)))]
6492 "ix86_match_ccmode (insn, CCGOCmode)
6493 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6495 switch (get_attr_type (insn))
6498 if (operands[2] == const1_rtx)
6499 return "inc{b}\t%0";
6502 gcc_assert (operands[2] == constm1_rtx
6503 || (CONST_INT_P (operands[2])
6504 && INTVAL (operands[2]) == 255));
6505 return "dec{b}\t%0";
6509 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6510 if (CONST_INT_P (operands[2])
6511 && INTVAL (operands[2]) < 0)
6513 operands[2] = GEN_INT (-INTVAL (operands[2]));
6514 return "sub{b}\t{%2, %0|%0, %2}";
6516 return "add{b}\t{%2, %0|%0, %2}";
6520 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6521 (const_string "incdec")
6522 (const_string "alu")))
6523 (set_attr "mode" "QI")])
6525 (define_insn "*addqi_3"
6526 [(set (reg FLAGS_REG)
6527 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6528 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6529 (clobber (match_scratch:QI 0 "=q"))]
6530 "ix86_match_ccmode (insn, CCZmode)
6531 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6533 switch (get_attr_type (insn))
6536 if (operands[2] == const1_rtx)
6537 return "inc{b}\t%0";
6540 gcc_assert (operands[2] == constm1_rtx
6541 || (CONST_INT_P (operands[2])
6542 && INTVAL (operands[2]) == 255));
6543 return "dec{b}\t%0";
6547 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6548 if (CONST_INT_P (operands[2])
6549 && INTVAL (operands[2]) < 0)
6551 operands[2] = GEN_INT (-INTVAL (operands[2]));
6552 return "sub{b}\t{%2, %0|%0, %2}";
6554 return "add{b}\t{%2, %0|%0, %2}";
6558 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6559 (const_string "incdec")
6560 (const_string "alu")))
6561 (set_attr "mode" "QI")])
6563 ; See comments above addsi_4 for details.
6564 (define_insn "*addqi_4"
6565 [(set (reg FLAGS_REG)
6566 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6567 (match_operand:QI 2 "const_int_operand" "n")))
6568 (clobber (match_scratch:QI 0 "=qm"))]
6569 "ix86_match_ccmode (insn, CCGCmode)
6570 && (INTVAL (operands[2]) & 0xff) != 0x80"
6572 switch (get_attr_type (insn))
6575 if (operands[2] == constm1_rtx
6576 || (CONST_INT_P (operands[2])
6577 && INTVAL (operands[2]) == 255))
6578 return "inc{b}\t%0";
6581 gcc_assert (operands[2] == const1_rtx);
6582 return "dec{b}\t%0";
6586 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6587 if (INTVAL (operands[2]) < 0)
6589 operands[2] = GEN_INT (-INTVAL (operands[2]));
6590 return "add{b}\t{%2, %0|%0, %2}";
6592 return "sub{b}\t{%2, %0|%0, %2}";
6596 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6597 (const_string "incdec")
6598 (const_string "alu")))
6599 (set_attr "mode" "QI")])
6602 (define_insn "*addqi_5"
6603 [(set (reg FLAGS_REG)
6605 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6606 (match_operand:QI 2 "general_operand" "qmni"))
6608 (clobber (match_scratch:QI 0 "=q"))]
6609 "ix86_match_ccmode (insn, CCGOCmode)
6610 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6612 switch (get_attr_type (insn))
6615 if (operands[2] == const1_rtx)
6616 return "inc{b}\t%0";
6619 gcc_assert (operands[2] == constm1_rtx
6620 || (CONST_INT_P (operands[2])
6621 && INTVAL (operands[2]) == 255));
6622 return "dec{b}\t%0";
6626 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6627 if (CONST_INT_P (operands[2])
6628 && INTVAL (operands[2]) < 0)
6630 operands[2] = GEN_INT (-INTVAL (operands[2]));
6631 return "sub{b}\t{%2, %0|%0, %2}";
6633 return "add{b}\t{%2, %0|%0, %2}";
6637 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6638 (const_string "incdec")
6639 (const_string "alu")))
6640 (set_attr "mode" "QI")])
6643 (define_insn "addqi_ext_1"
6644 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6649 (match_operand 1 "ext_register_operand" "0")
6652 (match_operand:QI 2 "general_operand" "Qmn")))
6653 (clobber (reg:CC FLAGS_REG))]
6656 switch (get_attr_type (insn))
6659 if (operands[2] == const1_rtx)
6660 return "inc{b}\t%h0";
6663 gcc_assert (operands[2] == constm1_rtx
6664 || (CONST_INT_P (operands[2])
6665 && INTVAL (operands[2]) == 255));
6666 return "dec{b}\t%h0";
6670 return "add{b}\t{%2, %h0|%h0, %2}";
6674 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6675 (const_string "incdec")
6676 (const_string "alu")))
6677 (set_attr "mode" "QI")])
6679 (define_insn "*addqi_ext_1_rex64"
6680 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6685 (match_operand 1 "ext_register_operand" "0")
6688 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6689 (clobber (reg:CC FLAGS_REG))]
6692 switch (get_attr_type (insn))
6695 if (operands[2] == const1_rtx)
6696 return "inc{b}\t%h0";
6699 gcc_assert (operands[2] == constm1_rtx
6700 || (CONST_INT_P (operands[2])
6701 && INTVAL (operands[2]) == 255));
6702 return "dec{b}\t%h0";
6706 return "add{b}\t{%2, %h0|%h0, %2}";
6710 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6711 (const_string "incdec")
6712 (const_string "alu")))
6713 (set_attr "mode" "QI")])
6715 (define_insn "*addqi_ext_2"
6716 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6721 (match_operand 1 "ext_register_operand" "%0")
6725 (match_operand 2 "ext_register_operand" "Q")
6728 (clobber (reg:CC FLAGS_REG))]
6730 "add{b}\t{%h2, %h0|%h0, %h2}"
6731 [(set_attr "type" "alu")
6732 (set_attr "mode" "QI")])
6734 ;; The patterns that match these are at the end of this file.
6736 (define_expand "addxf3"
6737 [(set (match_operand:XF 0 "register_operand" "")
6738 (plus:XF (match_operand:XF 1 "register_operand" "")
6739 (match_operand:XF 2 "register_operand" "")))]
6743 (define_expand "adddf3"
6744 [(set (match_operand:DF 0 "register_operand" "")
6745 (plus:DF (match_operand:DF 1 "register_operand" "")
6746 (match_operand:DF 2 "nonimmediate_operand" "")))]
6747 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6750 (define_expand "addsf3"
6751 [(set (match_operand:SF 0 "register_operand" "")
6752 (plus:SF (match_operand:SF 1 "register_operand" "")
6753 (match_operand:SF 2 "nonimmediate_operand" "")))]
6754 "TARGET_80387 || TARGET_SSE_MATH"
6757 ;; Subtract instructions
6759 ;; %%% splits for subditi3
6761 (define_expand "subti3"
6762 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6763 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6764 (match_operand:TI 2 "x86_64_general_operand" "")))
6765 (clobber (reg:CC FLAGS_REG))])]
6767 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6769 (define_insn "*subti3_1"
6770 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6771 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6772 (match_operand:TI 2 "general_operand" "roiF,riF")))
6773 (clobber (reg:CC FLAGS_REG))]
6774 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6778 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6779 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6780 (match_operand:TI 2 "general_operand" "")))
6781 (clobber (reg:CC FLAGS_REG))]
6782 "TARGET_64BIT && reload_completed"
6783 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6784 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6785 (parallel [(set (match_dup 3)
6786 (minus:DI (match_dup 4)
6787 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6789 (clobber (reg:CC FLAGS_REG))])]
6790 "split_ti (operands+0, 1, operands+0, operands+3);
6791 split_ti (operands+1, 1, operands+1, operands+4);
6792 split_ti (operands+2, 1, operands+2, operands+5);")
6794 ;; %%% splits for subsidi3
6796 (define_expand "subdi3"
6797 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6798 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6799 (match_operand:DI 2 "x86_64_general_operand" "")))
6800 (clobber (reg:CC FLAGS_REG))])]
6802 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6804 (define_insn "*subdi3_1"
6805 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6806 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6807 (match_operand:DI 2 "general_operand" "roiF,riF")))
6808 (clobber (reg:CC FLAGS_REG))]
6809 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6813 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6814 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6815 (match_operand:DI 2 "general_operand" "")))
6816 (clobber (reg:CC FLAGS_REG))]
6817 "!TARGET_64BIT && reload_completed"
6818 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6819 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6820 (parallel [(set (match_dup 3)
6821 (minus:SI (match_dup 4)
6822 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6824 (clobber (reg:CC FLAGS_REG))])]
6825 "split_di (operands+0, 1, operands+0, operands+3);
6826 split_di (operands+1, 1, operands+1, operands+4);
6827 split_di (operands+2, 1, operands+2, operands+5);")
6829 (define_insn "subdi3_carry_rex64"
6830 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6831 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6832 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6833 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6834 (clobber (reg:CC FLAGS_REG))]
6835 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6836 "sbb{q}\t{%2, %0|%0, %2}"
6837 [(set_attr "type" "alu")
6838 (set_attr "pent_pair" "pu")
6839 (set_attr "mode" "DI")])
6841 (define_insn "*subdi_1_rex64"
6842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6843 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6844 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6845 (clobber (reg:CC FLAGS_REG))]
6846 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6847 "sub{q}\t{%2, %0|%0, %2}"
6848 [(set_attr "type" "alu")
6849 (set_attr "mode" "DI")])
6851 (define_insn "*subdi_2_rex64"
6852 [(set (reg FLAGS_REG)
6854 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6855 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6857 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6858 (minus:DI (match_dup 1) (match_dup 2)))]
6859 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6860 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6861 "sub{q}\t{%2, %0|%0, %2}"
6862 [(set_attr "type" "alu")
6863 (set_attr "mode" "DI")])
6865 (define_insn "*subdi_3_rex63"
6866 [(set (reg FLAGS_REG)
6867 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6868 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6869 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6870 (minus:DI (match_dup 1) (match_dup 2)))]
6871 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6872 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6873 "sub{q}\t{%2, %0|%0, %2}"
6874 [(set_attr "type" "alu")
6875 (set_attr "mode" "DI")])
6877 (define_insn "subqi3_carry"
6878 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6879 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6880 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6881 (match_operand:QI 2 "general_operand" "qi,qm"))))
6882 (clobber (reg:CC FLAGS_REG))]
6883 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6884 "sbb{b}\t{%2, %0|%0, %2}"
6885 [(set_attr "type" "alu")
6886 (set_attr "pent_pair" "pu")
6887 (set_attr "mode" "QI")])
6889 (define_insn "subhi3_carry"
6890 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6891 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6892 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6893 (match_operand:HI 2 "general_operand" "ri,rm"))))
6894 (clobber (reg:CC FLAGS_REG))]
6895 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6896 "sbb{w}\t{%2, %0|%0, %2}"
6897 [(set_attr "type" "alu")
6898 (set_attr "pent_pair" "pu")
6899 (set_attr "mode" "HI")])
6901 (define_insn "subsi3_carry"
6902 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6903 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6904 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6905 (match_operand:SI 2 "general_operand" "ri,rm"))))
6906 (clobber (reg:CC FLAGS_REG))]
6907 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6908 "sbb{l}\t{%2, %0|%0, %2}"
6909 [(set_attr "type" "alu")
6910 (set_attr "pent_pair" "pu")
6911 (set_attr "mode" "SI")])
6913 (define_insn "subsi3_carry_zext"
6914 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6916 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6917 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6918 (match_operand:SI 2 "general_operand" "ri,rm")))))
6919 (clobber (reg:CC FLAGS_REG))]
6920 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6921 "sbb{l}\t{%2, %k0|%k0, %2}"
6922 [(set_attr "type" "alu")
6923 (set_attr "pent_pair" "pu")
6924 (set_attr "mode" "SI")])
6926 (define_expand "subsi3"
6927 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6928 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6929 (match_operand:SI 2 "general_operand" "")))
6930 (clobber (reg:CC FLAGS_REG))])]
6932 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6934 (define_insn "*subsi_1"
6935 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6936 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6937 (match_operand:SI 2 "general_operand" "ri,rm")))
6938 (clobber (reg:CC FLAGS_REG))]
6939 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6940 "sub{l}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "alu")
6942 (set_attr "mode" "SI")])
6944 (define_insn "*subsi_1_zext"
6945 [(set (match_operand:DI 0 "register_operand" "=r")
6947 (minus:SI (match_operand:SI 1 "register_operand" "0")
6948 (match_operand:SI 2 "general_operand" "rim"))))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6951 "sub{l}\t{%2, %k0|%k0, %2}"
6952 [(set_attr "type" "alu")
6953 (set_attr "mode" "SI")])
6955 (define_insn "*subsi_2"
6956 [(set (reg FLAGS_REG)
6958 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6959 (match_operand:SI 2 "general_operand" "ri,rm"))
6961 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6962 (minus:SI (match_dup 1) (match_dup 2)))]
6963 "ix86_match_ccmode (insn, CCGOCmode)
6964 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6965 "sub{l}\t{%2, %0|%0, %2}"
6966 [(set_attr "type" "alu")
6967 (set_attr "mode" "SI")])
6969 (define_insn "*subsi_2_zext"
6970 [(set (reg FLAGS_REG)
6972 (minus:SI (match_operand:SI 1 "register_operand" "0")
6973 (match_operand:SI 2 "general_operand" "rim"))
6975 (set (match_operand:DI 0 "register_operand" "=r")
6977 (minus:SI (match_dup 1)
6979 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6980 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6981 "sub{l}\t{%2, %k0|%k0, %2}"
6982 [(set_attr "type" "alu")
6983 (set_attr "mode" "SI")])
6985 (define_insn "*subsi_3"
6986 [(set (reg FLAGS_REG)
6987 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6988 (match_operand:SI 2 "general_operand" "ri,rm")))
6989 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6990 (minus:SI (match_dup 1) (match_dup 2)))]
6991 "ix86_match_ccmode (insn, CCmode)
6992 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6993 "sub{l}\t{%2, %0|%0, %2}"
6994 [(set_attr "type" "alu")
6995 (set_attr "mode" "SI")])
6997 (define_insn "*subsi_3_zext"
6998 [(set (reg FLAGS_REG)
6999 (compare (match_operand:SI 1 "register_operand" "0")
7000 (match_operand:SI 2 "general_operand" "rim")))
7001 (set (match_operand:DI 0 "register_operand" "=r")
7003 (minus:SI (match_dup 1)
7005 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7006 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7007 "sub{l}\t{%2, %1|%1, %2}"
7008 [(set_attr "type" "alu")
7009 (set_attr "mode" "DI")])
7011 (define_expand "subhi3"
7012 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7013 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7014 (match_operand:HI 2 "general_operand" "")))
7015 (clobber (reg:CC FLAGS_REG))])]
7016 "TARGET_HIMODE_MATH"
7017 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7019 (define_insn "*subhi_1"
7020 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7021 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7022 (match_operand:HI 2 "general_operand" "ri,rm")))
7023 (clobber (reg:CC FLAGS_REG))]
7024 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7025 "sub{w}\t{%2, %0|%0, %2}"
7026 [(set_attr "type" "alu")
7027 (set_attr "mode" "HI")])
7029 (define_insn "*subhi_2"
7030 [(set (reg FLAGS_REG)
7032 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7033 (match_operand:HI 2 "general_operand" "ri,rm"))
7035 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7036 (minus:HI (match_dup 1) (match_dup 2)))]
7037 "ix86_match_ccmode (insn, CCGOCmode)
7038 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7039 "sub{w}\t{%2, %0|%0, %2}"
7040 [(set_attr "type" "alu")
7041 (set_attr "mode" "HI")])
7043 (define_insn "*subhi_3"
7044 [(set (reg FLAGS_REG)
7045 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7046 (match_operand:HI 2 "general_operand" "ri,rm")))
7047 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7048 (minus:HI (match_dup 1) (match_dup 2)))]
7049 "ix86_match_ccmode (insn, CCmode)
7050 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7051 "sub{w}\t{%2, %0|%0, %2}"
7052 [(set_attr "type" "alu")
7053 (set_attr "mode" "HI")])
7055 (define_expand "subqi3"
7056 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7057 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7058 (match_operand:QI 2 "general_operand" "")))
7059 (clobber (reg:CC FLAGS_REG))])]
7060 "TARGET_QIMODE_MATH"
7061 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7063 (define_insn "*subqi_1"
7064 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7065 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7066 (match_operand:QI 2 "general_operand" "qn,qmn")))
7067 (clobber (reg:CC FLAGS_REG))]
7068 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7069 "sub{b}\t{%2, %0|%0, %2}"
7070 [(set_attr "type" "alu")
7071 (set_attr "mode" "QI")])
7073 (define_insn "*subqi_1_slp"
7074 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7075 (minus:QI (match_dup 0)
7076 (match_operand:QI 1 "general_operand" "qn,qmn")))
7077 (clobber (reg:CC FLAGS_REG))]
7078 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7079 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7080 "sub{b}\t{%1, %0|%0, %1}"
7081 [(set_attr "type" "alu1")
7082 (set_attr "mode" "QI")])
7084 (define_insn "*subqi_2"
7085 [(set (reg FLAGS_REG)
7087 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7088 (match_operand:QI 2 "general_operand" "qi,qm"))
7090 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7091 (minus:HI (match_dup 1) (match_dup 2)))]
7092 "ix86_match_ccmode (insn, CCGOCmode)
7093 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7094 "sub{b}\t{%2, %0|%0, %2}"
7095 [(set_attr "type" "alu")
7096 (set_attr "mode" "QI")])
7098 (define_insn "*subqi_3"
7099 [(set (reg FLAGS_REG)
7100 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7101 (match_operand:QI 2 "general_operand" "qi,qm")))
7102 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7103 (minus:HI (match_dup 1) (match_dup 2)))]
7104 "ix86_match_ccmode (insn, CCmode)
7105 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7106 "sub{b}\t{%2, %0|%0, %2}"
7107 [(set_attr "type" "alu")
7108 (set_attr "mode" "QI")])
7110 ;; The patterns that match these are at the end of this file.
7112 (define_expand "subxf3"
7113 [(set (match_operand:XF 0 "register_operand" "")
7114 (minus:XF (match_operand:XF 1 "register_operand" "")
7115 (match_operand:XF 2 "register_operand" "")))]
7119 (define_expand "subdf3"
7120 [(set (match_operand:DF 0 "register_operand" "")
7121 (minus:DF (match_operand:DF 1 "register_operand" "")
7122 (match_operand:DF 2 "nonimmediate_operand" "")))]
7123 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7126 (define_expand "subsf3"
7127 [(set (match_operand:SF 0 "register_operand" "")
7128 (minus:SF (match_operand:SF 1 "register_operand" "")
7129 (match_operand:SF 2 "nonimmediate_operand" "")))]
7130 "TARGET_80387 || TARGET_SSE_MATH"
7133 ;; Multiply instructions
7135 (define_expand "muldi3"
7136 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7137 (mult:DI (match_operand:DI 1 "register_operand" "")
7138 (match_operand:DI 2 "x86_64_general_operand" "")))
7139 (clobber (reg:CC FLAGS_REG))])]
7144 ;; IMUL reg64, reg64, imm8 Direct
7145 ;; IMUL reg64, mem64, imm8 VectorPath
7146 ;; IMUL reg64, reg64, imm32 Direct
7147 ;; IMUL reg64, mem64, imm32 VectorPath
7148 ;; IMUL reg64, reg64 Direct
7149 ;; IMUL reg64, mem64 Direct
7151 (define_insn "*muldi3_1_rex64"
7152 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7153 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7154 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7155 (clobber (reg:CC FLAGS_REG))]
7157 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7159 imul{q}\t{%2, %1, %0|%0, %1, %2}
7160 imul{q}\t{%2, %1, %0|%0, %1, %2}
7161 imul{q}\t{%2, %0|%0, %2}"
7162 [(set_attr "type" "imul")
7163 (set_attr "prefix_0f" "0,0,1")
7164 (set (attr "athlon_decode")
7165 (cond [(eq_attr "cpu" "athlon")
7166 (const_string "vector")
7167 (eq_attr "alternative" "1")
7168 (const_string "vector")
7169 (and (eq_attr "alternative" "2")
7170 (match_operand 1 "memory_operand" ""))
7171 (const_string "vector")]
7172 (const_string "direct")))
7173 (set (attr "amdfam10_decode")
7174 (cond [(and (eq_attr "alternative" "0,1")
7175 (match_operand 1 "memory_operand" ""))
7176 (const_string "vector")]
7177 (const_string "direct")))
7178 (set_attr "mode" "DI")])
7180 (define_expand "mulsi3"
7181 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7182 (mult:SI (match_operand:SI 1 "register_operand" "")
7183 (match_operand:SI 2 "general_operand" "")))
7184 (clobber (reg:CC FLAGS_REG))])]
7189 ;; IMUL reg32, reg32, imm8 Direct
7190 ;; IMUL reg32, mem32, imm8 VectorPath
7191 ;; IMUL reg32, reg32, imm32 Direct
7192 ;; IMUL reg32, mem32, imm32 VectorPath
7193 ;; IMUL reg32, reg32 Direct
7194 ;; IMUL reg32, mem32 Direct
7196 (define_insn "*mulsi3_1"
7197 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7198 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7199 (match_operand:SI 2 "general_operand" "K,i,mr")))
7200 (clobber (reg:CC FLAGS_REG))]
7201 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7203 imul{l}\t{%2, %1, %0|%0, %1, %2}
7204 imul{l}\t{%2, %1, %0|%0, %1, %2}
7205 imul{l}\t{%2, %0|%0, %2}"
7206 [(set_attr "type" "imul")
7207 (set_attr "prefix_0f" "0,0,1")
7208 (set (attr "athlon_decode")
7209 (cond [(eq_attr "cpu" "athlon")
7210 (const_string "vector")
7211 (eq_attr "alternative" "1")
7212 (const_string "vector")
7213 (and (eq_attr "alternative" "2")
7214 (match_operand 1 "memory_operand" ""))
7215 (const_string "vector")]
7216 (const_string "direct")))
7217 (set (attr "amdfam10_decode")
7218 (cond [(and (eq_attr "alternative" "0,1")
7219 (match_operand 1 "memory_operand" ""))
7220 (const_string "vector")]
7221 (const_string "direct")))
7222 (set_attr "mode" "SI")])
7224 (define_insn "*mulsi3_1_zext"
7225 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7227 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7228 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7229 (clobber (reg:CC FLAGS_REG))]
7231 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7233 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7234 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7235 imul{l}\t{%2, %k0|%k0, %2}"
7236 [(set_attr "type" "imul")
7237 (set_attr "prefix_0f" "0,0,1")
7238 (set (attr "athlon_decode")
7239 (cond [(eq_attr "cpu" "athlon")
7240 (const_string "vector")
7241 (eq_attr "alternative" "1")
7242 (const_string "vector")
7243 (and (eq_attr "alternative" "2")
7244 (match_operand 1 "memory_operand" ""))
7245 (const_string "vector")]
7246 (const_string "direct")))
7247 (set (attr "amdfam10_decode")
7248 (cond [(and (eq_attr "alternative" "0,1")
7249 (match_operand 1 "memory_operand" ""))
7250 (const_string "vector")]
7251 (const_string "direct")))
7252 (set_attr "mode" "SI")])
7254 (define_expand "mulhi3"
7255 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7256 (mult:HI (match_operand:HI 1 "register_operand" "")
7257 (match_operand:HI 2 "general_operand" "")))
7258 (clobber (reg:CC FLAGS_REG))])]
7259 "TARGET_HIMODE_MATH"
7263 ;; IMUL reg16, reg16, imm8 VectorPath
7264 ;; IMUL reg16, mem16, imm8 VectorPath
7265 ;; IMUL reg16, reg16, imm16 VectorPath
7266 ;; IMUL reg16, mem16, imm16 VectorPath
7267 ;; IMUL reg16, reg16 Direct
7268 ;; IMUL reg16, mem16 Direct
7269 (define_insn "*mulhi3_1"
7270 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7271 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7272 (match_operand:HI 2 "general_operand" "K,i,mr")))
7273 (clobber (reg:CC FLAGS_REG))]
7274 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7276 imul{w}\t{%2, %1, %0|%0, %1, %2}
7277 imul{w}\t{%2, %1, %0|%0, %1, %2}
7278 imul{w}\t{%2, %0|%0, %2}"
7279 [(set_attr "type" "imul")
7280 (set_attr "prefix_0f" "0,0,1")
7281 (set (attr "athlon_decode")
7282 (cond [(eq_attr "cpu" "athlon")
7283 (const_string "vector")
7284 (eq_attr "alternative" "1,2")
7285 (const_string "vector")]
7286 (const_string "direct")))
7287 (set (attr "amdfam10_decode")
7288 (cond [(eq_attr "alternative" "0,1")
7289 (const_string "vector")]
7290 (const_string "direct")))
7291 (set_attr "mode" "HI")])
7293 (define_expand "mulqi3"
7294 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7295 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7296 (match_operand:QI 2 "register_operand" "")))
7297 (clobber (reg:CC FLAGS_REG))])]
7298 "TARGET_QIMODE_MATH"
7305 (define_insn "*mulqi3_1"
7306 [(set (match_operand:QI 0 "register_operand" "=a")
7307 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7308 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7309 (clobber (reg:CC FLAGS_REG))]
7311 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7313 [(set_attr "type" "imul")
7314 (set_attr "length_immediate" "0")
7315 (set (attr "athlon_decode")
7316 (if_then_else (eq_attr "cpu" "athlon")
7317 (const_string "vector")
7318 (const_string "direct")))
7319 (set_attr "amdfam10_decode" "direct")
7320 (set_attr "mode" "QI")])
7322 (define_expand "umulqihi3"
7323 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7324 (mult:HI (zero_extend:HI
7325 (match_operand:QI 1 "nonimmediate_operand" ""))
7327 (match_operand:QI 2 "register_operand" ""))))
7328 (clobber (reg:CC FLAGS_REG))])]
7329 "TARGET_QIMODE_MATH"
7332 (define_insn "*umulqihi3_1"
7333 [(set (match_operand:HI 0 "register_operand" "=a")
7334 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7335 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7336 (clobber (reg:CC FLAGS_REG))]
7338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7340 [(set_attr "type" "imul")
7341 (set_attr "length_immediate" "0")
7342 (set (attr "athlon_decode")
7343 (if_then_else (eq_attr "cpu" "athlon")
7344 (const_string "vector")
7345 (const_string "direct")))
7346 (set_attr "amdfam10_decode" "direct")
7347 (set_attr "mode" "QI")])
7349 (define_expand "mulqihi3"
7350 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7351 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7352 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7353 (clobber (reg:CC FLAGS_REG))])]
7354 "TARGET_QIMODE_MATH"
7357 (define_insn "*mulqihi3_insn"
7358 [(set (match_operand:HI 0 "register_operand" "=a")
7359 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7360 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7361 (clobber (reg:CC FLAGS_REG))]
7363 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7365 [(set_attr "type" "imul")
7366 (set_attr "length_immediate" "0")
7367 (set (attr "athlon_decode")
7368 (if_then_else (eq_attr "cpu" "athlon")
7369 (const_string "vector")
7370 (const_string "direct")))
7371 (set_attr "amdfam10_decode" "direct")
7372 (set_attr "mode" "QI")])
7374 (define_expand "umulditi3"
7375 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7376 (mult:TI (zero_extend:TI
7377 (match_operand:DI 1 "nonimmediate_operand" ""))
7379 (match_operand:DI 2 "register_operand" ""))))
7380 (clobber (reg:CC FLAGS_REG))])]
7384 (define_insn "*umulditi3_insn"
7385 [(set (match_operand:TI 0 "register_operand" "=A")
7386 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7387 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7388 (clobber (reg:CC FLAGS_REG))]
7390 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7392 [(set_attr "type" "imul")
7393 (set_attr "length_immediate" "0")
7394 (set (attr "athlon_decode")
7395 (if_then_else (eq_attr "cpu" "athlon")
7396 (const_string "vector")
7397 (const_string "double")))
7398 (set_attr "amdfam10_decode" "double")
7399 (set_attr "mode" "DI")])
7401 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7402 (define_expand "umulsidi3"
7403 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7404 (mult:DI (zero_extend:DI
7405 (match_operand:SI 1 "nonimmediate_operand" ""))
7407 (match_operand:SI 2 "register_operand" ""))))
7408 (clobber (reg:CC FLAGS_REG))])]
7412 (define_insn "*umulsidi3_insn"
7413 [(set (match_operand:DI 0 "register_operand" "=A")
7414 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7415 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7416 (clobber (reg:CC FLAGS_REG))]
7418 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7420 [(set_attr "type" "imul")
7421 (set_attr "length_immediate" "0")
7422 (set (attr "athlon_decode")
7423 (if_then_else (eq_attr "cpu" "athlon")
7424 (const_string "vector")
7425 (const_string "double")))
7426 (set_attr "amdfam10_decode" "double")
7427 (set_attr "mode" "SI")])
7429 (define_expand "mulditi3"
7430 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7431 (mult:TI (sign_extend:TI
7432 (match_operand:DI 1 "nonimmediate_operand" ""))
7434 (match_operand:DI 2 "register_operand" ""))))
7435 (clobber (reg:CC FLAGS_REG))])]
7439 (define_insn "*mulditi3_insn"
7440 [(set (match_operand:TI 0 "register_operand" "=A")
7441 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7442 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7443 (clobber (reg:CC FLAGS_REG))]
7445 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7447 [(set_attr "type" "imul")
7448 (set_attr "length_immediate" "0")
7449 (set (attr "athlon_decode")
7450 (if_then_else (eq_attr "cpu" "athlon")
7451 (const_string "vector")
7452 (const_string "double")))
7453 (set_attr "amdfam10_decode" "double")
7454 (set_attr "mode" "DI")])
7456 (define_expand "mulsidi3"
7457 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7458 (mult:DI (sign_extend:DI
7459 (match_operand:SI 1 "nonimmediate_operand" ""))
7461 (match_operand:SI 2 "register_operand" ""))))
7462 (clobber (reg:CC FLAGS_REG))])]
7466 (define_insn "*mulsidi3_insn"
7467 [(set (match_operand:DI 0 "register_operand" "=A")
7468 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7469 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7470 (clobber (reg:CC FLAGS_REG))]
7472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7474 [(set_attr "type" "imul")
7475 (set_attr "length_immediate" "0")
7476 (set (attr "athlon_decode")
7477 (if_then_else (eq_attr "cpu" "athlon")
7478 (const_string "vector")
7479 (const_string "double")))
7480 (set_attr "amdfam10_decode" "double")
7481 (set_attr "mode" "SI")])
7483 (define_expand "umuldi3_highpart"
7484 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7487 (mult:TI (zero_extend:TI
7488 (match_operand:DI 1 "nonimmediate_operand" ""))
7490 (match_operand:DI 2 "register_operand" "")))
7492 (clobber (match_scratch:DI 3 ""))
7493 (clobber (reg:CC FLAGS_REG))])]
7497 (define_insn "*umuldi3_highpart_rex64"
7498 [(set (match_operand:DI 0 "register_operand" "=d")
7501 (mult:TI (zero_extend:TI
7502 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7504 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7506 (clobber (match_scratch:DI 3 "=1"))
7507 (clobber (reg:CC FLAGS_REG))]
7509 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7511 [(set_attr "type" "imul")
7512 (set_attr "length_immediate" "0")
7513 (set (attr "athlon_decode")
7514 (if_then_else (eq_attr "cpu" "athlon")
7515 (const_string "vector")
7516 (const_string "double")))
7517 (set_attr "amdfam10_decode" "double")
7518 (set_attr "mode" "DI")])
7520 (define_expand "umulsi3_highpart"
7521 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7524 (mult:DI (zero_extend:DI
7525 (match_operand:SI 1 "nonimmediate_operand" ""))
7527 (match_operand:SI 2 "register_operand" "")))
7529 (clobber (match_scratch:SI 3 ""))
7530 (clobber (reg:CC FLAGS_REG))])]
7534 (define_insn "*umulsi3_highpart_insn"
7535 [(set (match_operand:SI 0 "register_operand" "=d")
7538 (mult:DI (zero_extend:DI
7539 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7541 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7543 (clobber (match_scratch:SI 3 "=1"))
7544 (clobber (reg:CC FLAGS_REG))]
7545 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7547 [(set_attr "type" "imul")
7548 (set_attr "length_immediate" "0")
7549 (set (attr "athlon_decode")
7550 (if_then_else (eq_attr "cpu" "athlon")
7551 (const_string "vector")
7552 (const_string "double")))
7553 (set_attr "amdfam10_decode" "double")
7554 (set_attr "mode" "SI")])
7556 (define_insn "*umulsi3_highpart_zext"
7557 [(set (match_operand:DI 0 "register_operand" "=d")
7558 (zero_extend:DI (truncate:SI
7560 (mult:DI (zero_extend:DI
7561 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7563 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7565 (clobber (match_scratch:SI 3 "=1"))
7566 (clobber (reg:CC FLAGS_REG))]
7568 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7570 [(set_attr "type" "imul")
7571 (set_attr "length_immediate" "0")
7572 (set (attr "athlon_decode")
7573 (if_then_else (eq_attr "cpu" "athlon")
7574 (const_string "vector")
7575 (const_string "double")))
7576 (set_attr "amdfam10_decode" "double")
7577 (set_attr "mode" "SI")])
7579 (define_expand "smuldi3_highpart"
7580 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7583 (mult:TI (sign_extend:TI
7584 (match_operand:DI 1 "nonimmediate_operand" ""))
7586 (match_operand:DI 2 "register_operand" "")))
7588 (clobber (match_scratch:DI 3 ""))
7589 (clobber (reg:CC FLAGS_REG))])]
7593 (define_insn "*smuldi3_highpart_rex64"
7594 [(set (match_operand:DI 0 "register_operand" "=d")
7597 (mult:TI (sign_extend:TI
7598 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7600 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7602 (clobber (match_scratch:DI 3 "=1"))
7603 (clobber (reg:CC FLAGS_REG))]
7605 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7607 [(set_attr "type" "imul")
7608 (set (attr "athlon_decode")
7609 (if_then_else (eq_attr "cpu" "athlon")
7610 (const_string "vector")
7611 (const_string "double")))
7612 (set_attr "amdfam10_decode" "double")
7613 (set_attr "mode" "DI")])
7615 (define_expand "smulsi3_highpart"
7616 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7619 (mult:DI (sign_extend:DI
7620 (match_operand:SI 1 "nonimmediate_operand" ""))
7622 (match_operand:SI 2 "register_operand" "")))
7624 (clobber (match_scratch:SI 3 ""))
7625 (clobber (reg:CC FLAGS_REG))])]
7629 (define_insn "*smulsi3_highpart_insn"
7630 [(set (match_operand:SI 0 "register_operand" "=d")
7633 (mult:DI (sign_extend:DI
7634 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7636 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7638 (clobber (match_scratch:SI 3 "=1"))
7639 (clobber (reg:CC FLAGS_REG))]
7640 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7642 [(set_attr "type" "imul")
7643 (set (attr "athlon_decode")
7644 (if_then_else (eq_attr "cpu" "athlon")
7645 (const_string "vector")
7646 (const_string "double")))
7647 (set_attr "amdfam10_decode" "double")
7648 (set_attr "mode" "SI")])
7650 (define_insn "*smulsi3_highpart_zext"
7651 [(set (match_operand:DI 0 "register_operand" "=d")
7652 (zero_extend:DI (truncate:SI
7654 (mult:DI (sign_extend:DI
7655 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7657 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7659 (clobber (match_scratch:SI 3 "=1"))
7660 (clobber (reg:CC FLAGS_REG))]
7662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7664 [(set_attr "type" "imul")
7665 (set (attr "athlon_decode")
7666 (if_then_else (eq_attr "cpu" "athlon")
7667 (const_string "vector")
7668 (const_string "double")))
7669 (set_attr "amdfam10_decode" "double")
7670 (set_attr "mode" "SI")])
7672 ;; The patterns that match these are at the end of this file.
7674 (define_expand "mulxf3"
7675 [(set (match_operand:XF 0 "register_operand" "")
7676 (mult:XF (match_operand:XF 1 "register_operand" "")
7677 (match_operand:XF 2 "register_operand" "")))]
7681 (define_expand "muldf3"
7682 [(set (match_operand:DF 0 "register_operand" "")
7683 (mult:DF (match_operand:DF 1 "register_operand" "")
7684 (match_operand:DF 2 "nonimmediate_operand" "")))]
7685 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7688 (define_expand "mulsf3"
7689 [(set (match_operand:SF 0 "register_operand" "")
7690 (mult:SF (match_operand:SF 1 "register_operand" "")
7691 (match_operand:SF 2 "nonimmediate_operand" "")))]
7692 "TARGET_80387 || TARGET_SSE_MATH"
7695 ;; Divide instructions
7697 (define_insn "divqi3"
7698 [(set (match_operand:QI 0 "register_operand" "=a")
7699 (div:QI (match_operand:HI 1 "register_operand" "0")
7700 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7701 (clobber (reg:CC FLAGS_REG))]
7702 "TARGET_QIMODE_MATH"
7704 [(set_attr "type" "idiv")
7705 (set_attr "mode" "QI")])
7707 (define_insn "udivqi3"
7708 [(set (match_operand:QI 0 "register_operand" "=a")
7709 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7710 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7711 (clobber (reg:CC FLAGS_REG))]
7712 "TARGET_QIMODE_MATH"
7714 [(set_attr "type" "idiv")
7715 (set_attr "mode" "QI")])
7717 ;; The patterns that match these are at the end of this file.
7719 (define_expand "divxf3"
7720 [(set (match_operand:XF 0 "register_operand" "")
7721 (div:XF (match_operand:XF 1 "register_operand" "")
7722 (match_operand:XF 2 "register_operand" "")))]
7726 (define_expand "divdf3"
7727 [(set (match_operand:DF 0 "register_operand" "")
7728 (div:DF (match_operand:DF 1 "register_operand" "")
7729 (match_operand:DF 2 "nonimmediate_operand" "")))]
7730 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7733 (define_expand "divsf3"
7734 [(set (match_operand:SF 0 "register_operand" "")
7735 (div:SF (match_operand:SF 1 "register_operand" "")
7736 (match_operand:SF 2 "nonimmediate_operand" "")))]
7737 "TARGET_80387 || TARGET_SSE_MATH"
7740 ;; Remainder instructions.
7742 (define_expand "divmoddi4"
7743 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7744 (div:DI (match_operand:DI 1 "register_operand" "")
7745 (match_operand:DI 2 "nonimmediate_operand" "")))
7746 (set (match_operand:DI 3 "register_operand" "")
7747 (mod:DI (match_dup 1) (match_dup 2)))
7748 (clobber (reg:CC FLAGS_REG))])]
7752 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7753 ;; Penalize eax case slightly because it results in worse scheduling
7755 (define_insn "*divmoddi4_nocltd_rex64"
7756 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7757 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7758 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7759 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7760 (mod:DI (match_dup 2) (match_dup 3)))
7761 (clobber (reg:CC FLAGS_REG))]
7762 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7764 [(set_attr "type" "multi")])
7766 (define_insn "*divmoddi4_cltd_rex64"
7767 [(set (match_operand:DI 0 "register_operand" "=a")
7768 (div:DI (match_operand:DI 2 "register_operand" "a")
7769 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7770 (set (match_operand:DI 1 "register_operand" "=&d")
7771 (mod:DI (match_dup 2) (match_dup 3)))
7772 (clobber (reg:CC FLAGS_REG))]
7773 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7775 [(set_attr "type" "multi")])
7777 (define_insn "*divmoddi_noext_rex64"
7778 [(set (match_operand:DI 0 "register_operand" "=a")
7779 (div:DI (match_operand:DI 1 "register_operand" "0")
7780 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7781 (set (match_operand:DI 3 "register_operand" "=d")
7782 (mod:DI (match_dup 1) (match_dup 2)))
7783 (use (match_operand:DI 4 "register_operand" "3"))
7784 (clobber (reg:CC FLAGS_REG))]
7787 [(set_attr "type" "idiv")
7788 (set_attr "mode" "DI")])
7791 [(set (match_operand:DI 0 "register_operand" "")
7792 (div:DI (match_operand:DI 1 "register_operand" "")
7793 (match_operand:DI 2 "nonimmediate_operand" "")))
7794 (set (match_operand:DI 3 "register_operand" "")
7795 (mod:DI (match_dup 1) (match_dup 2)))
7796 (clobber (reg:CC FLAGS_REG))]
7797 "TARGET_64BIT && reload_completed"
7798 [(parallel [(set (match_dup 3)
7799 (ashiftrt:DI (match_dup 4) (const_int 63)))
7800 (clobber (reg:CC FLAGS_REG))])
7801 (parallel [(set (match_dup 0)
7802 (div:DI (reg:DI 0) (match_dup 2)))
7804 (mod:DI (reg:DI 0) (match_dup 2)))
7806 (clobber (reg:CC FLAGS_REG))])]
7808 /* Avoid use of cltd in favor of a mov+shift. */
7809 if (!TARGET_USE_CLTD && !optimize_size)
7811 if (true_regnum (operands[1]))
7812 emit_move_insn (operands[0], operands[1]);
7814 emit_move_insn (operands[3], operands[1]);
7815 operands[4] = operands[3];
7819 gcc_assert (!true_regnum (operands[1]));
7820 operands[4] = operands[1];
7825 (define_expand "divmodsi4"
7826 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7827 (div:SI (match_operand:SI 1 "register_operand" "")
7828 (match_operand:SI 2 "nonimmediate_operand" "")))
7829 (set (match_operand:SI 3 "register_operand" "")
7830 (mod:SI (match_dup 1) (match_dup 2)))
7831 (clobber (reg:CC FLAGS_REG))])]
7835 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7836 ;; Penalize eax case slightly because it results in worse scheduling
7838 (define_insn "*divmodsi4_nocltd"
7839 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7840 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7841 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7842 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7843 (mod:SI (match_dup 2) (match_dup 3)))
7844 (clobber (reg:CC FLAGS_REG))]
7845 "!optimize_size && !TARGET_USE_CLTD"
7847 [(set_attr "type" "multi")])
7849 (define_insn "*divmodsi4_cltd"
7850 [(set (match_operand:SI 0 "register_operand" "=a")
7851 (div:SI (match_operand:SI 2 "register_operand" "a")
7852 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7853 (set (match_operand:SI 1 "register_operand" "=&d")
7854 (mod:SI (match_dup 2) (match_dup 3)))
7855 (clobber (reg:CC FLAGS_REG))]
7856 "optimize_size || TARGET_USE_CLTD"
7858 [(set_attr "type" "multi")])
7860 (define_insn "*divmodsi_noext"
7861 [(set (match_operand:SI 0 "register_operand" "=a")
7862 (div:SI (match_operand:SI 1 "register_operand" "0")
7863 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7864 (set (match_operand:SI 3 "register_operand" "=d")
7865 (mod:SI (match_dup 1) (match_dup 2)))
7866 (use (match_operand:SI 4 "register_operand" "3"))
7867 (clobber (reg:CC FLAGS_REG))]
7870 [(set_attr "type" "idiv")
7871 (set_attr "mode" "SI")])
7874 [(set (match_operand:SI 0 "register_operand" "")
7875 (div:SI (match_operand:SI 1 "register_operand" "")
7876 (match_operand:SI 2 "nonimmediate_operand" "")))
7877 (set (match_operand:SI 3 "register_operand" "")
7878 (mod:SI (match_dup 1) (match_dup 2)))
7879 (clobber (reg:CC FLAGS_REG))]
7881 [(parallel [(set (match_dup 3)
7882 (ashiftrt:SI (match_dup 4) (const_int 31)))
7883 (clobber (reg:CC FLAGS_REG))])
7884 (parallel [(set (match_dup 0)
7885 (div:SI (reg:SI 0) (match_dup 2)))
7887 (mod:SI (reg:SI 0) (match_dup 2)))
7889 (clobber (reg:CC FLAGS_REG))])]
7891 /* Avoid use of cltd in favor of a mov+shift. */
7892 if (!TARGET_USE_CLTD && !optimize_size)
7894 if (true_regnum (operands[1]))
7895 emit_move_insn (operands[0], operands[1]);
7897 emit_move_insn (operands[3], operands[1]);
7898 operands[4] = operands[3];
7902 gcc_assert (!true_regnum (operands[1]));
7903 operands[4] = operands[1];
7907 (define_insn "divmodhi4"
7908 [(set (match_operand:HI 0 "register_operand" "=a")
7909 (div:HI (match_operand:HI 1 "register_operand" "0")
7910 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7911 (set (match_operand:HI 3 "register_operand" "=&d")
7912 (mod:HI (match_dup 1) (match_dup 2)))
7913 (clobber (reg:CC FLAGS_REG))]
7914 "TARGET_HIMODE_MATH"
7916 [(set_attr "type" "multi")
7917 (set_attr "length_immediate" "0")
7918 (set_attr "mode" "SI")])
7920 (define_insn "udivmoddi4"
7921 [(set (match_operand:DI 0 "register_operand" "=a")
7922 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7923 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7924 (set (match_operand:DI 3 "register_operand" "=&d")
7925 (umod:DI (match_dup 1) (match_dup 2)))
7926 (clobber (reg:CC FLAGS_REG))]
7928 "xor{q}\t%3, %3\;div{q}\t%2"
7929 [(set_attr "type" "multi")
7930 (set_attr "length_immediate" "0")
7931 (set_attr "mode" "DI")])
7933 (define_insn "*udivmoddi4_noext"
7934 [(set (match_operand:DI 0 "register_operand" "=a")
7935 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7936 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7937 (set (match_operand:DI 3 "register_operand" "=d")
7938 (umod:DI (match_dup 1) (match_dup 2)))
7940 (clobber (reg:CC FLAGS_REG))]
7943 [(set_attr "type" "idiv")
7944 (set_attr "mode" "DI")])
7947 [(set (match_operand:DI 0 "register_operand" "")
7948 (udiv:DI (match_operand:DI 1 "register_operand" "")
7949 (match_operand:DI 2 "nonimmediate_operand" "")))
7950 (set (match_operand:DI 3 "register_operand" "")
7951 (umod:DI (match_dup 1) (match_dup 2)))
7952 (clobber (reg:CC FLAGS_REG))]
7953 "TARGET_64BIT && reload_completed"
7954 [(set (match_dup 3) (const_int 0))
7955 (parallel [(set (match_dup 0)
7956 (udiv:DI (match_dup 1) (match_dup 2)))
7958 (umod:DI (match_dup 1) (match_dup 2)))
7960 (clobber (reg:CC FLAGS_REG))])]
7963 (define_insn "udivmodsi4"
7964 [(set (match_operand:SI 0 "register_operand" "=a")
7965 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7966 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7967 (set (match_operand:SI 3 "register_operand" "=&d")
7968 (umod:SI (match_dup 1) (match_dup 2)))
7969 (clobber (reg:CC FLAGS_REG))]
7971 "xor{l}\t%3, %3\;div{l}\t%2"
7972 [(set_attr "type" "multi")
7973 (set_attr "length_immediate" "0")
7974 (set_attr "mode" "SI")])
7976 (define_insn "*udivmodsi4_noext"
7977 [(set (match_operand:SI 0 "register_operand" "=a")
7978 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7979 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7980 (set (match_operand:SI 3 "register_operand" "=d")
7981 (umod:SI (match_dup 1) (match_dup 2)))
7983 (clobber (reg:CC FLAGS_REG))]
7986 [(set_attr "type" "idiv")
7987 (set_attr "mode" "SI")])
7990 [(set (match_operand:SI 0 "register_operand" "")
7991 (udiv:SI (match_operand:SI 1 "register_operand" "")
7992 (match_operand:SI 2 "nonimmediate_operand" "")))
7993 (set (match_operand:SI 3 "register_operand" "")
7994 (umod:SI (match_dup 1) (match_dup 2)))
7995 (clobber (reg:CC FLAGS_REG))]
7997 [(set (match_dup 3) (const_int 0))
7998 (parallel [(set (match_dup 0)
7999 (udiv:SI (match_dup 1) (match_dup 2)))
8001 (umod:SI (match_dup 1) (match_dup 2)))
8003 (clobber (reg:CC FLAGS_REG))])]
8006 (define_expand "udivmodhi4"
8007 [(set (match_dup 4) (const_int 0))
8008 (parallel [(set (match_operand:HI 0 "register_operand" "")
8009 (udiv:HI (match_operand:HI 1 "register_operand" "")
8010 (match_operand:HI 2 "nonimmediate_operand" "")))
8011 (set (match_operand:HI 3 "register_operand" "")
8012 (umod:HI (match_dup 1) (match_dup 2)))
8014 (clobber (reg:CC FLAGS_REG))])]
8015 "TARGET_HIMODE_MATH"
8016 "operands[4] = gen_reg_rtx (HImode);")
8018 (define_insn "*udivmodhi_noext"
8019 [(set (match_operand:HI 0 "register_operand" "=a")
8020 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8021 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8022 (set (match_operand:HI 3 "register_operand" "=d")
8023 (umod:HI (match_dup 1) (match_dup 2)))
8024 (use (match_operand:HI 4 "register_operand" "3"))
8025 (clobber (reg:CC FLAGS_REG))]
8028 [(set_attr "type" "idiv")
8029 (set_attr "mode" "HI")])
8031 ;; We cannot use div/idiv for double division, because it causes
8032 ;; "division by zero" on the overflow and that's not what we expect
8033 ;; from truncate. Because true (non truncating) double division is
8034 ;; never generated, we can't create this insn anyway.
8037 ; [(set (match_operand:SI 0 "register_operand" "=a")
8039 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8041 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8042 ; (set (match_operand:SI 3 "register_operand" "=d")
8044 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8045 ; (clobber (reg:CC FLAGS_REG))]
8047 ; "div{l}\t{%2, %0|%0, %2}"
8048 ; [(set_attr "type" "idiv")])
8050 ;;- Logical AND instructions
8052 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8053 ;; Note that this excludes ah.
8055 (define_insn "*testdi_1_rex64"
8056 [(set (reg FLAGS_REG)
8058 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8059 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8061 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8062 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8064 test{l}\t{%k1, %k0|%k0, %k1}
8065 test{l}\t{%k1, %k0|%k0, %k1}
8066 test{q}\t{%1, %0|%0, %1}
8067 test{q}\t{%1, %0|%0, %1}
8068 test{q}\t{%1, %0|%0, %1}"
8069 [(set_attr "type" "test")
8070 (set_attr "modrm" "0,1,0,1,1")
8071 (set_attr "mode" "SI,SI,DI,DI,DI")
8072 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8074 (define_insn "testsi_1"
8075 [(set (reg FLAGS_REG)
8077 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8078 (match_operand:SI 1 "general_operand" "in,in,rin"))
8080 "ix86_match_ccmode (insn, CCNOmode)
8081 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8082 "test{l}\t{%1, %0|%0, %1}"
8083 [(set_attr "type" "test")
8084 (set_attr "modrm" "0,1,1")
8085 (set_attr "mode" "SI")
8086 (set_attr "pent_pair" "uv,np,uv")])
8088 (define_expand "testsi_ccno_1"
8089 [(set (reg:CCNO FLAGS_REG)
8091 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8092 (match_operand:SI 1 "nonmemory_operand" ""))
8097 (define_insn "*testhi_1"
8098 [(set (reg FLAGS_REG)
8099 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8100 (match_operand:HI 1 "general_operand" "n,n,rn"))
8102 "ix86_match_ccmode (insn, CCNOmode)
8103 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8104 "test{w}\t{%1, %0|%0, %1}"
8105 [(set_attr "type" "test")
8106 (set_attr "modrm" "0,1,1")
8107 (set_attr "mode" "HI")
8108 (set_attr "pent_pair" "uv,np,uv")])
8110 (define_expand "testqi_ccz_1"
8111 [(set (reg:CCZ FLAGS_REG)
8112 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8113 (match_operand:QI 1 "nonmemory_operand" ""))
8118 (define_insn "*testqi_1_maybe_si"
8119 [(set (reg FLAGS_REG)
8122 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8123 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8125 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8126 && ix86_match_ccmode (insn,
8127 CONST_INT_P (operands[1])
8128 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8130 if (which_alternative == 3)
8132 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8133 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8134 return "test{l}\t{%1, %k0|%k0, %1}";
8136 return "test{b}\t{%1, %0|%0, %1}";
8138 [(set_attr "type" "test")
8139 (set_attr "modrm" "0,1,1,1")
8140 (set_attr "mode" "QI,QI,QI,SI")
8141 (set_attr "pent_pair" "uv,np,uv,np")])
8143 (define_insn "*testqi_1"
8144 [(set (reg FLAGS_REG)
8147 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8148 (match_operand:QI 1 "general_operand" "n,n,qn"))
8150 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8151 && ix86_match_ccmode (insn, CCNOmode)"
8152 "test{b}\t{%1, %0|%0, %1}"
8153 [(set_attr "type" "test")
8154 (set_attr "modrm" "0,1,1")
8155 (set_attr "mode" "QI")
8156 (set_attr "pent_pair" "uv,np,uv")])
8158 (define_expand "testqi_ext_ccno_0"
8159 [(set (reg:CCNO FLAGS_REG)
8163 (match_operand 0 "ext_register_operand" "")
8166 (match_operand 1 "const_int_operand" ""))
8171 (define_insn "*testqi_ext_0"
8172 [(set (reg FLAGS_REG)
8176 (match_operand 0 "ext_register_operand" "Q")
8179 (match_operand 1 "const_int_operand" "n"))
8181 "ix86_match_ccmode (insn, CCNOmode)"
8182 "test{b}\t{%1, %h0|%h0, %1}"
8183 [(set_attr "type" "test")
8184 (set_attr "mode" "QI")
8185 (set_attr "length_immediate" "1")
8186 (set_attr "pent_pair" "np")])
8188 (define_insn "*testqi_ext_1"
8189 [(set (reg FLAGS_REG)
8193 (match_operand 0 "ext_register_operand" "Q")
8197 (match_operand:QI 1 "general_operand" "Qm")))
8199 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8200 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8201 "test{b}\t{%1, %h0|%h0, %1}"
8202 [(set_attr "type" "test")
8203 (set_attr "mode" "QI")])
8205 (define_insn "*testqi_ext_1_rex64"
8206 [(set (reg FLAGS_REG)
8210 (match_operand 0 "ext_register_operand" "Q")
8214 (match_operand:QI 1 "register_operand" "Q")))
8216 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8217 "test{b}\t{%1, %h0|%h0, %1}"
8218 [(set_attr "type" "test")
8219 (set_attr "mode" "QI")])
8221 (define_insn "*testqi_ext_2"
8222 [(set (reg FLAGS_REG)
8226 (match_operand 0 "ext_register_operand" "Q")
8230 (match_operand 1 "ext_register_operand" "Q")
8234 "ix86_match_ccmode (insn, CCNOmode)"
8235 "test{b}\t{%h1, %h0|%h0, %h1}"
8236 [(set_attr "type" "test")
8237 (set_attr "mode" "QI")])
8239 ;; Combine likes to form bit extractions for some tests. Humor it.
8240 (define_insn "*testqi_ext_3"
8241 [(set (reg FLAGS_REG)
8242 (compare (zero_extract:SI
8243 (match_operand 0 "nonimmediate_operand" "rm")
8244 (match_operand:SI 1 "const_int_operand" "")
8245 (match_operand:SI 2 "const_int_operand" ""))
8247 "ix86_match_ccmode (insn, CCNOmode)
8248 && INTVAL (operands[1]) > 0
8249 && INTVAL (operands[2]) >= 0
8250 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8251 && (GET_MODE (operands[0]) == SImode
8252 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8253 || GET_MODE (operands[0]) == HImode
8254 || GET_MODE (operands[0]) == QImode)"
8257 (define_insn "*testqi_ext_3_rex64"
8258 [(set (reg FLAGS_REG)
8259 (compare (zero_extract:DI
8260 (match_operand 0 "nonimmediate_operand" "rm")
8261 (match_operand:DI 1 "const_int_operand" "")
8262 (match_operand:DI 2 "const_int_operand" ""))
8265 && ix86_match_ccmode (insn, CCNOmode)
8266 && INTVAL (operands[1]) > 0
8267 && INTVAL (operands[2]) >= 0
8268 /* Ensure that resulting mask is zero or sign extended operand. */
8269 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8270 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8271 && INTVAL (operands[1]) > 32))
8272 && (GET_MODE (operands[0]) == SImode
8273 || GET_MODE (operands[0]) == DImode
8274 || GET_MODE (operands[0]) == HImode
8275 || GET_MODE (operands[0]) == QImode)"
8279 [(set (match_operand 0 "flags_reg_operand" "")
8280 (match_operator 1 "compare_operator"
8282 (match_operand 2 "nonimmediate_operand" "")
8283 (match_operand 3 "const_int_operand" "")
8284 (match_operand 4 "const_int_operand" ""))
8286 "ix86_match_ccmode (insn, CCNOmode)"
8287 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8289 rtx val = operands[2];
8290 HOST_WIDE_INT len = INTVAL (operands[3]);
8291 HOST_WIDE_INT pos = INTVAL (operands[4]);
8293 enum machine_mode mode, submode;
8295 mode = GET_MODE (val);
8298 /* ??? Combine likes to put non-volatile mem extractions in QImode
8299 no matter the size of the test. So find a mode that works. */
8300 if (! MEM_VOLATILE_P (val))
8302 mode = smallest_mode_for_size (pos + len, MODE_INT);
8303 val = adjust_address (val, mode, 0);
8306 else if (GET_CODE (val) == SUBREG
8307 && (submode = GET_MODE (SUBREG_REG (val)),
8308 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8309 && pos + len <= GET_MODE_BITSIZE (submode))
8311 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8313 val = SUBREG_REG (val);
8315 else if (mode == HImode && pos + len <= 8)
8317 /* Small HImode tests can be converted to QImode. */
8319 val = gen_lowpart (QImode, val);
8322 if (len == HOST_BITS_PER_WIDE_INT)
8325 mask = ((HOST_WIDE_INT)1 << len) - 1;
8328 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8331 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8332 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8333 ;; this is relatively important trick.
8334 ;; Do the conversion only post-reload to avoid limiting of the register class
8337 [(set (match_operand 0 "flags_reg_operand" "")
8338 (match_operator 1 "compare_operator"
8339 [(and (match_operand 2 "register_operand" "")
8340 (match_operand 3 "const_int_operand" ""))
8343 && QI_REG_P (operands[2])
8344 && GET_MODE (operands[2]) != QImode
8345 && ((ix86_match_ccmode (insn, CCZmode)
8346 && !(INTVAL (operands[3]) & ~(255 << 8)))
8347 || (ix86_match_ccmode (insn, CCNOmode)
8348 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8351 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8354 "operands[2] = gen_lowpart (SImode, operands[2]);
8355 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8358 [(set (match_operand 0 "flags_reg_operand" "")
8359 (match_operator 1 "compare_operator"
8360 [(and (match_operand 2 "nonimmediate_operand" "")
8361 (match_operand 3 "const_int_operand" ""))
8364 && GET_MODE (operands[2]) != QImode
8365 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8366 && ((ix86_match_ccmode (insn, CCZmode)
8367 && !(INTVAL (operands[3]) & ~255))
8368 || (ix86_match_ccmode (insn, CCNOmode)
8369 && !(INTVAL (operands[3]) & ~127)))"
8371 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8373 "operands[2] = gen_lowpart (QImode, operands[2]);
8374 operands[3] = gen_lowpart (QImode, operands[3]);")
8377 ;; %%% This used to optimize known byte-wide and operations to memory,
8378 ;; and sometimes to QImode registers. If this is considered useful,
8379 ;; it should be done with splitters.
8381 (define_expand "anddi3"
8382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8383 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8384 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8385 (clobber (reg:CC FLAGS_REG))]
8387 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8389 (define_insn "*anddi_1_rex64"
8390 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8391 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8392 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8396 switch (get_attr_type (insn))
8400 enum machine_mode mode;
8402 gcc_assert (CONST_INT_P (operands[2]));
8403 if (INTVAL (operands[2]) == 0xff)
8407 gcc_assert (INTVAL (operands[2]) == 0xffff);
8411 operands[1] = gen_lowpart (mode, operands[1]);
8413 return "movz{bq|x}\t{%1,%0|%0, %1}";
8415 return "movz{wq|x}\t{%1,%0|%0, %1}";
8419 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8420 if (get_attr_mode (insn) == MODE_SI)
8421 return "and{l}\t{%k2, %k0|%k0, %k2}";
8423 return "and{q}\t{%2, %0|%0, %2}";
8426 [(set_attr "type" "alu,alu,alu,imovx")
8427 (set_attr "length_immediate" "*,*,*,0")
8428 (set_attr "mode" "SI,DI,DI,DI")])
8430 (define_insn "*anddi_2"
8431 [(set (reg FLAGS_REG)
8432 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8433 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8435 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8436 (and:DI (match_dup 1) (match_dup 2)))]
8437 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8438 && ix86_binary_operator_ok (AND, DImode, operands)"
8440 and{l}\t{%k2, %k0|%k0, %k2}
8441 and{q}\t{%2, %0|%0, %2}
8442 and{q}\t{%2, %0|%0, %2}"
8443 [(set_attr "type" "alu")
8444 (set_attr "mode" "SI,DI,DI")])
8446 (define_expand "andsi3"
8447 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8448 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8449 (match_operand:SI 2 "general_operand" "")))
8450 (clobber (reg:CC FLAGS_REG))]
8452 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8454 (define_insn "*andsi_1"
8455 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8456 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8457 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8458 (clobber (reg:CC FLAGS_REG))]
8459 "ix86_binary_operator_ok (AND, SImode, operands)"
8461 switch (get_attr_type (insn))
8465 enum machine_mode mode;
8467 gcc_assert (CONST_INT_P (operands[2]));
8468 if (INTVAL (operands[2]) == 0xff)
8472 gcc_assert (INTVAL (operands[2]) == 0xffff);
8476 operands[1] = gen_lowpart (mode, operands[1]);
8478 return "movz{bl|x}\t{%1,%0|%0, %1}";
8480 return "movz{wl|x}\t{%1,%0|%0, %1}";
8484 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8485 return "and{l}\t{%2, %0|%0, %2}";
8488 [(set_attr "type" "alu,alu,imovx")
8489 (set_attr "length_immediate" "*,*,0")
8490 (set_attr "mode" "SI")])
8493 [(set (match_operand 0 "register_operand" "")
8495 (const_int -65536)))
8496 (clobber (reg:CC FLAGS_REG))]
8497 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8498 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8499 "operands[1] = gen_lowpart (HImode, operands[0]);")
8502 [(set (match_operand 0 "ext_register_operand" "")
8505 (clobber (reg:CC FLAGS_REG))]
8506 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8507 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8508 "operands[1] = gen_lowpart (QImode, operands[0]);")
8511 [(set (match_operand 0 "ext_register_operand" "")
8513 (const_int -65281)))
8514 (clobber (reg:CC FLAGS_REG))]
8515 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8516 [(parallel [(set (zero_extract:SI (match_dup 0)
8520 (zero_extract:SI (match_dup 0)
8523 (zero_extract:SI (match_dup 0)
8526 (clobber (reg:CC FLAGS_REG))])]
8527 "operands[0] = gen_lowpart (SImode, operands[0]);")
8529 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8530 (define_insn "*andsi_1_zext"
8531 [(set (match_operand:DI 0 "register_operand" "=r")
8533 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8534 (match_operand:SI 2 "general_operand" "rim"))))
8535 (clobber (reg:CC FLAGS_REG))]
8536 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8537 "and{l}\t{%2, %k0|%k0, %2}"
8538 [(set_attr "type" "alu")
8539 (set_attr "mode" "SI")])
8541 (define_insn "*andsi_2"
8542 [(set (reg FLAGS_REG)
8543 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8544 (match_operand:SI 2 "general_operand" "rim,ri"))
8546 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8547 (and:SI (match_dup 1) (match_dup 2)))]
8548 "ix86_match_ccmode (insn, CCNOmode)
8549 && ix86_binary_operator_ok (AND, SImode, operands)"
8550 "and{l}\t{%2, %0|%0, %2}"
8551 [(set_attr "type" "alu")
8552 (set_attr "mode" "SI")])
8554 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8555 (define_insn "*andsi_2_zext"
8556 [(set (reg FLAGS_REG)
8557 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8558 (match_operand:SI 2 "general_operand" "rim"))
8560 (set (match_operand:DI 0 "register_operand" "=r")
8561 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8562 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8563 && ix86_binary_operator_ok (AND, SImode, operands)"
8564 "and{l}\t{%2, %k0|%k0, %2}"
8565 [(set_attr "type" "alu")
8566 (set_attr "mode" "SI")])
8568 (define_expand "andhi3"
8569 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8570 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8571 (match_operand:HI 2 "general_operand" "")))
8572 (clobber (reg:CC FLAGS_REG))]
8573 "TARGET_HIMODE_MATH"
8574 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8576 (define_insn "*andhi_1"
8577 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8578 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8579 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "ix86_binary_operator_ok (AND, HImode, operands)"
8583 switch (get_attr_type (insn))
8586 gcc_assert (CONST_INT_P (operands[2]));
8587 gcc_assert (INTVAL (operands[2]) == 0xff);
8588 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8593 return "and{w}\t{%2, %0|%0, %2}";
8596 [(set_attr "type" "alu,alu,imovx")
8597 (set_attr "length_immediate" "*,*,0")
8598 (set_attr "mode" "HI,HI,SI")])
8600 (define_insn "*andhi_2"
8601 [(set (reg FLAGS_REG)
8602 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8603 (match_operand:HI 2 "general_operand" "rim,ri"))
8605 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8606 (and:HI (match_dup 1) (match_dup 2)))]
8607 "ix86_match_ccmode (insn, CCNOmode)
8608 && ix86_binary_operator_ok (AND, HImode, operands)"
8609 "and{w}\t{%2, %0|%0, %2}"
8610 [(set_attr "type" "alu")
8611 (set_attr "mode" "HI")])
8613 (define_expand "andqi3"
8614 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8615 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8616 (match_operand:QI 2 "general_operand" "")))
8617 (clobber (reg:CC FLAGS_REG))]
8618 "TARGET_QIMODE_MATH"
8619 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8621 ;; %%% Potential partial reg stall on alternative 2. What to do?
8622 (define_insn "*andqi_1"
8623 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8624 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8625 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8626 (clobber (reg:CC FLAGS_REG))]
8627 "ix86_binary_operator_ok (AND, QImode, operands)"
8629 and{b}\t{%2, %0|%0, %2}
8630 and{b}\t{%2, %0|%0, %2}
8631 and{l}\t{%k2, %k0|%k0, %k2}"
8632 [(set_attr "type" "alu")
8633 (set_attr "mode" "QI,QI,SI")])
8635 (define_insn "*andqi_1_slp"
8636 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8637 (and:QI (match_dup 0)
8638 (match_operand:QI 1 "general_operand" "qi,qmi")))
8639 (clobber (reg:CC FLAGS_REG))]
8640 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8641 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8642 "and{b}\t{%1, %0|%0, %1}"
8643 [(set_attr "type" "alu1")
8644 (set_attr "mode" "QI")])
8646 (define_insn "*andqi_2_maybe_si"
8647 [(set (reg FLAGS_REG)
8649 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8650 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8652 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8653 (and:QI (match_dup 1) (match_dup 2)))]
8654 "ix86_binary_operator_ok (AND, QImode, operands)
8655 && ix86_match_ccmode (insn,
8656 CONST_INT_P (operands[2])
8657 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8659 if (which_alternative == 2)
8661 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8662 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8663 return "and{l}\t{%2, %k0|%k0, %2}";
8665 return "and{b}\t{%2, %0|%0, %2}";
8667 [(set_attr "type" "alu")
8668 (set_attr "mode" "QI,QI,SI")])
8670 (define_insn "*andqi_2"
8671 [(set (reg FLAGS_REG)
8673 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8674 (match_operand:QI 2 "general_operand" "qim,qi"))
8676 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8677 (and:QI (match_dup 1) (match_dup 2)))]
8678 "ix86_match_ccmode (insn, CCNOmode)
8679 && ix86_binary_operator_ok (AND, QImode, operands)"
8680 "and{b}\t{%2, %0|%0, %2}"
8681 [(set_attr "type" "alu")
8682 (set_attr "mode" "QI")])
8684 (define_insn "*andqi_2_slp"
8685 [(set (reg FLAGS_REG)
8687 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8688 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8690 (set (strict_low_part (match_dup 0))
8691 (and:QI (match_dup 0) (match_dup 1)))]
8692 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8693 && ix86_match_ccmode (insn, CCNOmode)
8694 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8695 "and{b}\t{%1, %0|%0, %1}"
8696 [(set_attr "type" "alu1")
8697 (set_attr "mode" "QI")])
8699 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8700 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8701 ;; for a QImode operand, which of course failed.
8703 (define_insn "andqi_ext_0"
8704 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8709 (match_operand 1 "ext_register_operand" "0")
8712 (match_operand 2 "const_int_operand" "n")))
8713 (clobber (reg:CC FLAGS_REG))]
8715 "and{b}\t{%2, %h0|%h0, %2}"
8716 [(set_attr "type" "alu")
8717 (set_attr "length_immediate" "1")
8718 (set_attr "mode" "QI")])
8720 ;; Generated by peephole translating test to and. This shows up
8721 ;; often in fp comparisons.
8723 (define_insn "*andqi_ext_0_cc"
8724 [(set (reg FLAGS_REG)
8728 (match_operand 1 "ext_register_operand" "0")
8731 (match_operand 2 "const_int_operand" "n"))
8733 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8742 "ix86_match_ccmode (insn, CCNOmode)"
8743 "and{b}\t{%2, %h0|%h0, %2}"
8744 [(set_attr "type" "alu")
8745 (set_attr "length_immediate" "1")
8746 (set_attr "mode" "QI")])
8748 (define_insn "*andqi_ext_1"
8749 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8754 (match_operand 1 "ext_register_operand" "0")
8758 (match_operand:QI 2 "general_operand" "Qm"))))
8759 (clobber (reg:CC FLAGS_REG))]
8761 "and{b}\t{%2, %h0|%h0, %2}"
8762 [(set_attr "type" "alu")
8763 (set_attr "length_immediate" "0")
8764 (set_attr "mode" "QI")])
8766 (define_insn "*andqi_ext_1_rex64"
8767 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8772 (match_operand 1 "ext_register_operand" "0")
8776 (match_operand 2 "ext_register_operand" "Q"))))
8777 (clobber (reg:CC FLAGS_REG))]
8779 "and{b}\t{%2, %h0|%h0, %2}"
8780 [(set_attr "type" "alu")
8781 (set_attr "length_immediate" "0")
8782 (set_attr "mode" "QI")])
8784 (define_insn "*andqi_ext_2"
8785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8790 (match_operand 1 "ext_register_operand" "%0")
8794 (match_operand 2 "ext_register_operand" "Q")
8797 (clobber (reg:CC FLAGS_REG))]
8799 "and{b}\t{%h2, %h0|%h0, %h2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "length_immediate" "0")
8802 (set_attr "mode" "QI")])
8804 ;; Convert wide AND instructions with immediate operand to shorter QImode
8805 ;; equivalents when possible.
8806 ;; Don't do the splitting with memory operands, since it introduces risk
8807 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8808 ;; for size, but that can (should?) be handled by generic code instead.
8810 [(set (match_operand 0 "register_operand" "")
8811 (and (match_operand 1 "register_operand" "")
8812 (match_operand 2 "const_int_operand" "")))
8813 (clobber (reg:CC FLAGS_REG))]
8815 && QI_REG_P (operands[0])
8816 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8817 && !(~INTVAL (operands[2]) & ~(255 << 8))
8818 && GET_MODE (operands[0]) != QImode"
8819 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8820 (and:SI (zero_extract:SI (match_dup 1)
8821 (const_int 8) (const_int 8))
8823 (clobber (reg:CC FLAGS_REG))])]
8824 "operands[0] = gen_lowpart (SImode, operands[0]);
8825 operands[1] = gen_lowpart (SImode, operands[1]);
8826 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8828 ;; Since AND can be encoded with sign extended immediate, this is only
8829 ;; profitable when 7th bit is not set.
8831 [(set (match_operand 0 "register_operand" "")
8832 (and (match_operand 1 "general_operand" "")
8833 (match_operand 2 "const_int_operand" "")))
8834 (clobber (reg:CC FLAGS_REG))]
8836 && ANY_QI_REG_P (operands[0])
8837 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8838 && !(~INTVAL (operands[2]) & ~255)
8839 && !(INTVAL (operands[2]) & 128)
8840 && GET_MODE (operands[0]) != QImode"
8841 [(parallel [(set (strict_low_part (match_dup 0))
8842 (and:QI (match_dup 1)
8844 (clobber (reg:CC FLAGS_REG))])]
8845 "operands[0] = gen_lowpart (QImode, operands[0]);
8846 operands[1] = gen_lowpart (QImode, operands[1]);
8847 operands[2] = gen_lowpart (QImode, operands[2]);")
8849 ;; Logical inclusive OR instructions
8851 ;; %%% This used to optimize known byte-wide and operations to memory.
8852 ;; If this is considered useful, it should be done with splitters.
8854 (define_expand "iordi3"
8855 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8856 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8857 (match_operand:DI 2 "x86_64_general_operand" "")))
8858 (clobber (reg:CC FLAGS_REG))]
8860 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8862 (define_insn "*iordi_1_rex64"
8863 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8864 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8865 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8866 (clobber (reg:CC FLAGS_REG))]
8868 && ix86_binary_operator_ok (IOR, DImode, operands)"
8869 "or{q}\t{%2, %0|%0, %2}"
8870 [(set_attr "type" "alu")
8871 (set_attr "mode" "DI")])
8873 (define_insn "*iordi_2_rex64"
8874 [(set (reg FLAGS_REG)
8875 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8876 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8878 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8879 (ior:DI (match_dup 1) (match_dup 2)))]
8881 && ix86_match_ccmode (insn, CCNOmode)
8882 && ix86_binary_operator_ok (IOR, DImode, operands)"
8883 "or{q}\t{%2, %0|%0, %2}"
8884 [(set_attr "type" "alu")
8885 (set_attr "mode" "DI")])
8887 (define_insn "*iordi_3_rex64"
8888 [(set (reg FLAGS_REG)
8889 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8890 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8892 (clobber (match_scratch:DI 0 "=r"))]
8894 && ix86_match_ccmode (insn, CCNOmode)
8895 && ix86_binary_operator_ok (IOR, DImode, operands)"
8896 "or{q}\t{%2, %0|%0, %2}"
8897 [(set_attr "type" "alu")
8898 (set_attr "mode" "DI")])
8901 (define_expand "iorsi3"
8902 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8903 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8904 (match_operand:SI 2 "general_operand" "")))
8905 (clobber (reg:CC FLAGS_REG))]
8907 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8909 (define_insn "*iorsi_1"
8910 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8911 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8912 (match_operand:SI 2 "general_operand" "ri,rmi")))
8913 (clobber (reg:CC FLAGS_REG))]
8914 "ix86_binary_operator_ok (IOR, SImode, operands)"
8915 "or{l}\t{%2, %0|%0, %2}"
8916 [(set_attr "type" "alu")
8917 (set_attr "mode" "SI")])
8919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8920 (define_insn "*iorsi_1_zext"
8921 [(set (match_operand:DI 0 "register_operand" "=rm")
8923 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8924 (match_operand:SI 2 "general_operand" "rim"))))
8925 (clobber (reg:CC FLAGS_REG))]
8926 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8927 "or{l}\t{%2, %k0|%k0, %2}"
8928 [(set_attr "type" "alu")
8929 (set_attr "mode" "SI")])
8931 (define_insn "*iorsi_1_zext_imm"
8932 [(set (match_operand:DI 0 "register_operand" "=rm")
8933 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8934 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8935 (clobber (reg:CC FLAGS_REG))]
8937 "or{l}\t{%2, %k0|%k0, %2}"
8938 [(set_attr "type" "alu")
8939 (set_attr "mode" "SI")])
8941 (define_insn "*iorsi_2"
8942 [(set (reg FLAGS_REG)
8943 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8944 (match_operand:SI 2 "general_operand" "rim,ri"))
8946 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8947 (ior:SI (match_dup 1) (match_dup 2)))]
8948 "ix86_match_ccmode (insn, CCNOmode)
8949 && ix86_binary_operator_ok (IOR, SImode, operands)"
8950 "or{l}\t{%2, %0|%0, %2}"
8951 [(set_attr "type" "alu")
8952 (set_attr "mode" "SI")])
8954 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8955 ;; ??? Special case for immediate operand is missing - it is tricky.
8956 (define_insn "*iorsi_2_zext"
8957 [(set (reg FLAGS_REG)
8958 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8959 (match_operand:SI 2 "general_operand" "rim"))
8961 (set (match_operand:DI 0 "register_operand" "=r")
8962 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8963 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8964 && ix86_binary_operator_ok (IOR, SImode, operands)"
8965 "or{l}\t{%2, %k0|%k0, %2}"
8966 [(set_attr "type" "alu")
8967 (set_attr "mode" "SI")])
8969 (define_insn "*iorsi_2_zext_imm"
8970 [(set (reg FLAGS_REG)
8971 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8974 (set (match_operand:DI 0 "register_operand" "=r")
8975 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8976 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977 && ix86_binary_operator_ok (IOR, SImode, operands)"
8978 "or{l}\t{%2, %k0|%k0, %2}"
8979 [(set_attr "type" "alu")
8980 (set_attr "mode" "SI")])
8982 (define_insn "*iorsi_3"
8983 [(set (reg FLAGS_REG)
8984 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985 (match_operand:SI 2 "general_operand" "rim"))
8987 (clobber (match_scratch:SI 0 "=r"))]
8988 "ix86_match_ccmode (insn, CCNOmode)
8989 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8990 "or{l}\t{%2, %0|%0, %2}"
8991 [(set_attr "type" "alu")
8992 (set_attr "mode" "SI")])
8994 (define_expand "iorhi3"
8995 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8996 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8997 (match_operand:HI 2 "general_operand" "")))
8998 (clobber (reg:CC FLAGS_REG))]
8999 "TARGET_HIMODE_MATH"
9000 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9002 (define_insn "*iorhi_1"
9003 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9004 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9005 (match_operand:HI 2 "general_operand" "rmi,ri")))
9006 (clobber (reg:CC FLAGS_REG))]
9007 "ix86_binary_operator_ok (IOR, HImode, operands)"
9008 "or{w}\t{%2, %0|%0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "HI")])
9012 (define_insn "*iorhi_2"
9013 [(set (reg FLAGS_REG)
9014 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9015 (match_operand:HI 2 "general_operand" "rim,ri"))
9017 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9018 (ior:HI (match_dup 1) (match_dup 2)))]
9019 "ix86_match_ccmode (insn, CCNOmode)
9020 && ix86_binary_operator_ok (IOR, HImode, operands)"
9021 "or{w}\t{%2, %0|%0, %2}"
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "HI")])
9025 (define_insn "*iorhi_3"
9026 [(set (reg FLAGS_REG)
9027 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9028 (match_operand:HI 2 "general_operand" "rim"))
9030 (clobber (match_scratch:HI 0 "=r"))]
9031 "ix86_match_ccmode (insn, CCNOmode)
9032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9033 "or{w}\t{%2, %0|%0, %2}"
9034 [(set_attr "type" "alu")
9035 (set_attr "mode" "HI")])
9037 (define_expand "iorqi3"
9038 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9039 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9040 (match_operand:QI 2 "general_operand" "")))
9041 (clobber (reg:CC FLAGS_REG))]
9042 "TARGET_QIMODE_MATH"
9043 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9045 ;; %%% Potential partial reg stall on alternative 2. What to do?
9046 (define_insn "*iorqi_1"
9047 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9048 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9049 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9050 (clobber (reg:CC FLAGS_REG))]
9051 "ix86_binary_operator_ok (IOR, QImode, operands)"
9053 or{b}\t{%2, %0|%0, %2}
9054 or{b}\t{%2, %0|%0, %2}
9055 or{l}\t{%k2, %k0|%k0, %k2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "mode" "QI,QI,SI")])
9059 (define_insn "*iorqi_1_slp"
9060 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9061 (ior:QI (match_dup 0)
9062 (match_operand:QI 1 "general_operand" "qmi,qi")))
9063 (clobber (reg:CC FLAGS_REG))]
9064 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9065 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9066 "or{b}\t{%1, %0|%0, %1}"
9067 [(set_attr "type" "alu1")
9068 (set_attr "mode" "QI")])
9070 (define_insn "*iorqi_2"
9071 [(set (reg FLAGS_REG)
9072 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9073 (match_operand:QI 2 "general_operand" "qim,qi"))
9075 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9076 (ior:QI (match_dup 1) (match_dup 2)))]
9077 "ix86_match_ccmode (insn, CCNOmode)
9078 && ix86_binary_operator_ok (IOR, QImode, operands)"
9079 "or{b}\t{%2, %0|%0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "mode" "QI")])
9083 (define_insn "*iorqi_2_slp"
9084 [(set (reg FLAGS_REG)
9085 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9086 (match_operand:QI 1 "general_operand" "qim,qi"))
9088 (set (strict_low_part (match_dup 0))
9089 (ior:QI (match_dup 0) (match_dup 1)))]
9090 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9091 && ix86_match_ccmode (insn, CCNOmode)
9092 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9093 "or{b}\t{%1, %0|%0, %1}"
9094 [(set_attr "type" "alu1")
9095 (set_attr "mode" "QI")])
9097 (define_insn "*iorqi_3"
9098 [(set (reg FLAGS_REG)
9099 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9100 (match_operand:QI 2 "general_operand" "qim"))
9102 (clobber (match_scratch:QI 0 "=q"))]
9103 "ix86_match_ccmode (insn, CCNOmode)
9104 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9105 "or{b}\t{%2, %0|%0, %2}"
9106 [(set_attr "type" "alu")
9107 (set_attr "mode" "QI")])
9109 (define_insn "iorqi_ext_0"
9110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9115 (match_operand 1 "ext_register_operand" "0")
9118 (match_operand 2 "const_int_operand" "n")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9121 "or{b}\t{%2, %h0|%h0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "length_immediate" "1")
9124 (set_attr "mode" "QI")])
9126 (define_insn "*iorqi_ext_1"
9127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9132 (match_operand 1 "ext_register_operand" "0")
9136 (match_operand:QI 2 "general_operand" "Qm"))))
9137 (clobber (reg:CC FLAGS_REG))]
9139 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9140 "or{b}\t{%2, %h0|%h0, %2}"
9141 [(set_attr "type" "alu")
9142 (set_attr "length_immediate" "0")
9143 (set_attr "mode" "QI")])
9145 (define_insn "*iorqi_ext_1_rex64"
9146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9151 (match_operand 1 "ext_register_operand" "0")
9155 (match_operand 2 "ext_register_operand" "Q"))))
9156 (clobber (reg:CC FLAGS_REG))]
9158 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9159 "or{b}\t{%2, %h0|%h0, %2}"
9160 [(set_attr "type" "alu")
9161 (set_attr "length_immediate" "0")
9162 (set_attr "mode" "QI")])
9164 (define_insn "*iorqi_ext_2"
9165 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9169 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9172 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9175 (clobber (reg:CC FLAGS_REG))]
9176 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177 "ior{b}\t{%h2, %h0|%h0, %h2}"
9178 [(set_attr "type" "alu")
9179 (set_attr "length_immediate" "0")
9180 (set_attr "mode" "QI")])
9183 [(set (match_operand 0 "register_operand" "")
9184 (ior (match_operand 1 "register_operand" "")
9185 (match_operand 2 "const_int_operand" "")))
9186 (clobber (reg:CC FLAGS_REG))]
9188 && QI_REG_P (operands[0])
9189 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9190 && !(INTVAL (operands[2]) & ~(255 << 8))
9191 && GET_MODE (operands[0]) != QImode"
9192 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9193 (ior:SI (zero_extract:SI (match_dup 1)
9194 (const_int 8) (const_int 8))
9196 (clobber (reg:CC FLAGS_REG))])]
9197 "operands[0] = gen_lowpart (SImode, operands[0]);
9198 operands[1] = gen_lowpart (SImode, operands[1]);
9199 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9201 ;; Since OR can be encoded with sign extended immediate, this is only
9202 ;; profitable when 7th bit is set.
9204 [(set (match_operand 0 "register_operand" "")
9205 (ior (match_operand 1 "general_operand" "")
9206 (match_operand 2 "const_int_operand" "")))
9207 (clobber (reg:CC FLAGS_REG))]
9209 && ANY_QI_REG_P (operands[0])
9210 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9211 && !(INTVAL (operands[2]) & ~255)
9212 && (INTVAL (operands[2]) & 128)
9213 && GET_MODE (operands[0]) != QImode"
9214 [(parallel [(set (strict_low_part (match_dup 0))
9215 (ior:QI (match_dup 1)
9217 (clobber (reg:CC FLAGS_REG))])]
9218 "operands[0] = gen_lowpart (QImode, operands[0]);
9219 operands[1] = gen_lowpart (QImode, operands[1]);
9220 operands[2] = gen_lowpart (QImode, operands[2]);")
9222 ;; Logical XOR instructions
9224 ;; %%% This used to optimize known byte-wide and operations to memory.
9225 ;; If this is considered useful, it should be done with splitters.
9227 (define_expand "xordi3"
9228 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9229 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9230 (match_operand:DI 2 "x86_64_general_operand" "")))
9231 (clobber (reg:CC FLAGS_REG))]
9233 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9235 (define_insn "*xordi_1_rex64"
9236 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9237 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9238 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9239 (clobber (reg:CC FLAGS_REG))]
9241 && ix86_binary_operator_ok (XOR, DImode, operands)"
9243 xor{q}\t{%2, %0|%0, %2}
9244 xor{q}\t{%2, %0|%0, %2}"
9245 [(set_attr "type" "alu")
9246 (set_attr "mode" "DI,DI")])
9248 (define_insn "*xordi_2_rex64"
9249 [(set (reg FLAGS_REG)
9250 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9251 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9253 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9254 (xor:DI (match_dup 1) (match_dup 2)))]
9256 && ix86_match_ccmode (insn, CCNOmode)
9257 && ix86_binary_operator_ok (XOR, DImode, operands)"
9259 xor{q}\t{%2, %0|%0, %2}
9260 xor{q}\t{%2, %0|%0, %2}"
9261 [(set_attr "type" "alu")
9262 (set_attr "mode" "DI,DI")])
9264 (define_insn "*xordi_3_rex64"
9265 [(set (reg FLAGS_REG)
9266 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9267 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9269 (clobber (match_scratch:DI 0 "=r"))]
9271 && ix86_match_ccmode (insn, CCNOmode)
9272 && ix86_binary_operator_ok (XOR, DImode, operands)"
9273 "xor{q}\t{%2, %0|%0, %2}"
9274 [(set_attr "type" "alu")
9275 (set_attr "mode" "DI")])
9277 (define_expand "xorsi3"
9278 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9279 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9280 (match_operand:SI 2 "general_operand" "")))
9281 (clobber (reg:CC FLAGS_REG))]
9283 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9285 (define_insn "*xorsi_1"
9286 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9287 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9288 (match_operand:SI 2 "general_operand" "ri,rm")))
9289 (clobber (reg:CC FLAGS_REG))]
9290 "ix86_binary_operator_ok (XOR, SImode, operands)"
9291 "xor{l}\t{%2, %0|%0, %2}"
9292 [(set_attr "type" "alu")
9293 (set_attr "mode" "SI")])
9295 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9296 ;; Add speccase for immediates
9297 (define_insn "*xorsi_1_zext"
9298 [(set (match_operand:DI 0 "register_operand" "=r")
9300 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9301 (match_operand:SI 2 "general_operand" "rim"))))
9302 (clobber (reg:CC FLAGS_REG))]
9303 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9304 "xor{l}\t{%2, %k0|%k0, %2}"
9305 [(set_attr "type" "alu")
9306 (set_attr "mode" "SI")])
9308 (define_insn "*xorsi_1_zext_imm"
9309 [(set (match_operand:DI 0 "register_operand" "=r")
9310 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9311 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9312 (clobber (reg:CC FLAGS_REG))]
9313 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9314 "xor{l}\t{%2, %k0|%k0, %2}"
9315 [(set_attr "type" "alu")
9316 (set_attr "mode" "SI")])
9318 (define_insn "*xorsi_2"
9319 [(set (reg FLAGS_REG)
9320 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9321 (match_operand:SI 2 "general_operand" "rim,ri"))
9323 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9324 (xor:SI (match_dup 1) (match_dup 2)))]
9325 "ix86_match_ccmode (insn, CCNOmode)
9326 && ix86_binary_operator_ok (XOR, SImode, operands)"
9327 "xor{l}\t{%2, %0|%0, %2}"
9328 [(set_attr "type" "alu")
9329 (set_attr "mode" "SI")])
9331 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9332 ;; ??? Special case for immediate operand is missing - it is tricky.
9333 (define_insn "*xorsi_2_zext"
9334 [(set (reg FLAGS_REG)
9335 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9336 (match_operand:SI 2 "general_operand" "rim"))
9338 (set (match_operand:DI 0 "register_operand" "=r")
9339 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9340 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9341 && ix86_binary_operator_ok (XOR, SImode, operands)"
9342 "xor{l}\t{%2, %k0|%k0, %2}"
9343 [(set_attr "type" "alu")
9344 (set_attr "mode" "SI")])
9346 (define_insn "*xorsi_2_zext_imm"
9347 [(set (reg FLAGS_REG)
9348 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9349 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9351 (set (match_operand:DI 0 "register_operand" "=r")
9352 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9353 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9354 && ix86_binary_operator_ok (XOR, SImode, operands)"
9355 "xor{l}\t{%2, %k0|%k0, %2}"
9356 [(set_attr "type" "alu")
9357 (set_attr "mode" "SI")])
9359 (define_insn "*xorsi_3"
9360 [(set (reg FLAGS_REG)
9361 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9362 (match_operand:SI 2 "general_operand" "rim"))
9364 (clobber (match_scratch:SI 0 "=r"))]
9365 "ix86_match_ccmode (insn, CCNOmode)
9366 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9367 "xor{l}\t{%2, %0|%0, %2}"
9368 [(set_attr "type" "alu")
9369 (set_attr "mode" "SI")])
9371 (define_expand "xorhi3"
9372 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9373 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9374 (match_operand:HI 2 "general_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "TARGET_HIMODE_MATH"
9377 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9379 (define_insn "*xorhi_1"
9380 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9381 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9382 (match_operand:HI 2 "general_operand" "rmi,ri")))
9383 (clobber (reg:CC FLAGS_REG))]
9384 "ix86_binary_operator_ok (XOR, HImode, operands)"
9385 "xor{w}\t{%2, %0|%0, %2}"
9386 [(set_attr "type" "alu")
9387 (set_attr "mode" "HI")])
9389 (define_insn "*xorhi_2"
9390 [(set (reg FLAGS_REG)
9391 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9392 (match_operand:HI 2 "general_operand" "rim,ri"))
9394 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9395 (xor:HI (match_dup 1) (match_dup 2)))]
9396 "ix86_match_ccmode (insn, CCNOmode)
9397 && ix86_binary_operator_ok (XOR, HImode, operands)"
9398 "xor{w}\t{%2, %0|%0, %2}"
9399 [(set_attr "type" "alu")
9400 (set_attr "mode" "HI")])
9402 (define_insn "*xorhi_3"
9403 [(set (reg FLAGS_REG)
9404 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9405 (match_operand:HI 2 "general_operand" "rim"))
9407 (clobber (match_scratch:HI 0 "=r"))]
9408 "ix86_match_ccmode (insn, CCNOmode)
9409 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9410 "xor{w}\t{%2, %0|%0, %2}"
9411 [(set_attr "type" "alu")
9412 (set_attr "mode" "HI")])
9414 (define_expand "xorqi3"
9415 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9416 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9417 (match_operand:QI 2 "general_operand" "")))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "TARGET_QIMODE_MATH"
9420 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9422 ;; %%% Potential partial reg stall on alternative 2. What to do?
9423 (define_insn "*xorqi_1"
9424 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9425 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9426 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9427 (clobber (reg:CC FLAGS_REG))]
9428 "ix86_binary_operator_ok (XOR, QImode, operands)"
9430 xor{b}\t{%2, %0|%0, %2}
9431 xor{b}\t{%2, %0|%0, %2}
9432 xor{l}\t{%k2, %k0|%k0, %k2}"
9433 [(set_attr "type" "alu")
9434 (set_attr "mode" "QI,QI,SI")])
9436 (define_insn "*xorqi_1_slp"
9437 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9438 (xor:QI (match_dup 0)
9439 (match_operand:QI 1 "general_operand" "qi,qmi")))
9440 (clobber (reg:CC FLAGS_REG))]
9441 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9443 "xor{b}\t{%1, %0|%0, %1}"
9444 [(set_attr "type" "alu1")
9445 (set_attr "mode" "QI")])
9447 (define_insn "xorqi_ext_0"
9448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9453 (match_operand 1 "ext_register_operand" "0")
9456 (match_operand 2 "const_int_operand" "n")))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9459 "xor{b}\t{%2, %h0|%h0, %2}"
9460 [(set_attr "type" "alu")
9461 (set_attr "length_immediate" "1")
9462 (set_attr "mode" "QI")])
9464 (define_insn "*xorqi_ext_1"
9465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9470 (match_operand 1 "ext_register_operand" "0")
9474 (match_operand:QI 2 "general_operand" "Qm"))))
9475 (clobber (reg:CC FLAGS_REG))]
9477 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9478 "xor{b}\t{%2, %h0|%h0, %2}"
9479 [(set_attr "type" "alu")
9480 (set_attr "length_immediate" "0")
9481 (set_attr "mode" "QI")])
9483 (define_insn "*xorqi_ext_1_rex64"
9484 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9489 (match_operand 1 "ext_register_operand" "0")
9493 (match_operand 2 "ext_register_operand" "Q"))))
9494 (clobber (reg:CC FLAGS_REG))]
9496 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9497 "xor{b}\t{%2, %h0|%h0, %2}"
9498 [(set_attr "type" "alu")
9499 (set_attr "length_immediate" "0")
9500 (set_attr "mode" "QI")])
9502 (define_insn "*xorqi_ext_2"
9503 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9507 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9510 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9513 (clobber (reg:CC FLAGS_REG))]
9514 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9515 "xor{b}\t{%h2, %h0|%h0, %h2}"
9516 [(set_attr "type" "alu")
9517 (set_attr "length_immediate" "0")
9518 (set_attr "mode" "QI")])
9520 (define_insn "*xorqi_cc_1"
9521 [(set (reg FLAGS_REG)
9523 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9524 (match_operand:QI 2 "general_operand" "qim,qi"))
9526 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9527 (xor:QI (match_dup 1) (match_dup 2)))]
9528 "ix86_match_ccmode (insn, CCNOmode)
9529 && ix86_binary_operator_ok (XOR, QImode, operands)"
9530 "xor{b}\t{%2, %0|%0, %2}"
9531 [(set_attr "type" "alu")
9532 (set_attr "mode" "QI")])
9534 (define_insn "*xorqi_2_slp"
9535 [(set (reg FLAGS_REG)
9536 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9537 (match_operand:QI 1 "general_operand" "qim,qi"))
9539 (set (strict_low_part (match_dup 0))
9540 (xor:QI (match_dup 0) (match_dup 1)))]
9541 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9542 && ix86_match_ccmode (insn, CCNOmode)
9543 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9544 "xor{b}\t{%1, %0|%0, %1}"
9545 [(set_attr "type" "alu1")
9546 (set_attr "mode" "QI")])
9548 (define_insn "*xorqi_cc_2"
9549 [(set (reg FLAGS_REG)
9551 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9552 (match_operand:QI 2 "general_operand" "qim"))
9554 (clobber (match_scratch:QI 0 "=q"))]
9555 "ix86_match_ccmode (insn, CCNOmode)
9556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9557 "xor{b}\t{%2, %0|%0, %2}"
9558 [(set_attr "type" "alu")
9559 (set_attr "mode" "QI")])
9561 (define_insn "*xorqi_cc_ext_1"
9562 [(set (reg FLAGS_REG)
9566 (match_operand 1 "ext_register_operand" "0")
9569 (match_operand:QI 2 "general_operand" "qmn"))
9571 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9575 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9577 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9578 "xor{b}\t{%2, %h0|%h0, %2}"
9579 [(set_attr "type" "alu")
9580 (set_attr "mode" "QI")])
9582 (define_insn "*xorqi_cc_ext_1_rex64"
9583 [(set (reg FLAGS_REG)
9587 (match_operand 1 "ext_register_operand" "0")
9590 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9592 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9596 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9599 "xor{b}\t{%2, %h0|%h0, %2}"
9600 [(set_attr "type" "alu")
9601 (set_attr "mode" "QI")])
9603 (define_expand "xorqi_cc_ext_1"
9605 (set (reg:CCNO FLAGS_REG)
9609 (match_operand 1 "ext_register_operand" "")
9612 (match_operand:QI 2 "general_operand" ""))
9614 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9618 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9624 [(set (match_operand 0 "register_operand" "")
9625 (xor (match_operand 1 "register_operand" "")
9626 (match_operand 2 "const_int_operand" "")))
9627 (clobber (reg:CC FLAGS_REG))]
9629 && QI_REG_P (operands[0])
9630 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9631 && !(INTVAL (operands[2]) & ~(255 << 8))
9632 && GET_MODE (operands[0]) != QImode"
9633 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9634 (xor:SI (zero_extract:SI (match_dup 1)
9635 (const_int 8) (const_int 8))
9637 (clobber (reg:CC FLAGS_REG))])]
9638 "operands[0] = gen_lowpart (SImode, operands[0]);
9639 operands[1] = gen_lowpart (SImode, operands[1]);
9640 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9642 ;; Since XOR can be encoded with sign extended immediate, this is only
9643 ;; profitable when 7th bit is set.
9645 [(set (match_operand 0 "register_operand" "")
9646 (xor (match_operand 1 "general_operand" "")
9647 (match_operand 2 "const_int_operand" "")))
9648 (clobber (reg:CC FLAGS_REG))]
9650 && ANY_QI_REG_P (operands[0])
9651 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9652 && !(INTVAL (operands[2]) & ~255)
9653 && (INTVAL (operands[2]) & 128)
9654 && GET_MODE (operands[0]) != QImode"
9655 [(parallel [(set (strict_low_part (match_dup 0))
9656 (xor:QI (match_dup 1)
9658 (clobber (reg:CC FLAGS_REG))])]
9659 "operands[0] = gen_lowpart (QImode, operands[0]);
9660 operands[1] = gen_lowpart (QImode, operands[1]);
9661 operands[2] = gen_lowpart (QImode, operands[2]);")
9663 ;; Negation instructions
9665 (define_expand "negti2"
9666 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9667 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9668 (clobber (reg:CC FLAGS_REG))])]
9670 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9672 (define_insn "*negti2_1"
9673 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9674 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9675 (clobber (reg:CC FLAGS_REG))]
9677 && ix86_unary_operator_ok (NEG, TImode, operands)"
9681 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9682 (neg:TI (match_operand:TI 1 "general_operand" "")))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "TARGET_64BIT && reload_completed"
9686 [(set (reg:CCZ FLAGS_REG)
9687 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9688 (set (match_dup 0) (neg:DI (match_dup 2)))])
9691 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9694 (clobber (reg:CC FLAGS_REG))])
9697 (neg:DI (match_dup 1)))
9698 (clobber (reg:CC FLAGS_REG))])]
9699 "split_ti (operands+1, 1, operands+2, operands+3);
9700 split_ti (operands+0, 1, operands+0, operands+1);")
9702 (define_expand "negdi2"
9703 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9704 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9705 (clobber (reg:CC FLAGS_REG))])]
9707 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9709 (define_insn "*negdi2_1"
9710 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9711 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9712 (clobber (reg:CC FLAGS_REG))]
9714 && ix86_unary_operator_ok (NEG, DImode, operands)"
9718 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9719 (neg:DI (match_operand:DI 1 "general_operand" "")))
9720 (clobber (reg:CC FLAGS_REG))]
9721 "!TARGET_64BIT && reload_completed"
9723 [(set (reg:CCZ FLAGS_REG)
9724 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9725 (set (match_dup 0) (neg:SI (match_dup 2)))])
9728 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9731 (clobber (reg:CC FLAGS_REG))])
9734 (neg:SI (match_dup 1)))
9735 (clobber (reg:CC FLAGS_REG))])]
9736 "split_di (operands+1, 1, operands+2, operands+3);
9737 split_di (operands+0, 1, operands+0, operands+1);")
9739 (define_insn "*negdi2_1_rex64"
9740 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9741 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9742 (clobber (reg:CC FLAGS_REG))]
9743 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9745 [(set_attr "type" "negnot")
9746 (set_attr "mode" "DI")])
9748 ;; The problem with neg is that it does not perform (compare x 0),
9749 ;; it really performs (compare 0 x), which leaves us with the zero
9750 ;; flag being the only useful item.
9752 (define_insn "*negdi2_cmpz_rex64"
9753 [(set (reg:CCZ FLAGS_REG)
9754 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9756 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9757 (neg:DI (match_dup 1)))]
9758 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9760 [(set_attr "type" "negnot")
9761 (set_attr "mode" "DI")])
9764 (define_expand "negsi2"
9765 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9766 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9767 (clobber (reg:CC FLAGS_REG))])]
9769 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9771 (define_insn "*negsi2_1"
9772 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9773 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "ix86_unary_operator_ok (NEG, SImode, operands)"
9777 [(set_attr "type" "negnot")
9778 (set_attr "mode" "SI")])
9780 ;; Combine is quite creative about this pattern.
9781 (define_insn "*negsi2_1_zext"
9782 [(set (match_operand:DI 0 "register_operand" "=r")
9783 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9786 (clobber (reg:CC FLAGS_REG))]
9787 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9789 [(set_attr "type" "negnot")
9790 (set_attr "mode" "SI")])
9792 ;; The problem with neg is that it does not perform (compare x 0),
9793 ;; it really performs (compare 0 x), which leaves us with the zero
9794 ;; flag being the only useful item.
9796 (define_insn "*negsi2_cmpz"
9797 [(set (reg:CCZ FLAGS_REG)
9798 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9800 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9801 (neg:SI (match_dup 1)))]
9802 "ix86_unary_operator_ok (NEG, SImode, operands)"
9804 [(set_attr "type" "negnot")
9805 (set_attr "mode" "SI")])
9807 (define_insn "*negsi2_cmpz_zext"
9808 [(set (reg:CCZ FLAGS_REG)
9809 (compare:CCZ (lshiftrt:DI
9811 (match_operand:DI 1 "register_operand" "0")
9815 (set (match_operand:DI 0 "register_operand" "=r")
9816 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9819 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9821 [(set_attr "type" "negnot")
9822 (set_attr "mode" "SI")])
9824 (define_expand "neghi2"
9825 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9826 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9827 (clobber (reg:CC FLAGS_REG))])]
9828 "TARGET_HIMODE_MATH"
9829 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9831 (define_insn "*neghi2_1"
9832 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9833 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "ix86_unary_operator_ok (NEG, HImode, operands)"
9837 [(set_attr "type" "negnot")
9838 (set_attr "mode" "HI")])
9840 (define_insn "*neghi2_cmpz"
9841 [(set (reg:CCZ FLAGS_REG)
9842 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9844 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9845 (neg:HI (match_dup 1)))]
9846 "ix86_unary_operator_ok (NEG, HImode, operands)"
9848 [(set_attr "type" "negnot")
9849 (set_attr "mode" "HI")])
9851 (define_expand "negqi2"
9852 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9853 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9854 (clobber (reg:CC FLAGS_REG))])]
9855 "TARGET_QIMODE_MATH"
9856 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9858 (define_insn "*negqi2_1"
9859 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9860 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "ix86_unary_operator_ok (NEG, QImode, operands)"
9864 [(set_attr "type" "negnot")
9865 (set_attr "mode" "QI")])
9867 (define_insn "*negqi2_cmpz"
9868 [(set (reg:CCZ FLAGS_REG)
9869 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9871 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9872 (neg:QI (match_dup 1)))]
9873 "ix86_unary_operator_ok (NEG, QImode, operands)"
9875 [(set_attr "type" "negnot")
9876 (set_attr "mode" "QI")])
9878 ;; Changing of sign for FP values is doable using integer unit too.
9880 (define_expand "negsf2"
9881 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9882 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9883 "TARGET_80387 || TARGET_SSE_MATH"
9884 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9886 (define_expand "abssf2"
9887 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9888 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9889 "TARGET_80387 || TARGET_SSE_MATH"
9890 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9892 (define_insn "*absnegsf2_mixed"
9893 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9894 (match_operator:SF 3 "absneg_operator"
9895 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9896 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9897 (clobber (reg:CC FLAGS_REG))]
9898 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9899 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9902 (define_insn "*absnegsf2_sse"
9903 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9904 (match_operator:SF 3 "absneg_operator"
9905 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9906 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9907 (clobber (reg:CC FLAGS_REG))]
9909 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9912 (define_insn "*absnegsf2_i387"
9913 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9914 (match_operator:SF 3 "absneg_operator"
9915 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9916 (use (match_operand 2 "" ""))
9917 (clobber (reg:CC FLAGS_REG))]
9918 "TARGET_80387 && !TARGET_SSE_MATH
9919 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9922 (define_expand "copysignsf3"
9923 [(match_operand:SF 0 "register_operand" "")
9924 (match_operand:SF 1 "nonmemory_operand" "")
9925 (match_operand:SF 2 "register_operand" "")]
9928 ix86_expand_copysign (operands);
9932 (define_insn_and_split "copysignsf3_const"
9933 [(set (match_operand:SF 0 "register_operand" "=x")
9935 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9936 (match_operand:SF 2 "register_operand" "0")
9937 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9941 "&& reload_completed"
9944 ix86_split_copysign_const (operands);
9948 (define_insn "copysignsf3_var"
9949 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9951 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9952 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9953 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9954 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9956 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9961 [(set (match_operand:SF 0 "register_operand" "")
9963 [(match_operand:SF 2 "register_operand" "")
9964 (match_operand:SF 3 "register_operand" "")
9965 (match_operand:V4SF 4 "" "")
9966 (match_operand:V4SF 5 "" "")]
9968 (clobber (match_scratch:V4SF 1 ""))]
9969 "TARGET_SSE_MATH && reload_completed"
9972 ix86_split_copysign_var (operands);
9976 (define_expand "negdf2"
9977 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9978 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9979 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9980 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9982 (define_expand "absdf2"
9983 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9984 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9985 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9986 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9988 (define_insn "*absnegdf2_mixed"
9989 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
9990 (match_operator:DF 3 "absneg_operator"
9991 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9992 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
9993 (clobber (reg:CC FLAGS_REG))]
9994 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9995 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9998 (define_insn "*absnegdf2_sse"
9999 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10000 (match_operator:DF 3 "absneg_operator"
10001 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10002 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10003 (clobber (reg:CC FLAGS_REG))]
10004 "TARGET_SSE2 && TARGET_SSE_MATH
10005 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10008 (define_insn "*absnegdf2_i387"
10009 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10010 (match_operator:DF 3 "absneg_operator"
10011 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10012 (use (match_operand 2 "" ""))
10013 (clobber (reg:CC FLAGS_REG))]
10014 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10015 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10018 (define_expand "copysigndf3"
10019 [(match_operand:DF 0 "register_operand" "")
10020 (match_operand:DF 1 "nonmemory_operand" "")
10021 (match_operand:DF 2 "register_operand" "")]
10022 "TARGET_SSE2 && TARGET_SSE_MATH"
10024 ix86_expand_copysign (operands);
10028 (define_insn_and_split "copysigndf3_const"
10029 [(set (match_operand:DF 0 "register_operand" "=x")
10031 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
10032 (match_operand:DF 2 "register_operand" "0")
10033 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10035 "TARGET_SSE2 && TARGET_SSE_MATH"
10037 "&& reload_completed"
10040 ix86_split_copysign_const (operands);
10044 (define_insn "copysigndf3_var"
10045 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
10047 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
10048 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
10049 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10050 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10052 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
10053 "TARGET_SSE2 && TARGET_SSE_MATH"
10057 [(set (match_operand:DF 0 "register_operand" "")
10059 [(match_operand:DF 2 "register_operand" "")
10060 (match_operand:DF 3 "register_operand" "")
10061 (match_operand:V2DF 4 "" "")
10062 (match_operand:V2DF 5 "" "")]
10064 (clobber (match_scratch:V2DF 1 ""))]
10065 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10068 ix86_split_copysign_var (operands);
10072 (define_expand "negxf2"
10073 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10074 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10076 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10078 (define_expand "absxf2"
10079 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10080 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10082 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10084 (define_insn "*absnegxf2_i387"
10085 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10086 (match_operator:XF 3 "absneg_operator"
10087 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10088 (use (match_operand 2 "" ""))
10089 (clobber (reg:CC FLAGS_REG))]
10091 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10094 ;; Splitters for fp abs and neg.
10097 [(set (match_operand 0 "fp_register_operand" "")
10098 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10099 (use (match_operand 2 "" ""))
10100 (clobber (reg:CC FLAGS_REG))]
10102 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10105 [(set (match_operand 0 "register_operand" "")
10106 (match_operator 3 "absneg_operator"
10107 [(match_operand 1 "register_operand" "")]))
10108 (use (match_operand 2 "nonimmediate_operand" ""))
10109 (clobber (reg:CC FLAGS_REG))]
10110 "reload_completed && SSE_REG_P (operands[0])"
10111 [(set (match_dup 0) (match_dup 3))]
10113 enum machine_mode mode = GET_MODE (operands[0]);
10114 enum machine_mode vmode = GET_MODE (operands[2]);
10117 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10118 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10119 if (operands_match_p (operands[0], operands[2]))
10122 operands[1] = operands[2];
10125 if (GET_CODE (operands[3]) == ABS)
10126 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10128 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10133 [(set (match_operand:SF 0 "register_operand" "")
10134 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10135 (use (match_operand:V4SF 2 "" ""))
10136 (clobber (reg:CC FLAGS_REG))]
10138 [(parallel [(set (match_dup 0) (match_dup 1))
10139 (clobber (reg:CC FLAGS_REG))])]
10142 operands[0] = gen_lowpart (SImode, operands[0]);
10143 if (GET_CODE (operands[1]) == ABS)
10145 tmp = gen_int_mode (0x7fffffff, SImode);
10146 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10150 tmp = gen_int_mode (0x80000000, SImode);
10151 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10157 [(set (match_operand:DF 0 "register_operand" "")
10158 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10159 (use (match_operand 2 "" ""))
10160 (clobber (reg:CC FLAGS_REG))]
10162 [(parallel [(set (match_dup 0) (match_dup 1))
10163 (clobber (reg:CC FLAGS_REG))])]
10168 tmp = gen_lowpart (DImode, operands[0]);
10169 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10172 if (GET_CODE (operands[1]) == ABS)
10175 tmp = gen_rtx_NOT (DImode, tmp);
10179 operands[0] = gen_highpart (SImode, operands[0]);
10180 if (GET_CODE (operands[1]) == ABS)
10182 tmp = gen_int_mode (0x7fffffff, SImode);
10183 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10187 tmp = gen_int_mode (0x80000000, SImode);
10188 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10195 [(set (match_operand:XF 0 "register_operand" "")
10196 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10197 (use (match_operand 2 "" ""))
10198 (clobber (reg:CC FLAGS_REG))]
10200 [(parallel [(set (match_dup 0) (match_dup 1))
10201 (clobber (reg:CC FLAGS_REG))])]
10204 operands[0] = gen_rtx_REG (SImode,
10205 true_regnum (operands[0])
10206 + (TARGET_64BIT ? 1 : 2));
10207 if (GET_CODE (operands[1]) == ABS)
10209 tmp = GEN_INT (0x7fff);
10210 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10214 tmp = GEN_INT (0x8000);
10215 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10221 [(set (match_operand 0 "memory_operand" "")
10222 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10223 (use (match_operand 2 "" ""))
10224 (clobber (reg:CC FLAGS_REG))]
10226 [(parallel [(set (match_dup 0) (match_dup 1))
10227 (clobber (reg:CC FLAGS_REG))])]
10229 enum machine_mode mode = GET_MODE (operands[0]);
10230 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10233 operands[0] = adjust_address (operands[0], QImode, size - 1);
10234 if (GET_CODE (operands[1]) == ABS)
10236 tmp = gen_int_mode (0x7f, QImode);
10237 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10241 tmp = gen_int_mode (0x80, QImode);
10242 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10247 ;; Conditionalize these after reload. If they match before reload, we
10248 ;; lose the clobber and ability to use integer instructions.
10250 (define_insn "*negsf2_1"
10251 [(set (match_operand:SF 0 "register_operand" "=f")
10252 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10253 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10255 [(set_attr "type" "fsgn")
10256 (set_attr "mode" "SF")])
10258 (define_insn "*negdf2_1"
10259 [(set (match_operand:DF 0 "register_operand" "=f")
10260 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10261 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10263 [(set_attr "type" "fsgn")
10264 (set_attr "mode" "DF")])
10266 (define_insn "*negxf2_1"
10267 [(set (match_operand:XF 0 "register_operand" "=f")
10268 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10271 [(set_attr "type" "fsgn")
10272 (set_attr "mode" "XF")])
10274 (define_insn "*abssf2_1"
10275 [(set (match_operand:SF 0 "register_operand" "=f")
10276 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10277 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10279 [(set_attr "type" "fsgn")
10280 (set_attr "mode" "SF")])
10282 (define_insn "*absdf2_1"
10283 [(set (match_operand:DF 0 "register_operand" "=f")
10284 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10285 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10287 [(set_attr "type" "fsgn")
10288 (set_attr "mode" "DF")])
10290 (define_insn "*absxf2_1"
10291 [(set (match_operand:XF 0 "register_operand" "=f")
10292 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10295 [(set_attr "type" "fsgn")
10296 (set_attr "mode" "DF")])
10298 (define_insn "*negextendsfdf2"
10299 [(set (match_operand:DF 0 "register_operand" "=f")
10300 (neg:DF (float_extend:DF
10301 (match_operand:SF 1 "register_operand" "0"))))]
10302 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10304 [(set_attr "type" "fsgn")
10305 (set_attr "mode" "DF")])
10307 (define_insn "*negextenddfxf2"
10308 [(set (match_operand:XF 0 "register_operand" "=f")
10309 (neg:XF (float_extend:XF
10310 (match_operand:DF 1 "register_operand" "0"))))]
10313 [(set_attr "type" "fsgn")
10314 (set_attr "mode" "XF")])
10316 (define_insn "*negextendsfxf2"
10317 [(set (match_operand:XF 0 "register_operand" "=f")
10318 (neg:XF (float_extend:XF
10319 (match_operand:SF 1 "register_operand" "0"))))]
10322 [(set_attr "type" "fsgn")
10323 (set_attr "mode" "XF")])
10325 (define_insn "*absextendsfdf2"
10326 [(set (match_operand:DF 0 "register_operand" "=f")
10327 (abs:DF (float_extend:DF
10328 (match_operand:SF 1 "register_operand" "0"))))]
10329 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10331 [(set_attr "type" "fsgn")
10332 (set_attr "mode" "DF")])
10334 (define_insn "*absextenddfxf2"
10335 [(set (match_operand:XF 0 "register_operand" "=f")
10336 (abs:XF (float_extend:XF
10337 (match_operand:DF 1 "register_operand" "0"))))]
10340 [(set_attr "type" "fsgn")
10341 (set_attr "mode" "XF")])
10343 (define_insn "*absextendsfxf2"
10344 [(set (match_operand:XF 0 "register_operand" "=f")
10345 (abs:XF (float_extend:XF
10346 (match_operand:SF 1 "register_operand" "0"))))]
10349 [(set_attr "type" "fsgn")
10350 (set_attr "mode" "XF")])
10352 ;; One complement instructions
10354 (define_expand "one_cmpldi2"
10355 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10356 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10358 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10360 (define_insn "*one_cmpldi2_1_rex64"
10361 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10363 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10365 [(set_attr "type" "negnot")
10366 (set_attr "mode" "DI")])
10368 (define_insn "*one_cmpldi2_2_rex64"
10369 [(set (reg FLAGS_REG)
10370 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10372 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10373 (not:DI (match_dup 1)))]
10374 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10375 && ix86_unary_operator_ok (NOT, DImode, operands)"
10377 [(set_attr "type" "alu1")
10378 (set_attr "mode" "DI")])
10381 [(set (match_operand 0 "flags_reg_operand" "")
10382 (match_operator 2 "compare_operator"
10383 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10385 (set (match_operand:DI 1 "nonimmediate_operand" "")
10386 (not:DI (match_dup 3)))]
10387 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10388 [(parallel [(set (match_dup 0)
10390 [(xor:DI (match_dup 3) (const_int -1))
10393 (xor:DI (match_dup 3) (const_int -1)))])]
10396 (define_expand "one_cmplsi2"
10397 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10398 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10400 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10402 (define_insn "*one_cmplsi2_1"
10403 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10404 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10405 "ix86_unary_operator_ok (NOT, SImode, operands)"
10407 [(set_attr "type" "negnot")
10408 (set_attr "mode" "SI")])
10410 ;; ??? Currently never generated - xor is used instead.
10411 (define_insn "*one_cmplsi2_1_zext"
10412 [(set (match_operand:DI 0 "register_operand" "=r")
10413 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10414 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10416 [(set_attr "type" "negnot")
10417 (set_attr "mode" "SI")])
10419 (define_insn "*one_cmplsi2_2"
10420 [(set (reg FLAGS_REG)
10421 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10423 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10424 (not:SI (match_dup 1)))]
10425 "ix86_match_ccmode (insn, CCNOmode)
10426 && ix86_unary_operator_ok (NOT, SImode, operands)"
10428 [(set_attr "type" "alu1")
10429 (set_attr "mode" "SI")])
10432 [(set (match_operand 0 "flags_reg_operand" "")
10433 (match_operator 2 "compare_operator"
10434 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10436 (set (match_operand:SI 1 "nonimmediate_operand" "")
10437 (not:SI (match_dup 3)))]
10438 "ix86_match_ccmode (insn, CCNOmode)"
10439 [(parallel [(set (match_dup 0)
10440 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10443 (xor:SI (match_dup 3) (const_int -1)))])]
10446 ;; ??? Currently never generated - xor is used instead.
10447 (define_insn "*one_cmplsi2_2_zext"
10448 [(set (reg FLAGS_REG)
10449 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10451 (set (match_operand:DI 0 "register_operand" "=r")
10452 (zero_extend:DI (not:SI (match_dup 1))))]
10453 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10454 && ix86_unary_operator_ok (NOT, SImode, operands)"
10456 [(set_attr "type" "alu1")
10457 (set_attr "mode" "SI")])
10460 [(set (match_operand 0 "flags_reg_operand" "")
10461 (match_operator 2 "compare_operator"
10462 [(not:SI (match_operand:SI 3 "register_operand" ""))
10464 (set (match_operand:DI 1 "register_operand" "")
10465 (zero_extend:DI (not:SI (match_dup 3))))]
10466 "ix86_match_ccmode (insn, CCNOmode)"
10467 [(parallel [(set (match_dup 0)
10468 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10471 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10474 (define_expand "one_cmplhi2"
10475 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10476 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10477 "TARGET_HIMODE_MATH"
10478 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10480 (define_insn "*one_cmplhi2_1"
10481 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10482 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10483 "ix86_unary_operator_ok (NOT, HImode, operands)"
10485 [(set_attr "type" "negnot")
10486 (set_attr "mode" "HI")])
10488 (define_insn "*one_cmplhi2_2"
10489 [(set (reg FLAGS_REG)
10490 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10492 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10493 (not:HI (match_dup 1)))]
10494 "ix86_match_ccmode (insn, CCNOmode)
10495 && ix86_unary_operator_ok (NEG, HImode, operands)"
10497 [(set_attr "type" "alu1")
10498 (set_attr "mode" "HI")])
10501 [(set (match_operand 0 "flags_reg_operand" "")
10502 (match_operator 2 "compare_operator"
10503 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10505 (set (match_operand:HI 1 "nonimmediate_operand" "")
10506 (not:HI (match_dup 3)))]
10507 "ix86_match_ccmode (insn, CCNOmode)"
10508 [(parallel [(set (match_dup 0)
10509 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10512 (xor:HI (match_dup 3) (const_int -1)))])]
10515 ;; %%% Potential partial reg stall on alternative 1. What to do?
10516 (define_expand "one_cmplqi2"
10517 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10518 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10519 "TARGET_QIMODE_MATH"
10520 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10522 (define_insn "*one_cmplqi2_1"
10523 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10524 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10525 "ix86_unary_operator_ok (NOT, QImode, operands)"
10529 [(set_attr "type" "negnot")
10530 (set_attr "mode" "QI,SI")])
10532 (define_insn "*one_cmplqi2_2"
10533 [(set (reg FLAGS_REG)
10534 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10536 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10537 (not:QI (match_dup 1)))]
10538 "ix86_match_ccmode (insn, CCNOmode)
10539 && ix86_unary_operator_ok (NOT, QImode, operands)"
10541 [(set_attr "type" "alu1")
10542 (set_attr "mode" "QI")])
10545 [(set (match_operand 0 "flags_reg_operand" "")
10546 (match_operator 2 "compare_operator"
10547 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10549 (set (match_operand:QI 1 "nonimmediate_operand" "")
10550 (not:QI (match_dup 3)))]
10551 "ix86_match_ccmode (insn, CCNOmode)"
10552 [(parallel [(set (match_dup 0)
10553 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10556 (xor:QI (match_dup 3) (const_int -1)))])]
10559 ;; Arithmetic shift instructions
10561 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10562 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10563 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10564 ;; from the assembler input.
10566 ;; This instruction shifts the target reg/mem as usual, but instead of
10567 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10568 ;; is a left shift double, bits are taken from the high order bits of
10569 ;; reg, else if the insn is a shift right double, bits are taken from the
10570 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10571 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10573 ;; Since sh[lr]d does not change the `reg' operand, that is done
10574 ;; separately, making all shifts emit pairs of shift double and normal
10575 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10576 ;; support a 63 bit shift, each shift where the count is in a reg expands
10577 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10579 ;; If the shift count is a constant, we need never emit more than one
10580 ;; shift pair, instead using moves and sign extension for counts greater
10583 (define_expand "ashlti3"
10584 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10585 (ashift:TI (match_operand:TI 1 "register_operand" "")
10586 (match_operand:QI 2 "nonmemory_operand" "")))
10587 (clobber (reg:CC FLAGS_REG))])]
10590 if (! immediate_operand (operands[2], QImode))
10592 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10595 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10599 (define_insn "ashlti3_1"
10600 [(set (match_operand:TI 0 "register_operand" "=r")
10601 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10602 (match_operand:QI 2 "register_operand" "c")))
10603 (clobber (match_scratch:DI 3 "=&r"))
10604 (clobber (reg:CC FLAGS_REG))]
10607 [(set_attr "type" "multi")])
10609 (define_insn "*ashlti3_2"
10610 [(set (match_operand:TI 0 "register_operand" "=r")
10611 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10612 (match_operand:QI 2 "immediate_operand" "O")))
10613 (clobber (reg:CC FLAGS_REG))]
10616 [(set_attr "type" "multi")])
10619 [(set (match_operand:TI 0 "register_operand" "")
10620 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10621 (match_operand:QI 2 "register_operand" "")))
10622 (clobber (match_scratch:DI 3 ""))
10623 (clobber (reg:CC FLAGS_REG))]
10624 "TARGET_64BIT && reload_completed"
10626 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10629 [(set (match_operand:TI 0 "register_operand" "")
10630 (ashift:TI (match_operand:TI 1 "register_operand" "")
10631 (match_operand:QI 2 "immediate_operand" "")))
10632 (clobber (reg:CC FLAGS_REG))]
10633 "TARGET_64BIT && reload_completed"
10635 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10637 (define_insn "x86_64_shld"
10638 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10639 (ior:DI (ashift:DI (match_dup 0)
10640 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10641 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10642 (minus:QI (const_int 64) (match_dup 2)))))
10643 (clobber (reg:CC FLAGS_REG))]
10646 shld{q}\t{%2, %1, %0|%0, %1, %2}
10647 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10648 [(set_attr "type" "ishift")
10649 (set_attr "prefix_0f" "1")
10650 (set_attr "mode" "DI")
10651 (set_attr "athlon_decode" "vector")
10652 (set_attr "amdfam10_decode" "vector")])
10654 (define_expand "x86_64_shift_adj"
10655 [(set (reg:CCZ FLAGS_REG)
10656 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10659 (set (match_operand:DI 0 "register_operand" "")
10660 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10661 (match_operand:DI 1 "register_operand" "")
10664 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10665 (match_operand:DI 3 "register_operand" "r")
10670 (define_expand "ashldi3"
10671 [(set (match_operand:DI 0 "shiftdi_operand" "")
10672 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10673 (match_operand:QI 2 "nonmemory_operand" "")))]
10675 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10677 (define_insn "*ashldi3_1_rex64"
10678 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10679 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10680 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10681 (clobber (reg:CC FLAGS_REG))]
10682 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10684 switch (get_attr_type (insn))
10687 gcc_assert (operands[2] == const1_rtx);
10688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10689 return "add{q}\t{%0, %0|%0, %0}";
10692 gcc_assert (CONST_INT_P (operands[2]));
10693 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10694 operands[1] = gen_rtx_MULT (DImode, operands[1],
10695 GEN_INT (1 << INTVAL (operands[2])));
10696 return "lea{q}\t{%a1, %0|%0, %a1}";
10699 if (REG_P (operands[2]))
10700 return "sal{q}\t{%b2, %0|%0, %b2}";
10701 else if (operands[2] == const1_rtx
10702 && (TARGET_SHIFT1 || optimize_size))
10703 return "sal{q}\t%0";
10705 return "sal{q}\t{%2, %0|%0, %2}";
10708 [(set (attr "type")
10709 (cond [(eq_attr "alternative" "1")
10710 (const_string "lea")
10711 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10713 (match_operand 0 "register_operand" ""))
10714 (match_operand 2 "const1_operand" ""))
10715 (const_string "alu")
10717 (const_string "ishift")))
10718 (set_attr "mode" "DI")])
10720 ;; Convert lea to the lea pattern to avoid flags dependency.
10722 [(set (match_operand:DI 0 "register_operand" "")
10723 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10724 (match_operand:QI 2 "immediate_operand" "")))
10725 (clobber (reg:CC FLAGS_REG))]
10726 "TARGET_64BIT && reload_completed
10727 && true_regnum (operands[0]) != true_regnum (operands[1])"
10728 [(set (match_dup 0)
10729 (mult:DI (match_dup 1)
10731 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10733 ;; This pattern can't accept a variable shift count, since shifts by
10734 ;; zero don't affect the flags. We assume that shifts by constant
10735 ;; zero are optimized away.
10736 (define_insn "*ashldi3_cmp_rex64"
10737 [(set (reg FLAGS_REG)
10739 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10740 (match_operand:QI 2 "immediate_operand" "e"))
10742 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10743 (ashift:DI (match_dup 1) (match_dup 2)))]
10744 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10745 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10747 || !TARGET_PARTIAL_FLAG_REG_STALL
10748 || (operands[2] == const1_rtx
10750 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10752 switch (get_attr_type (insn))
10755 gcc_assert (operands[2] == const1_rtx);
10756 return "add{q}\t{%0, %0|%0, %0}";
10759 if (REG_P (operands[2]))
10760 return "sal{q}\t{%b2, %0|%0, %b2}";
10761 else if (operands[2] == const1_rtx
10762 && (TARGET_SHIFT1 || optimize_size))
10763 return "sal{q}\t%0";
10765 return "sal{q}\t{%2, %0|%0, %2}";
10768 [(set (attr "type")
10769 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10771 (match_operand 0 "register_operand" ""))
10772 (match_operand 2 "const1_operand" ""))
10773 (const_string "alu")
10775 (const_string "ishift")))
10776 (set_attr "mode" "DI")])
10778 (define_insn "*ashldi3_cconly_rex64"
10779 [(set (reg FLAGS_REG)
10781 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10782 (match_operand:QI 2 "immediate_operand" "e"))
10784 (clobber (match_scratch:DI 0 "=r"))]
10785 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10786 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10788 || !TARGET_PARTIAL_FLAG_REG_STALL
10789 || (operands[2] == const1_rtx
10791 || TARGET_DOUBLE_WITH_ADD)))"
10793 switch (get_attr_type (insn))
10796 gcc_assert (operands[2] == const1_rtx);
10797 return "add{q}\t{%0, %0|%0, %0}";
10800 if (REG_P (operands[2]))
10801 return "sal{q}\t{%b2, %0|%0, %b2}";
10802 else if (operands[2] == const1_rtx
10803 && (TARGET_SHIFT1 || optimize_size))
10804 return "sal{q}\t%0";
10806 return "sal{q}\t{%2, %0|%0, %2}";
10809 [(set (attr "type")
10810 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10812 (match_operand 0 "register_operand" ""))
10813 (match_operand 2 "const1_operand" ""))
10814 (const_string "alu")
10816 (const_string "ishift")))
10817 (set_attr "mode" "DI")])
10819 (define_insn "*ashldi3_1"
10820 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10821 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10822 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10823 (clobber (reg:CC FLAGS_REG))]
10826 [(set_attr "type" "multi")])
10828 ;; By default we don't ask for a scratch register, because when DImode
10829 ;; values are manipulated, registers are already at a premium. But if
10830 ;; we have one handy, we won't turn it away.
10832 [(match_scratch:SI 3 "r")
10833 (parallel [(set (match_operand:DI 0 "register_operand" "")
10834 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10835 (match_operand:QI 2 "nonmemory_operand" "")))
10836 (clobber (reg:CC FLAGS_REG))])
10838 "!TARGET_64BIT && TARGET_CMOVE"
10840 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10843 [(set (match_operand:DI 0 "register_operand" "")
10844 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10845 (match_operand:QI 2 "nonmemory_operand" "")))
10846 (clobber (reg:CC FLAGS_REG))]
10847 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10848 ? flow2_completed : reload_completed)"
10850 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10852 (define_insn "x86_shld_1"
10853 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10854 (ior:SI (ashift:SI (match_dup 0)
10855 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10856 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10857 (minus:QI (const_int 32) (match_dup 2)))))
10858 (clobber (reg:CC FLAGS_REG))]
10861 shld{l}\t{%2, %1, %0|%0, %1, %2}
10862 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10863 [(set_attr "type" "ishift")
10864 (set_attr "prefix_0f" "1")
10865 (set_attr "mode" "SI")
10866 (set_attr "pent_pair" "np")
10867 (set_attr "athlon_decode" "vector")
10868 (set_attr "amdfam10_decode" "vector")])
10870 (define_expand "x86_shift_adj_1"
10871 [(set (reg:CCZ FLAGS_REG)
10872 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10875 (set (match_operand:SI 0 "register_operand" "")
10876 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10877 (match_operand:SI 1 "register_operand" "")
10880 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10881 (match_operand:SI 3 "register_operand" "r")
10886 (define_expand "x86_shift_adj_2"
10887 [(use (match_operand:SI 0 "register_operand" ""))
10888 (use (match_operand:SI 1 "register_operand" ""))
10889 (use (match_operand:QI 2 "register_operand" ""))]
10892 rtx label = gen_label_rtx ();
10895 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10897 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10898 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10899 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10900 gen_rtx_LABEL_REF (VOIDmode, label),
10902 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10903 JUMP_LABEL (tmp) = label;
10905 emit_move_insn (operands[0], operands[1]);
10906 ix86_expand_clear (operands[1]);
10908 emit_label (label);
10909 LABEL_NUSES (label) = 1;
10914 (define_expand "ashlsi3"
10915 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10916 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10917 (match_operand:QI 2 "nonmemory_operand" "")))
10918 (clobber (reg:CC FLAGS_REG))]
10920 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10922 (define_insn "*ashlsi3_1"
10923 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10924 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10925 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10929 switch (get_attr_type (insn))
10932 gcc_assert (operands[2] == const1_rtx);
10933 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10934 return "add{l}\t{%0, %0|%0, %0}";
10940 if (REG_P (operands[2]))
10941 return "sal{l}\t{%b2, %0|%0, %b2}";
10942 else if (operands[2] == const1_rtx
10943 && (TARGET_SHIFT1 || optimize_size))
10944 return "sal{l}\t%0";
10946 return "sal{l}\t{%2, %0|%0, %2}";
10949 [(set (attr "type")
10950 (cond [(eq_attr "alternative" "1")
10951 (const_string "lea")
10952 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10954 (match_operand 0 "register_operand" ""))
10955 (match_operand 2 "const1_operand" ""))
10956 (const_string "alu")
10958 (const_string "ishift")))
10959 (set_attr "mode" "SI")])
10961 ;; Convert lea to the lea pattern to avoid flags dependency.
10963 [(set (match_operand 0 "register_operand" "")
10964 (ashift (match_operand 1 "index_register_operand" "")
10965 (match_operand:QI 2 "const_int_operand" "")))
10966 (clobber (reg:CC FLAGS_REG))]
10968 && true_regnum (operands[0]) != true_regnum (operands[1])
10969 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10973 enum machine_mode mode = GET_MODE (operands[0]);
10975 if (GET_MODE_SIZE (mode) < 4)
10976 operands[0] = gen_lowpart (SImode, operands[0]);
10978 operands[1] = gen_lowpart (Pmode, operands[1]);
10979 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10981 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10982 if (Pmode != SImode)
10983 pat = gen_rtx_SUBREG (SImode, pat, 0);
10984 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10988 ;; Rare case of shifting RSP is handled by generating move and shift
10990 [(set (match_operand 0 "register_operand" "")
10991 (ashift (match_operand 1 "register_operand" "")
10992 (match_operand:QI 2 "const_int_operand" "")))
10993 (clobber (reg:CC FLAGS_REG))]
10995 && true_regnum (operands[0]) != true_regnum (operands[1])"
10999 emit_move_insn (operands[0], operands[1]);
11000 pat = gen_rtx_SET (VOIDmode, operands[0],
11001 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11002 operands[0], operands[2]));
11003 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11004 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11008 (define_insn "*ashlsi3_1_zext"
11009 [(set (match_operand:DI 0 "register_operand" "=r,r")
11010 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11011 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11012 (clobber (reg:CC FLAGS_REG))]
11013 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11015 switch (get_attr_type (insn))
11018 gcc_assert (operands[2] == const1_rtx);
11019 return "add{l}\t{%k0, %k0|%k0, %k0}";
11025 if (REG_P (operands[2]))
11026 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11027 else if (operands[2] == const1_rtx
11028 && (TARGET_SHIFT1 || optimize_size))
11029 return "sal{l}\t%k0";
11031 return "sal{l}\t{%2, %k0|%k0, %2}";
11034 [(set (attr "type")
11035 (cond [(eq_attr "alternative" "1")
11036 (const_string "lea")
11037 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11039 (match_operand 2 "const1_operand" ""))
11040 (const_string "alu")
11042 (const_string "ishift")))
11043 (set_attr "mode" "SI")])
11045 ;; Convert lea to the lea pattern to avoid flags dependency.
11047 [(set (match_operand:DI 0 "register_operand" "")
11048 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11049 (match_operand:QI 2 "const_int_operand" ""))))
11050 (clobber (reg:CC FLAGS_REG))]
11051 "TARGET_64BIT && reload_completed
11052 && true_regnum (operands[0]) != true_regnum (operands[1])"
11053 [(set (match_dup 0) (zero_extend:DI
11054 (subreg:SI (mult:SI (match_dup 1)
11055 (match_dup 2)) 0)))]
11057 operands[1] = gen_lowpart (Pmode, operands[1]);
11058 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11061 ;; This pattern can't accept a variable shift count, since shifts by
11062 ;; zero don't affect the flags. We assume that shifts by constant
11063 ;; zero are optimized away.
11064 (define_insn "*ashlsi3_cmp"
11065 [(set (reg FLAGS_REG)
11067 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11068 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11070 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11071 (ashift:SI (match_dup 1) (match_dup 2)))]
11072 "ix86_match_ccmode (insn, CCGOCmode)
11073 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11075 || !TARGET_PARTIAL_FLAG_REG_STALL
11076 || (operands[2] == const1_rtx
11078 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11080 switch (get_attr_type (insn))
11083 gcc_assert (operands[2] == const1_rtx);
11084 return "add{l}\t{%0, %0|%0, %0}";
11087 if (REG_P (operands[2]))
11088 return "sal{l}\t{%b2, %0|%0, %b2}";
11089 else if (operands[2] == const1_rtx
11090 && (TARGET_SHIFT1 || optimize_size))
11091 return "sal{l}\t%0";
11093 return "sal{l}\t{%2, %0|%0, %2}";
11096 [(set (attr "type")
11097 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11099 (match_operand 0 "register_operand" ""))
11100 (match_operand 2 "const1_operand" ""))
11101 (const_string "alu")
11103 (const_string "ishift")))
11104 (set_attr "mode" "SI")])
11106 (define_insn "*ashlsi3_cconly"
11107 [(set (reg FLAGS_REG)
11109 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11110 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11112 (clobber (match_scratch:SI 0 "=r"))]
11113 "ix86_match_ccmode (insn, CCGOCmode)
11114 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11116 || !TARGET_PARTIAL_FLAG_REG_STALL
11117 || (operands[2] == const1_rtx
11119 || TARGET_DOUBLE_WITH_ADD)))"
11121 switch (get_attr_type (insn))
11124 gcc_assert (operands[2] == const1_rtx);
11125 return "add{l}\t{%0, %0|%0, %0}";
11128 if (REG_P (operands[2]))
11129 return "sal{l}\t{%b2, %0|%0, %b2}";
11130 else if (operands[2] == const1_rtx
11131 && (TARGET_SHIFT1 || optimize_size))
11132 return "sal{l}\t%0";
11134 return "sal{l}\t{%2, %0|%0, %2}";
11137 [(set (attr "type")
11138 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11140 (match_operand 0 "register_operand" ""))
11141 (match_operand 2 "const1_operand" ""))
11142 (const_string "alu")
11144 (const_string "ishift")))
11145 (set_attr "mode" "SI")])
11147 (define_insn "*ashlsi3_cmp_zext"
11148 [(set (reg FLAGS_REG)
11150 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11151 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11153 (set (match_operand:DI 0 "register_operand" "=r")
11154 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11155 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11158 || !TARGET_PARTIAL_FLAG_REG_STALL
11159 || (operands[2] == const1_rtx
11161 || TARGET_DOUBLE_WITH_ADD)))"
11163 switch (get_attr_type (insn))
11166 gcc_assert (operands[2] == const1_rtx);
11167 return "add{l}\t{%k0, %k0|%k0, %k0}";
11170 if (REG_P (operands[2]))
11171 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11172 else if (operands[2] == const1_rtx
11173 && (TARGET_SHIFT1 || optimize_size))
11174 return "sal{l}\t%k0";
11176 return "sal{l}\t{%2, %k0|%k0, %2}";
11179 [(set (attr "type")
11180 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11182 (match_operand 2 "const1_operand" ""))
11183 (const_string "alu")
11185 (const_string "ishift")))
11186 (set_attr "mode" "SI")])
11188 (define_expand "ashlhi3"
11189 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11190 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11191 (match_operand:QI 2 "nonmemory_operand" "")))
11192 (clobber (reg:CC FLAGS_REG))]
11193 "TARGET_HIMODE_MATH"
11194 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11196 (define_insn "*ashlhi3_1_lea"
11197 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11198 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11199 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11200 (clobber (reg:CC FLAGS_REG))]
11201 "!TARGET_PARTIAL_REG_STALL
11202 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11204 switch (get_attr_type (insn))
11209 gcc_assert (operands[2] == const1_rtx);
11210 return "add{w}\t{%0, %0|%0, %0}";
11213 if (REG_P (operands[2]))
11214 return "sal{w}\t{%b2, %0|%0, %b2}";
11215 else if (operands[2] == const1_rtx
11216 && (TARGET_SHIFT1 || optimize_size))
11217 return "sal{w}\t%0";
11219 return "sal{w}\t{%2, %0|%0, %2}";
11222 [(set (attr "type")
11223 (cond [(eq_attr "alternative" "1")
11224 (const_string "lea")
11225 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11227 (match_operand 0 "register_operand" ""))
11228 (match_operand 2 "const1_operand" ""))
11229 (const_string "alu")
11231 (const_string "ishift")))
11232 (set_attr "mode" "HI,SI")])
11234 (define_insn "*ashlhi3_1"
11235 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11236 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11237 (match_operand:QI 2 "nonmemory_operand" "cI")))
11238 (clobber (reg:CC FLAGS_REG))]
11239 "TARGET_PARTIAL_REG_STALL
11240 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11242 switch (get_attr_type (insn))
11245 gcc_assert (operands[2] == const1_rtx);
11246 return "add{w}\t{%0, %0|%0, %0}";
11249 if (REG_P (operands[2]))
11250 return "sal{w}\t{%b2, %0|%0, %b2}";
11251 else if (operands[2] == const1_rtx
11252 && (TARGET_SHIFT1 || optimize_size))
11253 return "sal{w}\t%0";
11255 return "sal{w}\t{%2, %0|%0, %2}";
11258 [(set (attr "type")
11259 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11261 (match_operand 0 "register_operand" ""))
11262 (match_operand 2 "const1_operand" ""))
11263 (const_string "alu")
11265 (const_string "ishift")))
11266 (set_attr "mode" "HI")])
11268 ;; This pattern can't accept a variable shift count, since shifts by
11269 ;; zero don't affect the flags. We assume that shifts by constant
11270 ;; zero are optimized away.
11271 (define_insn "*ashlhi3_cmp"
11272 [(set (reg FLAGS_REG)
11274 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11275 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11277 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11278 (ashift:HI (match_dup 1) (match_dup 2)))]
11279 "ix86_match_ccmode (insn, CCGOCmode)
11280 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11282 || !TARGET_PARTIAL_FLAG_REG_STALL
11283 || (operands[2] == const1_rtx
11285 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11287 switch (get_attr_type (insn))
11290 gcc_assert (operands[2] == const1_rtx);
11291 return "add{w}\t{%0, %0|%0, %0}";
11294 if (REG_P (operands[2]))
11295 return "sal{w}\t{%b2, %0|%0, %b2}";
11296 else if (operands[2] == const1_rtx
11297 && (TARGET_SHIFT1 || optimize_size))
11298 return "sal{w}\t%0";
11300 return "sal{w}\t{%2, %0|%0, %2}";
11303 [(set (attr "type")
11304 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11306 (match_operand 0 "register_operand" ""))
11307 (match_operand 2 "const1_operand" ""))
11308 (const_string "alu")
11310 (const_string "ishift")))
11311 (set_attr "mode" "HI")])
11313 (define_insn "*ashlhi3_cconly"
11314 [(set (reg FLAGS_REG)
11316 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11317 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11319 (clobber (match_scratch:HI 0 "=r"))]
11320 "ix86_match_ccmode (insn, CCGOCmode)
11321 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11323 || !TARGET_PARTIAL_FLAG_REG_STALL
11324 || (operands[2] == const1_rtx
11326 || TARGET_DOUBLE_WITH_ADD)))"
11328 switch (get_attr_type (insn))
11331 gcc_assert (operands[2] == const1_rtx);
11332 return "add{w}\t{%0, %0|%0, %0}";
11335 if (REG_P (operands[2]))
11336 return "sal{w}\t{%b2, %0|%0, %b2}";
11337 else if (operands[2] == const1_rtx
11338 && (TARGET_SHIFT1 || optimize_size))
11339 return "sal{w}\t%0";
11341 return "sal{w}\t{%2, %0|%0, %2}";
11344 [(set (attr "type")
11345 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11347 (match_operand 0 "register_operand" ""))
11348 (match_operand 2 "const1_operand" ""))
11349 (const_string "alu")
11351 (const_string "ishift")))
11352 (set_attr "mode" "HI")])
11354 (define_expand "ashlqi3"
11355 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11356 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11357 (match_operand:QI 2 "nonmemory_operand" "")))
11358 (clobber (reg:CC FLAGS_REG))]
11359 "TARGET_QIMODE_MATH"
11360 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11362 ;; %%% Potential partial reg stall on alternative 2. What to do?
11364 (define_insn "*ashlqi3_1_lea"
11365 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11366 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11367 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11368 (clobber (reg:CC FLAGS_REG))]
11369 "!TARGET_PARTIAL_REG_STALL
11370 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11372 switch (get_attr_type (insn))
11377 gcc_assert (operands[2] == const1_rtx);
11378 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11379 return "add{l}\t{%k0, %k0|%k0, %k0}";
11381 return "add{b}\t{%0, %0|%0, %0}";
11384 if (REG_P (operands[2]))
11386 if (get_attr_mode (insn) == MODE_SI)
11387 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11389 return "sal{b}\t{%b2, %0|%0, %b2}";
11391 else if (operands[2] == const1_rtx
11392 && (TARGET_SHIFT1 || optimize_size))
11394 if (get_attr_mode (insn) == MODE_SI)
11395 return "sal{l}\t%0";
11397 return "sal{b}\t%0";
11401 if (get_attr_mode (insn) == MODE_SI)
11402 return "sal{l}\t{%2, %k0|%k0, %2}";
11404 return "sal{b}\t{%2, %0|%0, %2}";
11408 [(set (attr "type")
11409 (cond [(eq_attr "alternative" "2")
11410 (const_string "lea")
11411 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11413 (match_operand 0 "register_operand" ""))
11414 (match_operand 2 "const1_operand" ""))
11415 (const_string "alu")
11417 (const_string "ishift")))
11418 (set_attr "mode" "QI,SI,SI")])
11420 (define_insn "*ashlqi3_1"
11421 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11422 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11423 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11424 (clobber (reg:CC FLAGS_REG))]
11425 "TARGET_PARTIAL_REG_STALL
11426 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11428 switch (get_attr_type (insn))
11431 gcc_assert (operands[2] == const1_rtx);
11432 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11433 return "add{l}\t{%k0, %k0|%k0, %k0}";
11435 return "add{b}\t{%0, %0|%0, %0}";
11438 if (REG_P (operands[2]))
11440 if (get_attr_mode (insn) == MODE_SI)
11441 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11443 return "sal{b}\t{%b2, %0|%0, %b2}";
11445 else if (operands[2] == const1_rtx
11446 && (TARGET_SHIFT1 || optimize_size))
11448 if (get_attr_mode (insn) == MODE_SI)
11449 return "sal{l}\t%0";
11451 return "sal{b}\t%0";
11455 if (get_attr_mode (insn) == MODE_SI)
11456 return "sal{l}\t{%2, %k0|%k0, %2}";
11458 return "sal{b}\t{%2, %0|%0, %2}";
11462 [(set (attr "type")
11463 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11465 (match_operand 0 "register_operand" ""))
11466 (match_operand 2 "const1_operand" ""))
11467 (const_string "alu")
11469 (const_string "ishift")))
11470 (set_attr "mode" "QI,SI")])
11472 ;; This pattern can't accept a variable shift count, since shifts by
11473 ;; zero don't affect the flags. We assume that shifts by constant
11474 ;; zero are optimized away.
11475 (define_insn "*ashlqi3_cmp"
11476 [(set (reg FLAGS_REG)
11478 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11479 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11481 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11482 (ashift:QI (match_dup 1) (match_dup 2)))]
11483 "ix86_match_ccmode (insn, CCGOCmode)
11484 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11486 || !TARGET_PARTIAL_FLAG_REG_STALL
11487 || (operands[2] == const1_rtx
11489 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11491 switch (get_attr_type (insn))
11494 gcc_assert (operands[2] == const1_rtx);
11495 return "add{b}\t{%0, %0|%0, %0}";
11498 if (REG_P (operands[2]))
11499 return "sal{b}\t{%b2, %0|%0, %b2}";
11500 else if (operands[2] == const1_rtx
11501 && (TARGET_SHIFT1 || optimize_size))
11502 return "sal{b}\t%0";
11504 return "sal{b}\t{%2, %0|%0, %2}";
11507 [(set (attr "type")
11508 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11510 (match_operand 0 "register_operand" ""))
11511 (match_operand 2 "const1_operand" ""))
11512 (const_string "alu")
11514 (const_string "ishift")))
11515 (set_attr "mode" "QI")])
11517 (define_insn "*ashlqi3_cconly"
11518 [(set (reg FLAGS_REG)
11520 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11521 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11523 (clobber (match_scratch:QI 0 "=q"))]
11524 "ix86_match_ccmode (insn, CCGOCmode)
11525 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11527 || !TARGET_PARTIAL_FLAG_REG_STALL
11528 || (operands[2] == const1_rtx
11530 || TARGET_DOUBLE_WITH_ADD)))"
11532 switch (get_attr_type (insn))
11535 gcc_assert (operands[2] == const1_rtx);
11536 return "add{b}\t{%0, %0|%0, %0}";
11539 if (REG_P (operands[2]))
11540 return "sal{b}\t{%b2, %0|%0, %b2}";
11541 else if (operands[2] == const1_rtx
11542 && (TARGET_SHIFT1 || optimize_size))
11543 return "sal{b}\t%0";
11545 return "sal{b}\t{%2, %0|%0, %2}";
11548 [(set (attr "type")
11549 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11551 (match_operand 0 "register_operand" ""))
11552 (match_operand 2 "const1_operand" ""))
11553 (const_string "alu")
11555 (const_string "ishift")))
11556 (set_attr "mode" "QI")])
11558 ;; See comment above `ashldi3' about how this works.
11560 (define_expand "ashrti3"
11561 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11562 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11563 (match_operand:QI 2 "nonmemory_operand" "")))
11564 (clobber (reg:CC FLAGS_REG))])]
11567 if (! immediate_operand (operands[2], QImode))
11569 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11572 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11576 (define_insn "ashrti3_1"
11577 [(set (match_operand:TI 0 "register_operand" "=r")
11578 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11579 (match_operand:QI 2 "register_operand" "c")))
11580 (clobber (match_scratch:DI 3 "=&r"))
11581 (clobber (reg:CC FLAGS_REG))]
11584 [(set_attr "type" "multi")])
11586 (define_insn "*ashrti3_2"
11587 [(set (match_operand:TI 0 "register_operand" "=r")
11588 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11589 (match_operand:QI 2 "immediate_operand" "O")))
11590 (clobber (reg:CC FLAGS_REG))]
11593 [(set_attr "type" "multi")])
11596 [(set (match_operand:TI 0 "register_operand" "")
11597 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11598 (match_operand:QI 2 "register_operand" "")))
11599 (clobber (match_scratch:DI 3 ""))
11600 (clobber (reg:CC FLAGS_REG))]
11601 "TARGET_64BIT && reload_completed"
11603 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11606 [(set (match_operand:TI 0 "register_operand" "")
11607 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11608 (match_operand:QI 2 "immediate_operand" "")))
11609 (clobber (reg:CC FLAGS_REG))]
11610 "TARGET_64BIT && reload_completed"
11612 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11614 (define_insn "x86_64_shrd"
11615 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11616 (ior:DI (ashiftrt:DI (match_dup 0)
11617 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11618 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11619 (minus:QI (const_int 64) (match_dup 2)))))
11620 (clobber (reg:CC FLAGS_REG))]
11623 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11624 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11625 [(set_attr "type" "ishift")
11626 (set_attr "prefix_0f" "1")
11627 (set_attr "mode" "DI")
11628 (set_attr "athlon_decode" "vector")
11629 (set_attr "amdfam10_decode" "vector")])
11631 (define_expand "ashrdi3"
11632 [(set (match_operand:DI 0 "shiftdi_operand" "")
11633 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11634 (match_operand:QI 2 "nonmemory_operand" "")))]
11636 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11638 (define_insn "*ashrdi3_63_rex64"
11639 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11640 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11641 (match_operand:DI 2 "const_int_operand" "i,i")))
11642 (clobber (reg:CC FLAGS_REG))]
11643 "TARGET_64BIT && INTVAL (operands[2]) == 63
11644 && (TARGET_USE_CLTD || optimize_size)
11645 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11648 sar{q}\t{%2, %0|%0, %2}"
11649 [(set_attr "type" "imovx,ishift")
11650 (set_attr "prefix_0f" "0,*")
11651 (set_attr "length_immediate" "0,*")
11652 (set_attr "modrm" "0,1")
11653 (set_attr "mode" "DI")])
11655 (define_insn "*ashrdi3_1_one_bit_rex64"
11656 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11657 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11658 (match_operand:QI 2 "const1_operand" "")))
11659 (clobber (reg:CC FLAGS_REG))]
11660 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11661 && (TARGET_SHIFT1 || optimize_size)"
11663 [(set_attr "type" "ishift")
11664 (set (attr "length")
11665 (if_then_else (match_operand:DI 0 "register_operand" "")
11667 (const_string "*")))])
11669 (define_insn "*ashrdi3_1_rex64"
11670 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11671 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11672 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11673 (clobber (reg:CC FLAGS_REG))]
11674 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11676 sar{q}\t{%2, %0|%0, %2}
11677 sar{q}\t{%b2, %0|%0, %b2}"
11678 [(set_attr "type" "ishift")
11679 (set_attr "mode" "DI")])
11681 ;; This pattern can't accept a variable shift count, since shifts by
11682 ;; zero don't affect the flags. We assume that shifts by constant
11683 ;; zero are optimized away.
11684 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11685 [(set (reg FLAGS_REG)
11687 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11688 (match_operand:QI 2 "const1_operand" ""))
11690 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11691 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11692 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11693 && (TARGET_SHIFT1 || optimize_size)
11694 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11696 [(set_attr "type" "ishift")
11697 (set (attr "length")
11698 (if_then_else (match_operand:DI 0 "register_operand" "")
11700 (const_string "*")))])
11702 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11703 [(set (reg FLAGS_REG)
11705 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11706 (match_operand:QI 2 "const1_operand" ""))
11708 (clobber (match_scratch:DI 0 "=r"))]
11709 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11710 && (TARGET_SHIFT1 || optimize_size)
11711 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11713 [(set_attr "type" "ishift")
11714 (set_attr "length" "2")])
11716 ;; This pattern can't accept a variable shift count, since shifts by
11717 ;; zero don't affect the flags. We assume that shifts by constant
11718 ;; zero are optimized away.
11719 (define_insn "*ashrdi3_cmp_rex64"
11720 [(set (reg FLAGS_REG)
11722 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11723 (match_operand:QI 2 "const_int_operand" "n"))
11725 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11726 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11727 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11728 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11730 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11731 "sar{q}\t{%2, %0|%0, %2}"
11732 [(set_attr "type" "ishift")
11733 (set_attr "mode" "DI")])
11735 (define_insn "*ashrdi3_cconly_rex64"
11736 [(set (reg FLAGS_REG)
11738 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11739 (match_operand:QI 2 "const_int_operand" "n"))
11741 (clobber (match_scratch:DI 0 "=r"))]
11742 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11743 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11745 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11746 "sar{q}\t{%2, %0|%0, %2}"
11747 [(set_attr "type" "ishift")
11748 (set_attr "mode" "DI")])
11750 (define_insn "*ashrdi3_1"
11751 [(set (match_operand:DI 0 "register_operand" "=r")
11752 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11753 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11754 (clobber (reg:CC FLAGS_REG))]
11757 [(set_attr "type" "multi")])
11759 ;; By default we don't ask for a scratch register, because when DImode
11760 ;; values are manipulated, registers are already at a premium. But if
11761 ;; we have one handy, we won't turn it away.
11763 [(match_scratch:SI 3 "r")
11764 (parallel [(set (match_operand:DI 0 "register_operand" "")
11765 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11766 (match_operand:QI 2 "nonmemory_operand" "")))
11767 (clobber (reg:CC FLAGS_REG))])
11769 "!TARGET_64BIT && TARGET_CMOVE"
11771 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11774 [(set (match_operand:DI 0 "register_operand" "")
11775 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11776 (match_operand:QI 2 "nonmemory_operand" "")))
11777 (clobber (reg:CC FLAGS_REG))]
11778 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11779 ? flow2_completed : reload_completed)"
11781 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11783 (define_insn "x86_shrd_1"
11784 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11785 (ior:SI (ashiftrt:SI (match_dup 0)
11786 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11787 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11788 (minus:QI (const_int 32) (match_dup 2)))))
11789 (clobber (reg:CC FLAGS_REG))]
11792 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11793 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11794 [(set_attr "type" "ishift")
11795 (set_attr "prefix_0f" "1")
11796 (set_attr "pent_pair" "np")
11797 (set_attr "mode" "SI")])
11799 (define_expand "x86_shift_adj_3"
11800 [(use (match_operand:SI 0 "register_operand" ""))
11801 (use (match_operand:SI 1 "register_operand" ""))
11802 (use (match_operand:QI 2 "register_operand" ""))]
11805 rtx label = gen_label_rtx ();
11808 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11810 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11811 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11812 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11813 gen_rtx_LABEL_REF (VOIDmode, label),
11815 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11816 JUMP_LABEL (tmp) = label;
11818 emit_move_insn (operands[0], operands[1]);
11819 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11821 emit_label (label);
11822 LABEL_NUSES (label) = 1;
11827 (define_insn "ashrsi3_31"
11828 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11829 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11830 (match_operand:SI 2 "const_int_operand" "i,i")))
11831 (clobber (reg:CC FLAGS_REG))]
11832 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11833 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11836 sar{l}\t{%2, %0|%0, %2}"
11837 [(set_attr "type" "imovx,ishift")
11838 (set_attr "prefix_0f" "0,*")
11839 (set_attr "length_immediate" "0,*")
11840 (set_attr "modrm" "0,1")
11841 (set_attr "mode" "SI")])
11843 (define_insn "*ashrsi3_31_zext"
11844 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11845 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11846 (match_operand:SI 2 "const_int_operand" "i,i"))))
11847 (clobber (reg:CC FLAGS_REG))]
11848 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11849 && INTVAL (operands[2]) == 31
11850 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11853 sar{l}\t{%2, %k0|%k0, %2}"
11854 [(set_attr "type" "imovx,ishift")
11855 (set_attr "prefix_0f" "0,*")
11856 (set_attr "length_immediate" "0,*")
11857 (set_attr "modrm" "0,1")
11858 (set_attr "mode" "SI")])
11860 (define_expand "ashrsi3"
11861 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11862 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11863 (match_operand:QI 2 "nonmemory_operand" "")))
11864 (clobber (reg:CC FLAGS_REG))]
11866 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11868 (define_insn "*ashrsi3_1_one_bit"
11869 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11870 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11871 (match_operand:QI 2 "const1_operand" "")))
11872 (clobber (reg:CC FLAGS_REG))]
11873 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11874 && (TARGET_SHIFT1 || optimize_size)"
11876 [(set_attr "type" "ishift")
11877 (set (attr "length")
11878 (if_then_else (match_operand:SI 0 "register_operand" "")
11880 (const_string "*")))])
11882 (define_insn "*ashrsi3_1_one_bit_zext"
11883 [(set (match_operand:DI 0 "register_operand" "=r")
11884 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11885 (match_operand:QI 2 "const1_operand" ""))))
11886 (clobber (reg:CC FLAGS_REG))]
11887 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11888 && (TARGET_SHIFT1 || optimize_size)"
11890 [(set_attr "type" "ishift")
11891 (set_attr "length" "2")])
11893 (define_insn "*ashrsi3_1"
11894 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11895 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11896 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11897 (clobber (reg:CC FLAGS_REG))]
11898 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11900 sar{l}\t{%2, %0|%0, %2}
11901 sar{l}\t{%b2, %0|%0, %b2}"
11902 [(set_attr "type" "ishift")
11903 (set_attr "mode" "SI")])
11905 (define_insn "*ashrsi3_1_zext"
11906 [(set (match_operand:DI 0 "register_operand" "=r,r")
11907 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11908 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11909 (clobber (reg:CC FLAGS_REG))]
11910 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11912 sar{l}\t{%2, %k0|%k0, %2}
11913 sar{l}\t{%b2, %k0|%k0, %b2}"
11914 [(set_attr "type" "ishift")
11915 (set_attr "mode" "SI")])
11917 ;; This pattern can't accept a variable shift count, since shifts by
11918 ;; zero don't affect the flags. We assume that shifts by constant
11919 ;; zero are optimized away.
11920 (define_insn "*ashrsi3_one_bit_cmp"
11921 [(set (reg FLAGS_REG)
11923 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11924 (match_operand:QI 2 "const1_operand" ""))
11926 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11927 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11928 "ix86_match_ccmode (insn, CCGOCmode)
11929 && (TARGET_SHIFT1 || optimize_size)
11930 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11932 [(set_attr "type" "ishift")
11933 (set (attr "length")
11934 (if_then_else (match_operand:SI 0 "register_operand" "")
11936 (const_string "*")))])
11938 (define_insn "*ashrsi3_one_bit_cconly"
11939 [(set (reg FLAGS_REG)
11941 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11942 (match_operand:QI 2 "const1_operand" ""))
11944 (clobber (match_scratch:SI 0 "=r"))]
11945 "ix86_match_ccmode (insn, CCGOCmode)
11946 && (TARGET_SHIFT1 || optimize_size)
11947 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11949 [(set_attr "type" "ishift")
11950 (set_attr "length" "2")])
11952 (define_insn "*ashrsi3_one_bit_cmp_zext"
11953 [(set (reg FLAGS_REG)
11955 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11956 (match_operand:QI 2 "const1_operand" ""))
11958 (set (match_operand:DI 0 "register_operand" "=r")
11959 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11960 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11961 && (TARGET_SHIFT1 || optimize_size)
11962 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11964 [(set_attr "type" "ishift")
11965 (set_attr "length" "2")])
11967 ;; This pattern can't accept a variable shift count, since shifts by
11968 ;; zero don't affect the flags. We assume that shifts by constant
11969 ;; zero are optimized away.
11970 (define_insn "*ashrsi3_cmp"
11971 [(set (reg FLAGS_REG)
11973 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11974 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11976 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11977 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11978 "ix86_match_ccmode (insn, CCGOCmode)
11979 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11981 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11982 "sar{l}\t{%2, %0|%0, %2}"
11983 [(set_attr "type" "ishift")
11984 (set_attr "mode" "SI")])
11986 (define_insn "*ashrsi3_cconly"
11987 [(set (reg FLAGS_REG)
11989 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11990 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11992 (clobber (match_scratch:SI 0 "=r"))]
11993 "ix86_match_ccmode (insn, CCGOCmode)
11994 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11996 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11997 "sar{l}\t{%2, %0|%0, %2}"
11998 [(set_attr "type" "ishift")
11999 (set_attr "mode" "SI")])
12001 (define_insn "*ashrsi3_cmp_zext"
12002 [(set (reg FLAGS_REG)
12004 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12005 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12007 (set (match_operand:DI 0 "register_operand" "=r")
12008 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12009 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12010 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12012 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12013 "sar{l}\t{%2, %k0|%k0, %2}"
12014 [(set_attr "type" "ishift")
12015 (set_attr "mode" "SI")])
12017 (define_expand "ashrhi3"
12018 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12019 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12020 (match_operand:QI 2 "nonmemory_operand" "")))
12021 (clobber (reg:CC FLAGS_REG))]
12022 "TARGET_HIMODE_MATH"
12023 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12025 (define_insn "*ashrhi3_1_one_bit"
12026 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12027 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12028 (match_operand:QI 2 "const1_operand" "")))
12029 (clobber (reg:CC FLAGS_REG))]
12030 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12031 && (TARGET_SHIFT1 || optimize_size)"
12033 [(set_attr "type" "ishift")
12034 (set (attr "length")
12035 (if_then_else (match_operand 0 "register_operand" "")
12037 (const_string "*")))])
12039 (define_insn "*ashrhi3_1"
12040 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12041 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12042 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12043 (clobber (reg:CC FLAGS_REG))]
12044 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12046 sar{w}\t{%2, %0|%0, %2}
12047 sar{w}\t{%b2, %0|%0, %b2}"
12048 [(set_attr "type" "ishift")
12049 (set_attr "mode" "HI")])
12051 ;; This pattern can't accept a variable shift count, since shifts by
12052 ;; zero don't affect the flags. We assume that shifts by constant
12053 ;; zero are optimized away.
12054 (define_insn "*ashrhi3_one_bit_cmp"
12055 [(set (reg FLAGS_REG)
12057 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12058 (match_operand:QI 2 "const1_operand" ""))
12060 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12061 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12062 "ix86_match_ccmode (insn, CCGOCmode)
12063 && (TARGET_SHIFT1 || optimize_size)
12064 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12066 [(set_attr "type" "ishift")
12067 (set (attr "length")
12068 (if_then_else (match_operand 0 "register_operand" "")
12070 (const_string "*")))])
12072 (define_insn "*ashrhi3_one_bit_cconly"
12073 [(set (reg FLAGS_REG)
12075 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12076 (match_operand:QI 2 "const1_operand" ""))
12078 (clobber (match_scratch:HI 0 "=r"))]
12079 "ix86_match_ccmode (insn, CCGOCmode)
12080 && (TARGET_SHIFT1 || optimize_size)
12081 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12083 [(set_attr "type" "ishift")
12084 (set_attr "length" "2")])
12086 ;; This pattern can't accept a variable shift count, since shifts by
12087 ;; zero don't affect the flags. We assume that shifts by constant
12088 ;; zero are optimized away.
12089 (define_insn "*ashrhi3_cmp"
12090 [(set (reg FLAGS_REG)
12092 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12093 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12095 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12096 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12097 "ix86_match_ccmode (insn, CCGOCmode)
12098 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12100 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12101 "sar{w}\t{%2, %0|%0, %2}"
12102 [(set_attr "type" "ishift")
12103 (set_attr "mode" "HI")])
12105 (define_insn "*ashrhi3_cconly"
12106 [(set (reg FLAGS_REG)
12108 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12109 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12111 (clobber (match_scratch:HI 0 "=r"))]
12112 "ix86_match_ccmode (insn, CCGOCmode)
12113 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12115 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12116 "sar{w}\t{%2, %0|%0, %2}"
12117 [(set_attr "type" "ishift")
12118 (set_attr "mode" "HI")])
12120 (define_expand "ashrqi3"
12121 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12122 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12123 (match_operand:QI 2 "nonmemory_operand" "")))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "TARGET_QIMODE_MATH"
12126 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12128 (define_insn "*ashrqi3_1_one_bit"
12129 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12130 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12131 (match_operand:QI 2 "const1_operand" "")))
12132 (clobber (reg:CC FLAGS_REG))]
12133 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12134 && (TARGET_SHIFT1 || optimize_size)"
12136 [(set_attr "type" "ishift")
12137 (set (attr "length")
12138 (if_then_else (match_operand 0 "register_operand" "")
12140 (const_string "*")))])
12142 (define_insn "*ashrqi3_1_one_bit_slp"
12143 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12144 (ashiftrt:QI (match_dup 0)
12145 (match_operand:QI 1 "const1_operand" "")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12148 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12149 && (TARGET_SHIFT1 || optimize_size)"
12151 [(set_attr "type" "ishift1")
12152 (set (attr "length")
12153 (if_then_else (match_operand 0 "register_operand" "")
12155 (const_string "*")))])
12157 (define_insn "*ashrqi3_1"
12158 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12159 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12160 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12161 (clobber (reg:CC FLAGS_REG))]
12162 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12164 sar{b}\t{%2, %0|%0, %2}
12165 sar{b}\t{%b2, %0|%0, %b2}"
12166 [(set_attr "type" "ishift")
12167 (set_attr "mode" "QI")])
12169 (define_insn "*ashrqi3_1_slp"
12170 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12171 (ashiftrt:QI (match_dup 0)
12172 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12173 (clobber (reg:CC FLAGS_REG))]
12174 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12175 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12177 sar{b}\t{%1, %0|%0, %1}
12178 sar{b}\t{%b1, %0|%0, %b1}"
12179 [(set_attr "type" "ishift1")
12180 (set_attr "mode" "QI")])
12182 ;; This pattern can't accept a variable shift count, since shifts by
12183 ;; zero don't affect the flags. We assume that shifts by constant
12184 ;; zero are optimized away.
12185 (define_insn "*ashrqi3_one_bit_cmp"
12186 [(set (reg FLAGS_REG)
12188 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12189 (match_operand:QI 2 "const1_operand" "I"))
12191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12192 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12193 "ix86_match_ccmode (insn, CCGOCmode)
12194 && (TARGET_SHIFT1 || optimize_size)
12195 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12197 [(set_attr "type" "ishift")
12198 (set (attr "length")
12199 (if_then_else (match_operand 0 "register_operand" "")
12201 (const_string "*")))])
12203 (define_insn "*ashrqi3_one_bit_cconly"
12204 [(set (reg FLAGS_REG)
12206 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12207 (match_operand:QI 2 "const1_operand" "I"))
12209 (clobber (match_scratch:QI 0 "=q"))]
12210 "ix86_match_ccmode (insn, CCGOCmode)
12211 && (TARGET_SHIFT1 || optimize_size)
12212 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12214 [(set_attr "type" "ishift")
12215 (set_attr "length" "2")])
12217 ;; This pattern can't accept a variable shift count, since shifts by
12218 ;; zero don't affect the flags. We assume that shifts by constant
12219 ;; zero are optimized away.
12220 (define_insn "*ashrqi3_cmp"
12221 [(set (reg FLAGS_REG)
12223 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12224 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12226 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12227 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12228 "ix86_match_ccmode (insn, CCGOCmode)
12229 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12231 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12232 "sar{b}\t{%2, %0|%0, %2}"
12233 [(set_attr "type" "ishift")
12234 (set_attr "mode" "QI")])
12236 (define_insn "*ashrqi3_cconly"
12237 [(set (reg FLAGS_REG)
12239 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12240 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12242 (clobber (match_scratch:QI 0 "=q"))]
12243 "ix86_match_ccmode (insn, CCGOCmode)
12244 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12246 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12247 "sar{b}\t{%2, %0|%0, %2}"
12248 [(set_attr "type" "ishift")
12249 (set_attr "mode" "QI")])
12252 ;; Logical shift instructions
12254 ;; See comment above `ashldi3' about how this works.
12256 (define_expand "lshrti3"
12257 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12258 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12259 (match_operand:QI 2 "nonmemory_operand" "")))
12260 (clobber (reg:CC FLAGS_REG))])]
12263 if (! immediate_operand (operands[2], QImode))
12265 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12268 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12272 (define_insn "lshrti3_1"
12273 [(set (match_operand:TI 0 "register_operand" "=r")
12274 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12275 (match_operand:QI 2 "register_operand" "c")))
12276 (clobber (match_scratch:DI 3 "=&r"))
12277 (clobber (reg:CC FLAGS_REG))]
12280 [(set_attr "type" "multi")])
12282 (define_insn "*lshrti3_2"
12283 [(set (match_operand:TI 0 "register_operand" "=r")
12284 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12285 (match_operand:QI 2 "immediate_operand" "O")))
12286 (clobber (reg:CC FLAGS_REG))]
12289 [(set_attr "type" "multi")])
12292 [(set (match_operand:TI 0 "register_operand" "")
12293 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12294 (match_operand:QI 2 "register_operand" "")))
12295 (clobber (match_scratch:DI 3 ""))
12296 (clobber (reg:CC FLAGS_REG))]
12297 "TARGET_64BIT && reload_completed"
12299 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12302 [(set (match_operand:TI 0 "register_operand" "")
12303 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12304 (match_operand:QI 2 "immediate_operand" "")))
12305 (clobber (reg:CC FLAGS_REG))]
12306 "TARGET_64BIT && reload_completed"
12308 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12310 (define_expand "lshrdi3"
12311 [(set (match_operand:DI 0 "shiftdi_operand" "")
12312 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12313 (match_operand:QI 2 "nonmemory_operand" "")))]
12315 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12317 (define_insn "*lshrdi3_1_one_bit_rex64"
12318 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12319 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12320 (match_operand:QI 2 "const1_operand" "")))
12321 (clobber (reg:CC FLAGS_REG))]
12322 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12323 && (TARGET_SHIFT1 || optimize_size)"
12325 [(set_attr "type" "ishift")
12326 (set (attr "length")
12327 (if_then_else (match_operand:DI 0 "register_operand" "")
12329 (const_string "*")))])
12331 (define_insn "*lshrdi3_1_rex64"
12332 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12333 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12334 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12335 (clobber (reg:CC FLAGS_REG))]
12336 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12338 shr{q}\t{%2, %0|%0, %2}
12339 shr{q}\t{%b2, %0|%0, %b2}"
12340 [(set_attr "type" "ishift")
12341 (set_attr "mode" "DI")])
12343 ;; This pattern can't accept a variable shift count, since shifts by
12344 ;; zero don't affect the flags. We assume that shifts by constant
12345 ;; zero are optimized away.
12346 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12347 [(set (reg FLAGS_REG)
12349 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12350 (match_operand:QI 2 "const1_operand" ""))
12352 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12353 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12354 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12355 && (TARGET_SHIFT1 || optimize_size)
12356 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12358 [(set_attr "type" "ishift")
12359 (set (attr "length")
12360 (if_then_else (match_operand:DI 0 "register_operand" "")
12362 (const_string "*")))])
12364 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12365 [(set (reg FLAGS_REG)
12367 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const1_operand" ""))
12370 (clobber (match_scratch:DI 0 "=r"))]
12371 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12372 && (TARGET_SHIFT1 || optimize_size)
12373 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12375 [(set_attr "type" "ishift")
12376 (set_attr "length" "2")])
12378 ;; This pattern can't accept a variable shift count, since shifts by
12379 ;; zero don't affect the flags. We assume that shifts by constant
12380 ;; zero are optimized away.
12381 (define_insn "*lshrdi3_cmp_rex64"
12382 [(set (reg FLAGS_REG)
12384 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12385 (match_operand:QI 2 "const_int_operand" "e"))
12387 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12388 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12389 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12390 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12392 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12393 "shr{q}\t{%2, %0|%0, %2}"
12394 [(set_attr "type" "ishift")
12395 (set_attr "mode" "DI")])
12397 (define_insn "*lshrdi3_cconly_rex64"
12398 [(set (reg FLAGS_REG)
12400 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12401 (match_operand:QI 2 "const_int_operand" "e"))
12403 (clobber (match_scratch:DI 0 "=r"))]
12404 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12405 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12407 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12408 "shr{q}\t{%2, %0|%0, %2}"
12409 [(set_attr "type" "ishift")
12410 (set_attr "mode" "DI")])
12412 (define_insn "*lshrdi3_1"
12413 [(set (match_operand:DI 0 "register_operand" "=r")
12414 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12415 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12416 (clobber (reg:CC FLAGS_REG))]
12419 [(set_attr "type" "multi")])
12421 ;; By default we don't ask for a scratch register, because when DImode
12422 ;; values are manipulated, registers are already at a premium. But if
12423 ;; we have one handy, we won't turn it away.
12425 [(match_scratch:SI 3 "r")
12426 (parallel [(set (match_operand:DI 0 "register_operand" "")
12427 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12428 (match_operand:QI 2 "nonmemory_operand" "")))
12429 (clobber (reg:CC FLAGS_REG))])
12431 "!TARGET_64BIT && TARGET_CMOVE"
12433 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12436 [(set (match_operand:DI 0 "register_operand" "")
12437 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12438 (match_operand:QI 2 "nonmemory_operand" "")))
12439 (clobber (reg:CC FLAGS_REG))]
12440 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12441 ? flow2_completed : reload_completed)"
12443 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12445 (define_expand "lshrsi3"
12446 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12447 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12448 (match_operand:QI 2 "nonmemory_operand" "")))
12449 (clobber (reg:CC FLAGS_REG))]
12451 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12453 (define_insn "*lshrsi3_1_one_bit"
12454 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12455 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12456 (match_operand:QI 2 "const1_operand" "")))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12459 && (TARGET_SHIFT1 || optimize_size)"
12461 [(set_attr "type" "ishift")
12462 (set (attr "length")
12463 (if_then_else (match_operand:SI 0 "register_operand" "")
12465 (const_string "*")))])
12467 (define_insn "*lshrsi3_1_one_bit_zext"
12468 [(set (match_operand:DI 0 "register_operand" "=r")
12469 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12470 (match_operand:QI 2 "const1_operand" "")))
12471 (clobber (reg:CC FLAGS_REG))]
12472 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12473 && (TARGET_SHIFT1 || optimize_size)"
12475 [(set_attr "type" "ishift")
12476 (set_attr "length" "2")])
12478 (define_insn "*lshrsi3_1"
12479 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12480 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12481 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12482 (clobber (reg:CC FLAGS_REG))]
12483 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12485 shr{l}\t{%2, %0|%0, %2}
12486 shr{l}\t{%b2, %0|%0, %b2}"
12487 [(set_attr "type" "ishift")
12488 (set_attr "mode" "SI")])
12490 (define_insn "*lshrsi3_1_zext"
12491 [(set (match_operand:DI 0 "register_operand" "=r,r")
12493 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12494 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12495 (clobber (reg:CC FLAGS_REG))]
12496 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12498 shr{l}\t{%2, %k0|%k0, %2}
12499 shr{l}\t{%b2, %k0|%k0, %b2}"
12500 [(set_attr "type" "ishift")
12501 (set_attr "mode" "SI")])
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags. We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*lshrsi3_one_bit_cmp"
12507 [(set (reg FLAGS_REG)
12509 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510 (match_operand:QI 2 "const1_operand" ""))
12512 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12514 "ix86_match_ccmode (insn, CCGOCmode)
12515 && (TARGET_SHIFT1 || optimize_size)
12516 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12518 [(set_attr "type" "ishift")
12519 (set (attr "length")
12520 (if_then_else (match_operand:SI 0 "register_operand" "")
12522 (const_string "*")))])
12524 (define_insn "*lshrsi3_one_bit_cconly"
12525 [(set (reg FLAGS_REG)
12527 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12528 (match_operand:QI 2 "const1_operand" ""))
12530 (clobber (match_scratch:SI 0 "=r"))]
12531 "ix86_match_ccmode (insn, CCGOCmode)
12532 && (TARGET_SHIFT1 || optimize_size)
12533 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12535 [(set_attr "type" "ishift")
12536 (set_attr "length" "2")])
12538 (define_insn "*lshrsi3_cmp_one_bit_zext"
12539 [(set (reg FLAGS_REG)
12541 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12542 (match_operand:QI 2 "const1_operand" ""))
12544 (set (match_operand:DI 0 "register_operand" "=r")
12545 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12546 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12547 && (TARGET_SHIFT1 || optimize_size)
12548 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12550 [(set_attr "type" "ishift")
12551 (set_attr "length" "2")])
12553 ;; This pattern can't accept a variable shift count, since shifts by
12554 ;; zero don't affect the flags. We assume that shifts by constant
12555 ;; zero are optimized away.
12556 (define_insn "*lshrsi3_cmp"
12557 [(set (reg FLAGS_REG)
12559 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12560 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12562 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12563 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12564 "ix86_match_ccmode (insn, CCGOCmode)
12565 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12567 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12568 "shr{l}\t{%2, %0|%0, %2}"
12569 [(set_attr "type" "ishift")
12570 (set_attr "mode" "SI")])
12572 (define_insn "*lshrsi3_cconly"
12573 [(set (reg FLAGS_REG)
12575 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12576 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12578 (clobber (match_scratch:SI 0 "=r"))]
12579 "ix86_match_ccmode (insn, CCGOCmode)
12580 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12582 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12583 "shr{l}\t{%2, %0|%0, %2}"
12584 [(set_attr "type" "ishift")
12585 (set_attr "mode" "SI")])
12587 (define_insn "*lshrsi3_cmp_zext"
12588 [(set (reg FLAGS_REG)
12590 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12591 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12593 (set (match_operand:DI 0 "register_operand" "=r")
12594 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12595 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12596 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12598 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12599 "shr{l}\t{%2, %k0|%k0, %2}"
12600 [(set_attr "type" "ishift")
12601 (set_attr "mode" "SI")])
12603 (define_expand "lshrhi3"
12604 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12605 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12606 (match_operand:QI 2 "nonmemory_operand" "")))
12607 (clobber (reg:CC FLAGS_REG))]
12608 "TARGET_HIMODE_MATH"
12609 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12611 (define_insn "*lshrhi3_1_one_bit"
12612 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12613 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12614 (match_operand:QI 2 "const1_operand" "")))
12615 (clobber (reg:CC FLAGS_REG))]
12616 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12617 && (TARGET_SHIFT1 || optimize_size)"
12619 [(set_attr "type" "ishift")
12620 (set (attr "length")
12621 (if_then_else (match_operand 0 "register_operand" "")
12623 (const_string "*")))])
12625 (define_insn "*lshrhi3_1"
12626 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12627 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12628 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12629 (clobber (reg:CC FLAGS_REG))]
12630 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12632 shr{w}\t{%2, %0|%0, %2}
12633 shr{w}\t{%b2, %0|%0, %b2}"
12634 [(set_attr "type" "ishift")
12635 (set_attr "mode" "HI")])
12637 ;; This pattern can't accept a variable shift count, since shifts by
12638 ;; zero don't affect the flags. We assume that shifts by constant
12639 ;; zero are optimized away.
12640 (define_insn "*lshrhi3_one_bit_cmp"
12641 [(set (reg FLAGS_REG)
12643 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12644 (match_operand:QI 2 "const1_operand" ""))
12646 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12647 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12648 "ix86_match_ccmode (insn, CCGOCmode)
12649 && (TARGET_SHIFT1 || optimize_size)
12650 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12652 [(set_attr "type" "ishift")
12653 (set (attr "length")
12654 (if_then_else (match_operand:SI 0 "register_operand" "")
12656 (const_string "*")))])
12658 (define_insn "*lshrhi3_one_bit_cconly"
12659 [(set (reg FLAGS_REG)
12661 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12662 (match_operand:QI 2 "const1_operand" ""))
12664 (clobber (match_scratch:HI 0 "=r"))]
12665 "ix86_match_ccmode (insn, CCGOCmode)
12666 && (TARGET_SHIFT1 || optimize_size)
12667 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12669 [(set_attr "type" "ishift")
12670 (set_attr "length" "2")])
12672 ;; This pattern can't accept a variable shift count, since shifts by
12673 ;; zero don't affect the flags. We assume that shifts by constant
12674 ;; zero are optimized away.
12675 (define_insn "*lshrhi3_cmp"
12676 [(set (reg FLAGS_REG)
12678 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12679 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12681 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12682 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12683 "ix86_match_ccmode (insn, CCGOCmode)
12684 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12686 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12687 "shr{w}\t{%2, %0|%0, %2}"
12688 [(set_attr "type" "ishift")
12689 (set_attr "mode" "HI")])
12691 (define_insn "*lshrhi3_cconly"
12692 [(set (reg FLAGS_REG)
12694 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12695 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12697 (clobber (match_scratch:HI 0 "=r"))]
12698 "ix86_match_ccmode (insn, CCGOCmode)
12699 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12701 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12702 "shr{w}\t{%2, %0|%0, %2}"
12703 [(set_attr "type" "ishift")
12704 (set_attr "mode" "HI")])
12706 (define_expand "lshrqi3"
12707 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12708 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12709 (match_operand:QI 2 "nonmemory_operand" "")))
12710 (clobber (reg:CC FLAGS_REG))]
12711 "TARGET_QIMODE_MATH"
12712 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12714 (define_insn "*lshrqi3_1_one_bit"
12715 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12716 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12717 (match_operand:QI 2 "const1_operand" "")))
12718 (clobber (reg:CC FLAGS_REG))]
12719 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12720 && (TARGET_SHIFT1 || optimize_size)"
12722 [(set_attr "type" "ishift")
12723 (set (attr "length")
12724 (if_then_else (match_operand 0 "register_operand" "")
12726 (const_string "*")))])
12728 (define_insn "*lshrqi3_1_one_bit_slp"
12729 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12730 (lshiftrt:QI (match_dup 0)
12731 (match_operand:QI 1 "const1_operand" "")))
12732 (clobber (reg:CC FLAGS_REG))]
12733 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12734 && (TARGET_SHIFT1 || optimize_size)"
12736 [(set_attr "type" "ishift1")
12737 (set (attr "length")
12738 (if_then_else (match_operand 0 "register_operand" "")
12740 (const_string "*")))])
12742 (define_insn "*lshrqi3_1"
12743 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12744 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12745 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12746 (clobber (reg:CC FLAGS_REG))]
12747 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12749 shr{b}\t{%2, %0|%0, %2}
12750 shr{b}\t{%b2, %0|%0, %b2}"
12751 [(set_attr "type" "ishift")
12752 (set_attr "mode" "QI")])
12754 (define_insn "*lshrqi3_1_slp"
12755 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12756 (lshiftrt:QI (match_dup 0)
12757 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12758 (clobber (reg:CC FLAGS_REG))]
12759 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12760 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12762 shr{b}\t{%1, %0|%0, %1}
12763 shr{b}\t{%b1, %0|%0, %b1}"
12764 [(set_attr "type" "ishift1")
12765 (set_attr "mode" "QI")])
12767 ;; This pattern can't accept a variable shift count, since shifts by
12768 ;; zero don't affect the flags. We assume that shifts by constant
12769 ;; zero are optimized away.
12770 (define_insn "*lshrqi2_one_bit_cmp"
12771 [(set (reg FLAGS_REG)
12773 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12774 (match_operand:QI 2 "const1_operand" ""))
12776 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12777 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12778 "ix86_match_ccmode (insn, CCGOCmode)
12779 && (TARGET_SHIFT1 || optimize_size)
12780 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12782 [(set_attr "type" "ishift")
12783 (set (attr "length")
12784 (if_then_else (match_operand:SI 0 "register_operand" "")
12786 (const_string "*")))])
12788 (define_insn "*lshrqi2_one_bit_cconly"
12789 [(set (reg FLAGS_REG)
12791 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12792 (match_operand:QI 2 "const1_operand" ""))
12794 (clobber (match_scratch:QI 0 "=q"))]
12795 "ix86_match_ccmode (insn, CCGOCmode)
12796 && (TARGET_SHIFT1 || optimize_size)
12797 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12799 [(set_attr "type" "ishift")
12800 (set_attr "length" "2")])
12802 ;; This pattern can't accept a variable shift count, since shifts by
12803 ;; zero don't affect the flags. We assume that shifts by constant
12804 ;; zero are optimized away.
12805 (define_insn "*lshrqi2_cmp"
12806 [(set (reg FLAGS_REG)
12808 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12809 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12811 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12812 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12813 "ix86_match_ccmode (insn, CCGOCmode)
12814 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12816 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12817 "shr{b}\t{%2, %0|%0, %2}"
12818 [(set_attr "type" "ishift")
12819 (set_attr "mode" "QI")])
12821 (define_insn "*lshrqi2_cconly"
12822 [(set (reg FLAGS_REG)
12824 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12825 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12827 (clobber (match_scratch:QI 0 "=q"))]
12828 "ix86_match_ccmode (insn, CCGOCmode)
12829 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12831 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12832 "shr{b}\t{%2, %0|%0, %2}"
12833 [(set_attr "type" "ishift")
12834 (set_attr "mode" "QI")])
12836 ;; Rotate instructions
12838 (define_expand "rotldi3"
12839 [(set (match_operand:DI 0 "shiftdi_operand" "")
12840 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12841 (match_operand:QI 2 "nonmemory_operand" "")))
12842 (clobber (reg:CC FLAGS_REG))]
12847 ix86_expand_binary_operator (ROTATE, DImode, operands);
12850 if (!const_1_to_31_operand (operands[2], VOIDmode))
12852 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12856 ;; Implement rotation using two double-precision shift instructions
12857 ;; and a scratch register.
12858 (define_insn_and_split "ix86_rotldi3"
12859 [(set (match_operand:DI 0 "register_operand" "=r")
12860 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12861 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12862 (clobber (reg:CC FLAGS_REG))
12863 (clobber (match_scratch:SI 3 "=&r"))]
12866 "&& reload_completed"
12867 [(set (match_dup 3) (match_dup 4))
12869 [(set (match_dup 4)
12870 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12871 (lshiftrt:SI (match_dup 5)
12872 (minus:QI (const_int 32) (match_dup 2)))))
12873 (clobber (reg:CC FLAGS_REG))])
12875 [(set (match_dup 5)
12876 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12877 (lshiftrt:SI (match_dup 3)
12878 (minus:QI (const_int 32) (match_dup 2)))))
12879 (clobber (reg:CC FLAGS_REG))])]
12880 "split_di (operands, 1, operands + 4, operands + 5);")
12882 (define_insn "*rotlsi3_1_one_bit_rex64"
12883 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12884 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12885 (match_operand:QI 2 "const1_operand" "")))
12886 (clobber (reg:CC FLAGS_REG))]
12887 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12888 && (TARGET_SHIFT1 || optimize_size)"
12890 [(set_attr "type" "rotate")
12891 (set (attr "length")
12892 (if_then_else (match_operand:DI 0 "register_operand" "")
12894 (const_string "*")))])
12896 (define_insn "*rotldi3_1_rex64"
12897 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12898 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12899 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12900 (clobber (reg:CC FLAGS_REG))]
12901 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12903 rol{q}\t{%2, %0|%0, %2}
12904 rol{q}\t{%b2, %0|%0, %b2}"
12905 [(set_attr "type" "rotate")
12906 (set_attr "mode" "DI")])
12908 (define_expand "rotlsi3"
12909 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12910 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12911 (match_operand:QI 2 "nonmemory_operand" "")))
12912 (clobber (reg:CC FLAGS_REG))]
12914 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12916 (define_insn "*rotlsi3_1_one_bit"
12917 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12918 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12919 (match_operand:QI 2 "const1_operand" "")))
12920 (clobber (reg:CC FLAGS_REG))]
12921 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12922 && (TARGET_SHIFT1 || optimize_size)"
12924 [(set_attr "type" "rotate")
12925 (set (attr "length")
12926 (if_then_else (match_operand:SI 0 "register_operand" "")
12928 (const_string "*")))])
12930 (define_insn "*rotlsi3_1_one_bit_zext"
12931 [(set (match_operand:DI 0 "register_operand" "=r")
12933 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12934 (match_operand:QI 2 "const1_operand" ""))))
12935 (clobber (reg:CC FLAGS_REG))]
12936 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12937 && (TARGET_SHIFT1 || optimize_size)"
12939 [(set_attr "type" "rotate")
12940 (set_attr "length" "2")])
12942 (define_insn "*rotlsi3_1"
12943 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12944 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12945 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12946 (clobber (reg:CC FLAGS_REG))]
12947 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12949 rol{l}\t{%2, %0|%0, %2}
12950 rol{l}\t{%b2, %0|%0, %b2}"
12951 [(set_attr "type" "rotate")
12952 (set_attr "mode" "SI")])
12954 (define_insn "*rotlsi3_1_zext"
12955 [(set (match_operand:DI 0 "register_operand" "=r,r")
12957 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12958 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12962 rol{l}\t{%2, %k0|%k0, %2}
12963 rol{l}\t{%b2, %k0|%k0, %b2}"
12964 [(set_attr "type" "rotate")
12965 (set_attr "mode" "SI")])
12967 (define_expand "rotlhi3"
12968 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12969 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12970 (match_operand:QI 2 "nonmemory_operand" "")))
12971 (clobber (reg:CC FLAGS_REG))]
12972 "TARGET_HIMODE_MATH"
12973 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12975 (define_insn "*rotlhi3_1_one_bit"
12976 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12977 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12978 (match_operand:QI 2 "const1_operand" "")))
12979 (clobber (reg:CC FLAGS_REG))]
12980 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12981 && (TARGET_SHIFT1 || optimize_size)"
12983 [(set_attr "type" "rotate")
12984 (set (attr "length")
12985 (if_then_else (match_operand 0 "register_operand" "")
12987 (const_string "*")))])
12989 (define_insn "*rotlhi3_1"
12990 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12991 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12992 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12993 (clobber (reg:CC FLAGS_REG))]
12994 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12996 rol{w}\t{%2, %0|%0, %2}
12997 rol{w}\t{%b2, %0|%0, %b2}"
12998 [(set_attr "type" "rotate")
12999 (set_attr "mode" "HI")])
13001 (define_expand "rotlqi3"
13002 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13003 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13004 (match_operand:QI 2 "nonmemory_operand" "")))
13005 (clobber (reg:CC FLAGS_REG))]
13006 "TARGET_QIMODE_MATH"
13007 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13009 (define_insn "*rotlqi3_1_one_bit_slp"
13010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13011 (rotate:QI (match_dup 0)
13012 (match_operand:QI 1 "const1_operand" "")))
13013 (clobber (reg:CC FLAGS_REG))]
13014 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13015 && (TARGET_SHIFT1 || optimize_size)"
13017 [(set_attr "type" "rotate1")
13018 (set (attr "length")
13019 (if_then_else (match_operand 0 "register_operand" "")
13021 (const_string "*")))])
13023 (define_insn "*rotlqi3_1_one_bit"
13024 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13025 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13026 (match_operand:QI 2 "const1_operand" "")))
13027 (clobber (reg:CC FLAGS_REG))]
13028 "ix86_binary_operator_ok (ROTATE, QImode, operands)
13029 && (TARGET_SHIFT1 || optimize_size)"
13031 [(set_attr "type" "rotate")
13032 (set (attr "length")
13033 (if_then_else (match_operand 0 "register_operand" "")
13035 (const_string "*")))])
13037 (define_insn "*rotlqi3_1_slp"
13038 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13039 (rotate:QI (match_dup 0)
13040 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13041 (clobber (reg:CC FLAGS_REG))]
13042 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13043 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13045 rol{b}\t{%1, %0|%0, %1}
13046 rol{b}\t{%b1, %0|%0, %b1}"
13047 [(set_attr "type" "rotate1")
13048 (set_attr "mode" "QI")])
13050 (define_insn "*rotlqi3_1"
13051 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13052 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13053 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13054 (clobber (reg:CC FLAGS_REG))]
13055 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13057 rol{b}\t{%2, %0|%0, %2}
13058 rol{b}\t{%b2, %0|%0, %b2}"
13059 [(set_attr "type" "rotate")
13060 (set_attr "mode" "QI")])
13062 (define_expand "rotrdi3"
13063 [(set (match_operand:DI 0 "shiftdi_operand" "")
13064 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13065 (match_operand:QI 2 "nonmemory_operand" "")))
13066 (clobber (reg:CC FLAGS_REG))]
13071 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13074 if (!const_1_to_31_operand (operands[2], VOIDmode))
13076 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13080 ;; Implement rotation using two double-precision shift instructions
13081 ;; and a scratch register.
13082 (define_insn_and_split "ix86_rotrdi3"
13083 [(set (match_operand:DI 0 "register_operand" "=r")
13084 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13085 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13086 (clobber (reg:CC FLAGS_REG))
13087 (clobber (match_scratch:SI 3 "=&r"))]
13090 "&& reload_completed"
13091 [(set (match_dup 3) (match_dup 4))
13093 [(set (match_dup 4)
13094 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13095 (ashift:SI (match_dup 5)
13096 (minus:QI (const_int 32) (match_dup 2)))))
13097 (clobber (reg:CC FLAGS_REG))])
13099 [(set (match_dup 5)
13100 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13101 (ashift:SI (match_dup 3)
13102 (minus:QI (const_int 32) (match_dup 2)))))
13103 (clobber (reg:CC FLAGS_REG))])]
13104 "split_di (operands, 1, operands + 4, operands + 5);")
13106 (define_insn "*rotrdi3_1_one_bit_rex64"
13107 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13108 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13109 (match_operand:QI 2 "const1_operand" "")))
13110 (clobber (reg:CC FLAGS_REG))]
13111 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13112 && (TARGET_SHIFT1 || optimize_size)"
13114 [(set_attr "type" "rotate")
13115 (set (attr "length")
13116 (if_then_else (match_operand:DI 0 "register_operand" "")
13118 (const_string "*")))])
13120 (define_insn "*rotrdi3_1_rex64"
13121 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13122 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13123 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13124 (clobber (reg:CC FLAGS_REG))]
13125 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13127 ror{q}\t{%2, %0|%0, %2}
13128 ror{q}\t{%b2, %0|%0, %b2}"
13129 [(set_attr "type" "rotate")
13130 (set_attr "mode" "DI")])
13132 (define_expand "rotrsi3"
13133 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13134 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13135 (match_operand:QI 2 "nonmemory_operand" "")))
13136 (clobber (reg:CC FLAGS_REG))]
13138 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13140 (define_insn "*rotrsi3_1_one_bit"
13141 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13142 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13143 (match_operand:QI 2 "const1_operand" "")))
13144 (clobber (reg:CC FLAGS_REG))]
13145 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13146 && (TARGET_SHIFT1 || optimize_size)"
13148 [(set_attr "type" "rotate")
13149 (set (attr "length")
13150 (if_then_else (match_operand:SI 0 "register_operand" "")
13152 (const_string "*")))])
13154 (define_insn "*rotrsi3_1_one_bit_zext"
13155 [(set (match_operand:DI 0 "register_operand" "=r")
13157 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13158 (match_operand:QI 2 "const1_operand" ""))))
13159 (clobber (reg:CC FLAGS_REG))]
13160 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13161 && (TARGET_SHIFT1 || optimize_size)"
13163 [(set_attr "type" "rotate")
13164 (set (attr "length")
13165 (if_then_else (match_operand:SI 0 "register_operand" "")
13167 (const_string "*")))])
13169 (define_insn "*rotrsi3_1"
13170 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13171 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13172 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13173 (clobber (reg:CC FLAGS_REG))]
13174 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13176 ror{l}\t{%2, %0|%0, %2}
13177 ror{l}\t{%b2, %0|%0, %b2}"
13178 [(set_attr "type" "rotate")
13179 (set_attr "mode" "SI")])
13181 (define_insn "*rotrsi3_1_zext"
13182 [(set (match_operand:DI 0 "register_operand" "=r,r")
13184 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13185 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13186 (clobber (reg:CC FLAGS_REG))]
13187 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13189 ror{l}\t{%2, %k0|%k0, %2}
13190 ror{l}\t{%b2, %k0|%k0, %b2}"
13191 [(set_attr "type" "rotate")
13192 (set_attr "mode" "SI")])
13194 (define_expand "rotrhi3"
13195 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13196 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13197 (match_operand:QI 2 "nonmemory_operand" "")))
13198 (clobber (reg:CC FLAGS_REG))]
13199 "TARGET_HIMODE_MATH"
13200 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13202 (define_insn "*rotrhi3_one_bit"
13203 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13204 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13205 (match_operand:QI 2 "const1_operand" "")))
13206 (clobber (reg:CC FLAGS_REG))]
13207 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13208 && (TARGET_SHIFT1 || optimize_size)"
13210 [(set_attr "type" "rotate")
13211 (set (attr "length")
13212 (if_then_else (match_operand 0 "register_operand" "")
13214 (const_string "*")))])
13216 (define_insn "*rotrhi3"
13217 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13218 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13219 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13220 (clobber (reg:CC FLAGS_REG))]
13221 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13223 ror{w}\t{%2, %0|%0, %2}
13224 ror{w}\t{%b2, %0|%0, %b2}"
13225 [(set_attr "type" "rotate")
13226 (set_attr "mode" "HI")])
13228 (define_expand "rotrqi3"
13229 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13230 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13231 (match_operand:QI 2 "nonmemory_operand" "")))
13232 (clobber (reg:CC FLAGS_REG))]
13233 "TARGET_QIMODE_MATH"
13234 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13236 (define_insn "*rotrqi3_1_one_bit"
13237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13238 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13239 (match_operand:QI 2 "const1_operand" "")))
13240 (clobber (reg:CC FLAGS_REG))]
13241 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13242 && (TARGET_SHIFT1 || optimize_size)"
13244 [(set_attr "type" "rotate")
13245 (set (attr "length")
13246 (if_then_else (match_operand 0 "register_operand" "")
13248 (const_string "*")))])
13250 (define_insn "*rotrqi3_1_one_bit_slp"
13251 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13252 (rotatert:QI (match_dup 0)
13253 (match_operand:QI 1 "const1_operand" "")))
13254 (clobber (reg:CC FLAGS_REG))]
13255 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13256 && (TARGET_SHIFT1 || optimize_size)"
13258 [(set_attr "type" "rotate1")
13259 (set (attr "length")
13260 (if_then_else (match_operand 0 "register_operand" "")
13262 (const_string "*")))])
13264 (define_insn "*rotrqi3_1"
13265 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13266 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13267 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13268 (clobber (reg:CC FLAGS_REG))]
13269 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13271 ror{b}\t{%2, %0|%0, %2}
13272 ror{b}\t{%b2, %0|%0, %b2}"
13273 [(set_attr "type" "rotate")
13274 (set_attr "mode" "QI")])
13276 (define_insn "*rotrqi3_1_slp"
13277 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13278 (rotatert:QI (match_dup 0)
13279 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13280 (clobber (reg:CC FLAGS_REG))]
13281 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13282 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13284 ror{b}\t{%1, %0|%0, %1}
13285 ror{b}\t{%b1, %0|%0, %b1}"
13286 [(set_attr "type" "rotate1")
13287 (set_attr "mode" "QI")])
13289 ;; Bit set / bit test instructions
13291 (define_expand "extv"
13292 [(set (match_operand:SI 0 "register_operand" "")
13293 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13294 (match_operand:SI 2 "const8_operand" "")
13295 (match_operand:SI 3 "const8_operand" "")))]
13298 /* Handle extractions from %ah et al. */
13299 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13302 /* From mips.md: extract_bit_field doesn't verify that our source
13303 matches the predicate, so check it again here. */
13304 if (! ext_register_operand (operands[1], VOIDmode))
13308 (define_expand "extzv"
13309 [(set (match_operand:SI 0 "register_operand" "")
13310 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13311 (match_operand:SI 2 "const8_operand" "")
13312 (match_operand:SI 3 "const8_operand" "")))]
13315 /* Handle extractions from %ah et al. */
13316 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13319 /* From mips.md: extract_bit_field doesn't verify that our source
13320 matches the predicate, so check it again here. */
13321 if (! ext_register_operand (operands[1], VOIDmode))
13325 (define_expand "insv"
13326 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13327 (match_operand 1 "const8_operand" "")
13328 (match_operand 2 "const8_operand" ""))
13329 (match_operand 3 "register_operand" ""))]
13332 /* Handle insertions to %ah et al. */
13333 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13336 /* From mips.md: insert_bit_field doesn't verify that our source
13337 matches the predicate, so check it again here. */
13338 if (! ext_register_operand (operands[0], VOIDmode))
13342 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13344 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13349 ;; %%% bts, btr, btc, bt.
13350 ;; In general these instructions are *slow* when applied to memory,
13351 ;; since they enforce atomic operation. When applied to registers,
13352 ;; it depends on the cpu implementation. They're never faster than
13353 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13354 ;; no point. But in 64-bit, we can't hold the relevant immediates
13355 ;; within the instruction itself, so operating on bits in the high
13356 ;; 32-bits of a register becomes easier.
13358 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13359 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13360 ;; negdf respectively, so they can never be disabled entirely.
13362 (define_insn "*btsq"
13363 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13365 (match_operand:DI 1 "const_0_to_63_operand" ""))
13367 (clobber (reg:CC FLAGS_REG))]
13368 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13370 [(set_attr "type" "alu1")])
13372 (define_insn "*btrq"
13373 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13375 (match_operand:DI 1 "const_0_to_63_operand" ""))
13377 (clobber (reg:CC FLAGS_REG))]
13378 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13380 [(set_attr "type" "alu1")])
13382 (define_insn "*btcq"
13383 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13385 (match_operand:DI 1 "const_0_to_63_operand" ""))
13386 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13387 (clobber (reg:CC FLAGS_REG))]
13388 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13390 [(set_attr "type" "alu1")])
13392 ;; Allow Nocona to avoid these instructions if a register is available.
13395 [(match_scratch:DI 2 "r")
13396 (parallel [(set (zero_extract:DI
13397 (match_operand:DI 0 "register_operand" "")
13399 (match_operand:DI 1 "const_0_to_63_operand" ""))
13401 (clobber (reg:CC FLAGS_REG))])]
13402 "TARGET_64BIT && !TARGET_USE_BT"
13405 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13408 if (HOST_BITS_PER_WIDE_INT >= 64)
13409 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13410 else if (i < HOST_BITS_PER_WIDE_INT)
13411 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13413 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13415 op1 = immed_double_const (lo, hi, DImode);
13418 emit_move_insn (operands[2], op1);
13422 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13427 [(match_scratch:DI 2 "r")
13428 (parallel [(set (zero_extract:DI
13429 (match_operand:DI 0 "register_operand" "")
13431 (match_operand:DI 1 "const_0_to_63_operand" ""))
13433 (clobber (reg:CC FLAGS_REG))])]
13434 "TARGET_64BIT && !TARGET_USE_BT"
13437 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13440 if (HOST_BITS_PER_WIDE_INT >= 64)
13441 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13442 else if (i < HOST_BITS_PER_WIDE_INT)
13443 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13445 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13447 op1 = immed_double_const (~lo, ~hi, DImode);
13450 emit_move_insn (operands[2], op1);
13454 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13459 [(match_scratch:DI 2 "r")
13460 (parallel [(set (zero_extract:DI
13461 (match_operand:DI 0 "register_operand" "")
13463 (match_operand:DI 1 "const_0_to_63_operand" ""))
13464 (not:DI (zero_extract:DI
13465 (match_dup 0) (const_int 1) (match_dup 1))))
13466 (clobber (reg:CC FLAGS_REG))])]
13467 "TARGET_64BIT && !TARGET_USE_BT"
13470 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13473 if (HOST_BITS_PER_WIDE_INT >= 64)
13474 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13475 else if (i < HOST_BITS_PER_WIDE_INT)
13476 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13478 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13480 op1 = immed_double_const (lo, hi, DImode);
13483 emit_move_insn (operands[2], op1);
13487 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13491 ;; Store-flag instructions.
13493 ;; For all sCOND expanders, also expand the compare or test insn that
13494 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13496 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13497 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13498 ;; way, which can later delete the movzx if only QImode is needed.
13500 (define_expand "seq"
13501 [(set (match_operand:QI 0 "register_operand" "")
13502 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13504 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13506 (define_expand "sne"
13507 [(set (match_operand:QI 0 "register_operand" "")
13508 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13510 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13512 (define_expand "sgt"
13513 [(set (match_operand:QI 0 "register_operand" "")
13514 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13516 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13518 (define_expand "sgtu"
13519 [(set (match_operand:QI 0 "register_operand" "")
13520 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13522 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13524 (define_expand "slt"
13525 [(set (match_operand:QI 0 "register_operand" "")
13526 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13528 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13530 (define_expand "sltu"
13531 [(set (match_operand:QI 0 "register_operand" "")
13532 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13534 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13536 (define_expand "sge"
13537 [(set (match_operand:QI 0 "register_operand" "")
13538 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13540 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13542 (define_expand "sgeu"
13543 [(set (match_operand:QI 0 "register_operand" "")
13544 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13546 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13548 (define_expand "sle"
13549 [(set (match_operand:QI 0 "register_operand" "")
13550 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13552 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13554 (define_expand "sleu"
13555 [(set (match_operand:QI 0 "register_operand" "")
13556 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13558 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13560 (define_expand "sunordered"
13561 [(set (match_operand:QI 0 "register_operand" "")
13562 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13563 "TARGET_80387 || TARGET_SSE"
13564 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13566 (define_expand "sordered"
13567 [(set (match_operand:QI 0 "register_operand" "")
13568 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13570 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13572 (define_expand "suneq"
13573 [(set (match_operand:QI 0 "register_operand" "")
13574 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13575 "TARGET_80387 || TARGET_SSE"
13576 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13578 (define_expand "sunge"
13579 [(set (match_operand:QI 0 "register_operand" "")
13580 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13581 "TARGET_80387 || TARGET_SSE"
13582 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13584 (define_expand "sungt"
13585 [(set (match_operand:QI 0 "register_operand" "")
13586 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13587 "TARGET_80387 || TARGET_SSE"
13588 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13590 (define_expand "sunle"
13591 [(set (match_operand:QI 0 "register_operand" "")
13592 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13593 "TARGET_80387 || TARGET_SSE"
13594 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13596 (define_expand "sunlt"
13597 [(set (match_operand:QI 0 "register_operand" "")
13598 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13599 "TARGET_80387 || TARGET_SSE"
13600 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13602 (define_expand "sltgt"
13603 [(set (match_operand:QI 0 "register_operand" "")
13604 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13605 "TARGET_80387 || TARGET_SSE"
13606 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13608 (define_insn "*setcc_1"
13609 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13610 (match_operator:QI 1 "ix86_comparison_operator"
13611 [(reg FLAGS_REG) (const_int 0)]))]
13614 [(set_attr "type" "setcc")
13615 (set_attr "mode" "QI")])
13617 (define_insn "*setcc_2"
13618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13619 (match_operator:QI 1 "ix86_comparison_operator"
13620 [(reg FLAGS_REG) (const_int 0)]))]
13623 [(set_attr "type" "setcc")
13624 (set_attr "mode" "QI")])
13626 ;; In general it is not safe to assume too much about CCmode registers,
13627 ;; so simplify-rtx stops when it sees a second one. Under certain
13628 ;; conditions this is safe on x86, so help combine not create
13635 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13636 (ne:QI (match_operator 1 "ix86_comparison_operator"
13637 [(reg FLAGS_REG) (const_int 0)])
13640 [(set (match_dup 0) (match_dup 1))]
13642 PUT_MODE (operands[1], QImode);
13646 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13647 (ne:QI (match_operator 1 "ix86_comparison_operator"
13648 [(reg FLAGS_REG) (const_int 0)])
13651 [(set (match_dup 0) (match_dup 1))]
13653 PUT_MODE (operands[1], QImode);
13657 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13658 (eq:QI (match_operator 1 "ix86_comparison_operator"
13659 [(reg FLAGS_REG) (const_int 0)])
13662 [(set (match_dup 0) (match_dup 1))]
13664 rtx new_op1 = copy_rtx (operands[1]);
13665 operands[1] = new_op1;
13666 PUT_MODE (new_op1, QImode);
13667 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13668 GET_MODE (XEXP (new_op1, 0))));
13670 /* Make sure that (a) the CCmode we have for the flags is strong
13671 enough for the reversed compare or (b) we have a valid FP compare. */
13672 if (! ix86_comparison_operator (new_op1, VOIDmode))
13677 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13678 (eq:QI (match_operator 1 "ix86_comparison_operator"
13679 [(reg FLAGS_REG) (const_int 0)])
13682 [(set (match_dup 0) (match_dup 1))]
13684 rtx new_op1 = copy_rtx (operands[1]);
13685 operands[1] = new_op1;
13686 PUT_MODE (new_op1, QImode);
13687 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13688 GET_MODE (XEXP (new_op1, 0))));
13690 /* Make sure that (a) the CCmode we have for the flags is strong
13691 enough for the reversed compare or (b) we have a valid FP compare. */
13692 if (! ix86_comparison_operator (new_op1, VOIDmode))
13696 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13697 ;; subsequent logical operations are used to imitate conditional moves.
13698 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13701 (define_insn "*sse_setccsf"
13702 [(set (match_operand:SF 0 "register_operand" "=x")
13703 (match_operator:SF 1 "sse_comparison_operator"
13704 [(match_operand:SF 2 "register_operand" "0")
13705 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13707 "cmp%D1ss\t{%3, %0|%0, %3}"
13708 [(set_attr "type" "ssecmp")
13709 (set_attr "mode" "SF")])
13711 (define_insn "*sse_setccdf"
13712 [(set (match_operand:DF 0 "register_operand" "=x")
13713 (match_operator:DF 1 "sse_comparison_operator"
13714 [(match_operand:DF 2 "register_operand" "0")
13715 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13717 "cmp%D1sd\t{%3, %0|%0, %3}"
13718 [(set_attr "type" "ssecmp")
13719 (set_attr "mode" "DF")])
13721 ;; Basic conditional jump instructions.
13722 ;; We ignore the overflow flag for signed branch instructions.
13724 ;; For all bCOND expanders, also expand the compare or test insn that
13725 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13727 (define_expand "beq"
13729 (if_then_else (match_dup 1)
13730 (label_ref (match_operand 0 "" ""))
13733 "ix86_expand_branch (EQ, operands[0]); DONE;")
13735 (define_expand "bne"
13737 (if_then_else (match_dup 1)
13738 (label_ref (match_operand 0 "" ""))
13741 "ix86_expand_branch (NE, operands[0]); DONE;")
13743 (define_expand "bgt"
13745 (if_then_else (match_dup 1)
13746 (label_ref (match_operand 0 "" ""))
13749 "ix86_expand_branch (GT, operands[0]); DONE;")
13751 (define_expand "bgtu"
13753 (if_then_else (match_dup 1)
13754 (label_ref (match_operand 0 "" ""))
13757 "ix86_expand_branch (GTU, operands[0]); DONE;")
13759 (define_expand "blt"
13761 (if_then_else (match_dup 1)
13762 (label_ref (match_operand 0 "" ""))
13765 "ix86_expand_branch (LT, operands[0]); DONE;")
13767 (define_expand "bltu"
13769 (if_then_else (match_dup 1)
13770 (label_ref (match_operand 0 "" ""))
13773 "ix86_expand_branch (LTU, operands[0]); DONE;")
13775 (define_expand "bge"
13777 (if_then_else (match_dup 1)
13778 (label_ref (match_operand 0 "" ""))
13781 "ix86_expand_branch (GE, operands[0]); DONE;")
13783 (define_expand "bgeu"
13785 (if_then_else (match_dup 1)
13786 (label_ref (match_operand 0 "" ""))
13789 "ix86_expand_branch (GEU, operands[0]); DONE;")
13791 (define_expand "ble"
13793 (if_then_else (match_dup 1)
13794 (label_ref (match_operand 0 "" ""))
13797 "ix86_expand_branch (LE, operands[0]); DONE;")
13799 (define_expand "bleu"
13801 (if_then_else (match_dup 1)
13802 (label_ref (match_operand 0 "" ""))
13805 "ix86_expand_branch (LEU, operands[0]); DONE;")
13807 (define_expand "bunordered"
13809 (if_then_else (match_dup 1)
13810 (label_ref (match_operand 0 "" ""))
13812 "TARGET_80387 || TARGET_SSE_MATH"
13813 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13815 (define_expand "bordered"
13817 (if_then_else (match_dup 1)
13818 (label_ref (match_operand 0 "" ""))
13820 "TARGET_80387 || TARGET_SSE_MATH"
13821 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13823 (define_expand "buneq"
13825 (if_then_else (match_dup 1)
13826 (label_ref (match_operand 0 "" ""))
13828 "TARGET_80387 || TARGET_SSE_MATH"
13829 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13831 (define_expand "bunge"
13833 (if_then_else (match_dup 1)
13834 (label_ref (match_operand 0 "" ""))
13836 "TARGET_80387 || TARGET_SSE_MATH"
13837 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13839 (define_expand "bungt"
13841 (if_then_else (match_dup 1)
13842 (label_ref (match_operand 0 "" ""))
13844 "TARGET_80387 || TARGET_SSE_MATH"
13845 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13847 (define_expand "bunle"
13849 (if_then_else (match_dup 1)
13850 (label_ref (match_operand 0 "" ""))
13852 "TARGET_80387 || TARGET_SSE_MATH"
13853 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13855 (define_expand "bunlt"
13857 (if_then_else (match_dup 1)
13858 (label_ref (match_operand 0 "" ""))
13860 "TARGET_80387 || TARGET_SSE_MATH"
13861 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13863 (define_expand "bltgt"
13865 (if_then_else (match_dup 1)
13866 (label_ref (match_operand 0 "" ""))
13868 "TARGET_80387 || TARGET_SSE_MATH"
13869 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13871 (define_insn "*jcc_1"
13873 (if_then_else (match_operator 1 "ix86_comparison_operator"
13874 [(reg FLAGS_REG) (const_int 0)])
13875 (label_ref (match_operand 0 "" ""))
13879 [(set_attr "type" "ibr")
13880 (set_attr "modrm" "0")
13881 (set (attr "length")
13882 (if_then_else (and (ge (minus (match_dup 0) (pc))
13884 (lt (minus (match_dup 0) (pc))
13889 (define_insn "*jcc_2"
13891 (if_then_else (match_operator 1 "ix86_comparison_operator"
13892 [(reg FLAGS_REG) (const_int 0)])
13894 (label_ref (match_operand 0 "" ""))))]
13897 [(set_attr "type" "ibr")
13898 (set_attr "modrm" "0")
13899 (set (attr "length")
13900 (if_then_else (and (ge (minus (match_dup 0) (pc))
13902 (lt (minus (match_dup 0) (pc))
13907 ;; In general it is not safe to assume too much about CCmode registers,
13908 ;; so simplify-rtx stops when it sees a second one. Under certain
13909 ;; conditions this is safe on x86, so help combine not create
13917 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13918 [(reg FLAGS_REG) (const_int 0)])
13920 (label_ref (match_operand 1 "" ""))
13924 (if_then_else (match_dup 0)
13925 (label_ref (match_dup 1))
13928 PUT_MODE (operands[0], VOIDmode);
13933 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13934 [(reg FLAGS_REG) (const_int 0)])
13936 (label_ref (match_operand 1 "" ""))
13940 (if_then_else (match_dup 0)
13941 (label_ref (match_dup 1))
13944 rtx new_op0 = copy_rtx (operands[0]);
13945 operands[0] = new_op0;
13946 PUT_MODE (new_op0, VOIDmode);
13947 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13948 GET_MODE (XEXP (new_op0, 0))));
13950 /* Make sure that (a) the CCmode we have for the flags is strong
13951 enough for the reversed compare or (b) we have a valid FP compare. */
13952 if (! ix86_comparison_operator (new_op0, VOIDmode))
13956 ;; Define combination compare-and-branch fp compare instructions to use
13957 ;; during early optimization. Splitting the operation apart early makes
13958 ;; for bad code when we want to reverse the operation.
13960 (define_insn "*fp_jcc_1_mixed"
13962 (if_then_else (match_operator 0 "comparison_operator"
13963 [(match_operand 1 "register_operand" "f,x")
13964 (match_operand 2 "nonimmediate_operand" "f,xm")])
13965 (label_ref (match_operand 3 "" ""))
13967 (clobber (reg:CCFP FPSR_REG))
13968 (clobber (reg:CCFP FLAGS_REG))]
13969 "TARGET_MIX_SSE_I387
13970 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13971 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13972 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13975 (define_insn "*fp_jcc_1_sse"
13977 (if_then_else (match_operator 0 "comparison_operator"
13978 [(match_operand 1 "register_operand" "x")
13979 (match_operand 2 "nonimmediate_operand" "xm")])
13980 (label_ref (match_operand 3 "" ""))
13982 (clobber (reg:CCFP FPSR_REG))
13983 (clobber (reg:CCFP FLAGS_REG))]
13985 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13986 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13987 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13990 (define_insn "*fp_jcc_1_387"
13992 (if_then_else (match_operator 0 "comparison_operator"
13993 [(match_operand 1 "register_operand" "f")
13994 (match_operand 2 "register_operand" "f")])
13995 (label_ref (match_operand 3 "" ""))
13997 (clobber (reg:CCFP FPSR_REG))
13998 (clobber (reg:CCFP FLAGS_REG))]
13999 "TARGET_CMOVE && TARGET_80387
14000 && FLOAT_MODE_P (GET_MODE (operands[1]))
14001 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14002 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14005 (define_insn "*fp_jcc_2_mixed"
14007 (if_then_else (match_operator 0 "comparison_operator"
14008 [(match_operand 1 "register_operand" "f,x")
14009 (match_operand 2 "nonimmediate_operand" "f,xm")])
14011 (label_ref (match_operand 3 "" ""))))
14012 (clobber (reg:CCFP FPSR_REG))
14013 (clobber (reg:CCFP FLAGS_REG))]
14014 "TARGET_MIX_SSE_I387
14015 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14016 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14017 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14020 (define_insn "*fp_jcc_2_sse"
14022 (if_then_else (match_operator 0 "comparison_operator"
14023 [(match_operand 1 "register_operand" "x")
14024 (match_operand 2 "nonimmediate_operand" "xm")])
14026 (label_ref (match_operand 3 "" ""))))
14027 (clobber (reg:CCFP FPSR_REG))
14028 (clobber (reg:CCFP FLAGS_REG))]
14030 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14031 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14032 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14035 (define_insn "*fp_jcc_2_387"
14037 (if_then_else (match_operator 0 "comparison_operator"
14038 [(match_operand 1 "register_operand" "f")
14039 (match_operand 2 "register_operand" "f")])
14041 (label_ref (match_operand 3 "" ""))))
14042 (clobber (reg:CCFP FPSR_REG))
14043 (clobber (reg:CCFP FLAGS_REG))]
14044 "TARGET_CMOVE && TARGET_80387
14045 && FLOAT_MODE_P (GET_MODE (operands[1]))
14046 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14047 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14050 (define_insn "*fp_jcc_3_387"
14052 (if_then_else (match_operator 0 "comparison_operator"
14053 [(match_operand 1 "register_operand" "f")
14054 (match_operand 2 "nonimmediate_operand" "fm")])
14055 (label_ref (match_operand 3 "" ""))
14057 (clobber (reg:CCFP FPSR_REG))
14058 (clobber (reg:CCFP FLAGS_REG))
14059 (clobber (match_scratch:HI 4 "=a"))]
14061 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14062 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14063 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14064 && SELECT_CC_MODE (GET_CODE (operands[0]),
14065 operands[1], operands[2]) == CCFPmode
14066 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14069 (define_insn "*fp_jcc_4_387"
14071 (if_then_else (match_operator 0 "comparison_operator"
14072 [(match_operand 1 "register_operand" "f")
14073 (match_operand 2 "nonimmediate_operand" "fm")])
14075 (label_ref (match_operand 3 "" ""))))
14076 (clobber (reg:CCFP FPSR_REG))
14077 (clobber (reg:CCFP FLAGS_REG))
14078 (clobber (match_scratch:HI 4 "=a"))]
14080 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14081 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14082 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14083 && SELECT_CC_MODE (GET_CODE (operands[0]),
14084 operands[1], operands[2]) == CCFPmode
14085 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14088 (define_insn "*fp_jcc_5_387"
14090 (if_then_else (match_operator 0 "comparison_operator"
14091 [(match_operand 1 "register_operand" "f")
14092 (match_operand 2 "register_operand" "f")])
14093 (label_ref (match_operand 3 "" ""))
14095 (clobber (reg:CCFP FPSR_REG))
14096 (clobber (reg:CCFP FLAGS_REG))
14097 (clobber (match_scratch:HI 4 "=a"))]
14099 && FLOAT_MODE_P (GET_MODE (operands[1]))
14100 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14101 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14104 (define_insn "*fp_jcc_6_387"
14106 (if_then_else (match_operator 0 "comparison_operator"
14107 [(match_operand 1 "register_operand" "f")
14108 (match_operand 2 "register_operand" "f")])
14110 (label_ref (match_operand 3 "" ""))))
14111 (clobber (reg:CCFP FPSR_REG))
14112 (clobber (reg:CCFP FLAGS_REG))
14113 (clobber (match_scratch:HI 4 "=a"))]
14115 && FLOAT_MODE_P (GET_MODE (operands[1]))
14116 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14117 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14120 (define_insn "*fp_jcc_7_387"
14122 (if_then_else (match_operator 0 "comparison_operator"
14123 [(match_operand 1 "register_operand" "f")
14124 (match_operand 2 "const0_operand" "X")])
14125 (label_ref (match_operand 3 "" ""))
14127 (clobber (reg:CCFP FPSR_REG))
14128 (clobber (reg:CCFP FLAGS_REG))
14129 (clobber (match_scratch:HI 4 "=a"))]
14131 && FLOAT_MODE_P (GET_MODE (operands[1]))
14132 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14133 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14134 && SELECT_CC_MODE (GET_CODE (operands[0]),
14135 operands[1], operands[2]) == CCFPmode
14136 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14139 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14140 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14141 ;; with a precedence over other operators and is always put in the first
14142 ;; place. Swap condition and operands to match ficom instruction.
14144 (define_insn "*fp_jcc_8<mode>_387"
14146 (if_then_else (match_operator 0 "comparison_operator"
14147 [(match_operator 1 "float_operator"
14148 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14149 (match_operand 3 "register_operand" "f,f")])
14150 (label_ref (match_operand 4 "" ""))
14152 (clobber (reg:CCFP FPSR_REG))
14153 (clobber (reg:CCFP FLAGS_REG))
14154 (clobber (match_scratch:HI 5 "=a,a"))]
14155 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14156 && FLOAT_MODE_P (GET_MODE (operands[3]))
14157 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14158 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14159 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14160 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14165 (if_then_else (match_operator 0 "comparison_operator"
14166 [(match_operand 1 "register_operand" "")
14167 (match_operand 2 "nonimmediate_operand" "")])
14168 (match_operand 3 "" "")
14169 (match_operand 4 "" "")))
14170 (clobber (reg:CCFP FPSR_REG))
14171 (clobber (reg:CCFP FLAGS_REG))]
14175 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14176 operands[3], operands[4], NULL_RTX, NULL_RTX);
14182 (if_then_else (match_operator 0 "comparison_operator"
14183 [(match_operand 1 "register_operand" "")
14184 (match_operand 2 "general_operand" "")])
14185 (match_operand 3 "" "")
14186 (match_operand 4 "" "")))
14187 (clobber (reg:CCFP FPSR_REG))
14188 (clobber (reg:CCFP FLAGS_REG))
14189 (clobber (match_scratch:HI 5 "=a"))]
14193 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14194 operands[3], operands[4], operands[5], NULL_RTX);
14200 (if_then_else (match_operator 0 "comparison_operator"
14201 [(match_operator 1 "float_operator"
14202 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14203 (match_operand 3 "register_operand" "")])
14204 (match_operand 4 "" "")
14205 (match_operand 5 "" "")))
14206 (clobber (reg:CCFP FPSR_REG))
14207 (clobber (reg:CCFP FLAGS_REG))
14208 (clobber (match_scratch:HI 6 "=a"))]
14212 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14213 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14214 operands[3], operands[7],
14215 operands[4], operands[5], operands[6], NULL_RTX);
14219 ;; %%% Kill this when reload knows how to do it.
14222 (if_then_else (match_operator 0 "comparison_operator"
14223 [(match_operator 1 "float_operator"
14224 [(match_operand:X87MODEI12 2 "register_operand" "")])
14225 (match_operand 3 "register_operand" "")])
14226 (match_operand 4 "" "")
14227 (match_operand 5 "" "")))
14228 (clobber (reg:CCFP FPSR_REG))
14229 (clobber (reg:CCFP FLAGS_REG))
14230 (clobber (match_scratch:HI 6 "=a"))]
14234 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14235 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14236 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14237 operands[3], operands[7],
14238 operands[4], operands[5], operands[6], operands[2]);
14242 ;; Unconditional and other jump instructions
14244 (define_insn "jump"
14246 (label_ref (match_operand 0 "" "")))]
14249 [(set_attr "type" "ibr")
14250 (set (attr "length")
14251 (if_then_else (and (ge (minus (match_dup 0) (pc))
14253 (lt (minus (match_dup 0) (pc))
14257 (set_attr "modrm" "0")])
14259 (define_expand "indirect_jump"
14260 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14264 (define_insn "*indirect_jump"
14265 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14268 [(set_attr "type" "ibr")
14269 (set_attr "length_immediate" "0")])
14271 (define_insn "*indirect_jump_rtx64"
14272 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14275 [(set_attr "type" "ibr")
14276 (set_attr "length_immediate" "0")])
14278 (define_expand "tablejump"
14279 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14280 (use (label_ref (match_operand 1 "" "")))])]
14283 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14284 relative. Convert the relative address to an absolute address. */
14288 enum rtx_code code;
14294 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14296 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14300 op1 = pic_offset_table_rtx;
14305 op0 = pic_offset_table_rtx;
14309 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14314 (define_insn "*tablejump_1"
14315 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14316 (use (label_ref (match_operand 1 "" "")))]
14319 [(set_attr "type" "ibr")
14320 (set_attr "length_immediate" "0")])
14322 (define_insn "*tablejump_1_rtx64"
14323 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14324 (use (label_ref (match_operand 1 "" "")))]
14327 [(set_attr "type" "ibr")
14328 (set_attr "length_immediate" "0")])
14330 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14333 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14334 (set (match_operand:QI 1 "register_operand" "")
14335 (match_operator:QI 2 "ix86_comparison_operator"
14336 [(reg FLAGS_REG) (const_int 0)]))
14337 (set (match_operand 3 "q_regs_operand" "")
14338 (zero_extend (match_dup 1)))]
14339 "(peep2_reg_dead_p (3, operands[1])
14340 || operands_match_p (operands[1], operands[3]))
14341 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14342 [(set (match_dup 4) (match_dup 0))
14343 (set (strict_low_part (match_dup 5))
14346 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14347 operands[5] = gen_lowpart (QImode, operands[3]);
14348 ix86_expand_clear (operands[3]);
14351 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14354 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14355 (set (match_operand:QI 1 "register_operand" "")
14356 (match_operator:QI 2 "ix86_comparison_operator"
14357 [(reg FLAGS_REG) (const_int 0)]))
14358 (parallel [(set (match_operand 3 "q_regs_operand" "")
14359 (zero_extend (match_dup 1)))
14360 (clobber (reg:CC FLAGS_REG))])]
14361 "(peep2_reg_dead_p (3, operands[1])
14362 || operands_match_p (operands[1], operands[3]))
14363 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14364 [(set (match_dup 4) (match_dup 0))
14365 (set (strict_low_part (match_dup 5))
14368 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14369 operands[5] = gen_lowpart (QImode, operands[3]);
14370 ix86_expand_clear (operands[3]);
14373 ;; Call instructions.
14375 ;; The predicates normally associated with named expanders are not properly
14376 ;; checked for calls. This is a bug in the generic code, but it isn't that
14377 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14379 ;; Call subroutine returning no value.
14381 (define_expand "call_pop"
14382 [(parallel [(call (match_operand:QI 0 "" "")
14383 (match_operand:SI 1 "" ""))
14384 (set (reg:SI SP_REG)
14385 (plus:SI (reg:SI SP_REG)
14386 (match_operand:SI 3 "" "")))])]
14389 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14393 (define_insn "*call_pop_0"
14394 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14395 (match_operand:SI 1 "" ""))
14396 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14397 (match_operand:SI 2 "immediate_operand" "")))]
14400 if (SIBLING_CALL_P (insn))
14403 return "call\t%P0";
14405 [(set_attr "type" "call")])
14407 (define_insn "*call_pop_1"
14408 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14409 (match_operand:SI 1 "" ""))
14410 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14411 (match_operand:SI 2 "immediate_operand" "i")))]
14414 if (constant_call_address_operand (operands[0], Pmode))
14416 if (SIBLING_CALL_P (insn))
14419 return "call\t%P0";
14421 if (SIBLING_CALL_P (insn))
14424 return "call\t%A0";
14426 [(set_attr "type" "call")])
14428 (define_expand "call"
14429 [(call (match_operand:QI 0 "" "")
14430 (match_operand 1 "" ""))
14431 (use (match_operand 2 "" ""))]
14434 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14438 (define_expand "sibcall"
14439 [(call (match_operand:QI 0 "" "")
14440 (match_operand 1 "" ""))
14441 (use (match_operand 2 "" ""))]
14444 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14448 (define_insn "*call_0"
14449 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14450 (match_operand 1 "" ""))]
14453 if (SIBLING_CALL_P (insn))
14456 return "call\t%P0";
14458 [(set_attr "type" "call")])
14460 (define_insn "*call_1"
14461 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14462 (match_operand 1 "" ""))]
14463 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14465 if (constant_call_address_operand (operands[0], Pmode))
14466 return "call\t%P0";
14467 return "call\t%A0";
14469 [(set_attr "type" "call")])
14471 (define_insn "*sibcall_1"
14472 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14473 (match_operand 1 "" ""))]
14474 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14476 if (constant_call_address_operand (operands[0], Pmode))
14480 [(set_attr "type" "call")])
14482 (define_insn "*call_1_rex64"
14483 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14484 (match_operand 1 "" ""))]
14485 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14487 if (constant_call_address_operand (operands[0], Pmode))
14488 return "call\t%P0";
14489 return "call\t%A0";
14491 [(set_attr "type" "call")])
14493 (define_insn "*sibcall_1_rex64"
14494 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14495 (match_operand 1 "" ""))]
14496 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14498 [(set_attr "type" "call")])
14500 (define_insn "*sibcall_1_rex64_v"
14501 [(call (mem:QI (reg:DI R11_REG))
14502 (match_operand 0 "" ""))]
14503 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14505 [(set_attr "type" "call")])
14508 ;; Call subroutine, returning value in operand 0
14510 (define_expand "call_value_pop"
14511 [(parallel [(set (match_operand 0 "" "")
14512 (call (match_operand:QI 1 "" "")
14513 (match_operand:SI 2 "" "")))
14514 (set (reg:SI SP_REG)
14515 (plus:SI (reg:SI SP_REG)
14516 (match_operand:SI 4 "" "")))])]
14519 ix86_expand_call (operands[0], operands[1], operands[2],
14520 operands[3], operands[4], 0);
14524 (define_expand "call_value"
14525 [(set (match_operand 0 "" "")
14526 (call (match_operand:QI 1 "" "")
14527 (match_operand:SI 2 "" "")))
14528 (use (match_operand:SI 3 "" ""))]
14529 ;; Operand 2 not used on the i386.
14532 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14536 (define_expand "sibcall_value"
14537 [(set (match_operand 0 "" "")
14538 (call (match_operand:QI 1 "" "")
14539 (match_operand:SI 2 "" "")))
14540 (use (match_operand:SI 3 "" ""))]
14541 ;; Operand 2 not used on the i386.
14544 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14548 ;; Call subroutine returning any type.
14550 (define_expand "untyped_call"
14551 [(parallel [(call (match_operand 0 "" "")
14553 (match_operand 1 "" "")
14554 (match_operand 2 "" "")])]
14559 /* In order to give reg-stack an easier job in validating two
14560 coprocessor registers as containing a possible return value,
14561 simply pretend the untyped call returns a complex long double
14564 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14565 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14566 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14569 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14571 rtx set = XVECEXP (operands[2], 0, i);
14572 emit_move_insn (SET_DEST (set), SET_SRC (set));
14575 /* The optimizer does not know that the call sets the function value
14576 registers we stored in the result block. We avoid problems by
14577 claiming that all hard registers are used and clobbered at this
14579 emit_insn (gen_blockage (const0_rtx));
14584 ;; Prologue and epilogue instructions
14586 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14587 ;; all of memory. This blocks insns from being moved across this point.
14589 (define_insn "blockage"
14590 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14593 [(set_attr "length" "0")])
14595 ;; Insn emitted into the body of a function to return from a function.
14596 ;; This is only done if the function's epilogue is known to be simple.
14597 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14599 (define_expand "return"
14601 "ix86_can_use_return_insn_p ()"
14603 if (current_function_pops_args)
14605 rtx popc = GEN_INT (current_function_pops_args);
14606 emit_jump_insn (gen_return_pop_internal (popc));
14611 (define_insn "return_internal"
14615 [(set_attr "length" "1")
14616 (set_attr "length_immediate" "0")
14617 (set_attr "modrm" "0")])
14619 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14620 ;; instruction Athlon and K8 have.
14622 (define_insn "return_internal_long"
14624 (unspec [(const_int 0)] UNSPEC_REP)]
14627 [(set_attr "length" "1")
14628 (set_attr "length_immediate" "0")
14629 (set_attr "prefix_rep" "1")
14630 (set_attr "modrm" "0")])
14632 (define_insn "return_pop_internal"
14634 (use (match_operand:SI 0 "const_int_operand" ""))]
14637 [(set_attr "length" "3")
14638 (set_attr "length_immediate" "2")
14639 (set_attr "modrm" "0")])
14641 (define_insn "return_indirect_internal"
14643 (use (match_operand:SI 0 "register_operand" "r"))]
14646 [(set_attr "type" "ibr")
14647 (set_attr "length_immediate" "0")])
14653 [(set_attr "length" "1")
14654 (set_attr "length_immediate" "0")
14655 (set_attr "modrm" "0")])
14657 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14658 ;; branch prediction penalty for the third jump in a 16-byte
14661 (define_insn "align"
14662 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14665 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14666 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14668 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14669 The align insn is used to avoid 3 jump instructions in the row to improve
14670 branch prediction and the benefits hardly outweigh the cost of extra 8
14671 nops on the average inserted by full alignment pseudo operation. */
14675 [(set_attr "length" "16")])
14677 (define_expand "prologue"
14680 "ix86_expand_prologue (); DONE;")
14682 (define_insn "set_got"
14683 [(set (match_operand:SI 0 "register_operand" "=r")
14684 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14685 (clobber (reg:CC FLAGS_REG))]
14687 { return output_set_got (operands[0], NULL_RTX); }
14688 [(set_attr "type" "multi")
14689 (set_attr "length" "12")])
14691 (define_insn "set_got_labelled"
14692 [(set (match_operand:SI 0 "register_operand" "=r")
14693 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14695 (clobber (reg:CC FLAGS_REG))]
14697 { return output_set_got (operands[0], operands[1]); }
14698 [(set_attr "type" "multi")
14699 (set_attr "length" "12")])
14701 (define_insn "set_got_rex64"
14702 [(set (match_operand:DI 0 "register_operand" "=r")
14703 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14705 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14706 [(set_attr "type" "lea")
14707 (set_attr "length" "6")])
14709 (define_expand "epilogue"
14712 "ix86_expand_epilogue (1); DONE;")
14714 (define_expand "sibcall_epilogue"
14717 "ix86_expand_epilogue (0); DONE;")
14719 (define_expand "eh_return"
14720 [(use (match_operand 0 "register_operand" ""))]
14723 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14725 /* Tricky bit: we write the address of the handler to which we will
14726 be returning into someone else's stack frame, one word below the
14727 stack address we wish to restore. */
14728 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14729 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14730 tmp = gen_rtx_MEM (Pmode, tmp);
14731 emit_move_insn (tmp, ra);
14733 if (Pmode == SImode)
14734 emit_jump_insn (gen_eh_return_si (sa));
14736 emit_jump_insn (gen_eh_return_di (sa));
14741 (define_insn_and_split "eh_return_si"
14743 (unspec [(match_operand:SI 0 "register_operand" "c")]
14744 UNSPEC_EH_RETURN))]
14749 "ix86_expand_epilogue (2); DONE;")
14751 (define_insn_and_split "eh_return_di"
14753 (unspec [(match_operand:DI 0 "register_operand" "c")]
14754 UNSPEC_EH_RETURN))]
14759 "ix86_expand_epilogue (2); DONE;")
14761 (define_insn "leave"
14762 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14763 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14764 (clobber (mem:BLK (scratch)))]
14767 [(set_attr "type" "leave")])
14769 (define_insn "leave_rex64"
14770 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14771 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14772 (clobber (mem:BLK (scratch)))]
14775 [(set_attr "type" "leave")])
14777 (define_expand "ffssi2"
14779 [(set (match_operand:SI 0 "register_operand" "")
14780 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14781 (clobber (match_scratch:SI 2 ""))
14782 (clobber (reg:CC FLAGS_REG))])]
14786 (define_insn_and_split "*ffs_cmove"
14787 [(set (match_operand:SI 0 "register_operand" "=r")
14788 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14789 (clobber (match_scratch:SI 2 "=&r"))
14790 (clobber (reg:CC FLAGS_REG))]
14793 "&& reload_completed"
14794 [(set (match_dup 2) (const_int -1))
14795 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14796 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14797 (set (match_dup 0) (if_then_else:SI
14798 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14801 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14802 (clobber (reg:CC FLAGS_REG))])]
14805 (define_insn_and_split "*ffs_no_cmove"
14806 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14807 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14808 (clobber (match_scratch:SI 2 "=&q"))
14809 (clobber (reg:CC FLAGS_REG))]
14813 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14814 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14815 (set (strict_low_part (match_dup 3))
14816 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14817 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14818 (clobber (reg:CC FLAGS_REG))])
14819 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14820 (clobber (reg:CC FLAGS_REG))])
14821 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14822 (clobber (reg:CC FLAGS_REG))])]
14824 operands[3] = gen_lowpart (QImode, operands[2]);
14825 ix86_expand_clear (operands[2]);
14828 (define_insn "*ffssi_1"
14829 [(set (reg:CCZ FLAGS_REG)
14830 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14832 (set (match_operand:SI 0 "register_operand" "=r")
14833 (ctz:SI (match_dup 1)))]
14835 "bsf{l}\t{%1, %0|%0, %1}"
14836 [(set_attr "prefix_0f" "1")])
14838 (define_expand "ffsdi2"
14840 [(set (match_operand:DI 0 "register_operand" "")
14841 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14842 (clobber (match_scratch:DI 2 ""))
14843 (clobber (reg:CC FLAGS_REG))])]
14844 "TARGET_64BIT && TARGET_CMOVE"
14847 (define_insn_and_split "*ffs_rex64"
14848 [(set (match_operand:DI 0 "register_operand" "=r")
14849 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14850 (clobber (match_scratch:DI 2 "=&r"))
14851 (clobber (reg:CC FLAGS_REG))]
14852 "TARGET_64BIT && TARGET_CMOVE"
14854 "&& reload_completed"
14855 [(set (match_dup 2) (const_int -1))
14856 (parallel [(set (reg:CCZ FLAGS_REG)
14857 (compare:CCZ (match_dup 1) (const_int 0)))
14858 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14859 (set (match_dup 0) (if_then_else:DI
14860 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14863 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14864 (clobber (reg:CC FLAGS_REG))])]
14867 (define_insn "*ffsdi_1"
14868 [(set (reg:CCZ FLAGS_REG)
14869 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14871 (set (match_operand:DI 0 "register_operand" "=r")
14872 (ctz:DI (match_dup 1)))]
14874 "bsf{q}\t{%1, %0|%0, %1}"
14875 [(set_attr "prefix_0f" "1")])
14877 (define_insn "ctzsi2"
14878 [(set (match_operand:SI 0 "register_operand" "=r")
14879 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14880 (clobber (reg:CC FLAGS_REG))]
14882 "bsf{l}\t{%1, %0|%0, %1}"
14883 [(set_attr "prefix_0f" "1")])
14885 (define_insn "ctzdi2"
14886 [(set (match_operand:DI 0 "register_operand" "=r")
14887 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14888 (clobber (reg:CC FLAGS_REG))]
14890 "bsf{q}\t{%1, %0|%0, %1}"
14891 [(set_attr "prefix_0f" "1")])
14893 (define_expand "clzsi2"
14895 [(set (match_operand:SI 0 "register_operand" "")
14896 (minus:SI (const_int 31)
14897 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14898 (clobber (reg:CC FLAGS_REG))])
14900 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14901 (clobber (reg:CC FLAGS_REG))])]
14906 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14911 (define_insn "clzsi2_abm"
14912 [(set (match_operand:SI 0 "register_operand" "=r")
14913 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14914 (clobber (reg:CC FLAGS_REG))]
14916 "lzcnt{l}\t{%1, %0|%0, %1}"
14917 [(set_attr "prefix_rep" "1")
14918 (set_attr "type" "bitmanip")
14919 (set_attr "mode" "SI")])
14921 (define_insn "*bsr"
14922 [(set (match_operand:SI 0 "register_operand" "=r")
14923 (minus:SI (const_int 31)
14924 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14925 (clobber (reg:CC FLAGS_REG))]
14927 "bsr{l}\t{%1, %0|%0, %1}"
14928 [(set_attr "prefix_0f" "1")
14929 (set_attr "mode" "SI")])
14931 (define_insn "popcountsi2"
14932 [(set (match_operand:SI 0 "register_operand" "=r")
14933 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14934 (clobber (reg:CC FLAGS_REG))]
14936 "popcnt{l}\t{%1, %0|%0, %1}"
14937 [(set_attr "prefix_rep" "1")
14938 (set_attr "type" "bitmanip")
14939 (set_attr "mode" "SI")])
14941 (define_insn "*popcountsi2_cmp"
14942 [(set (reg FLAGS_REG)
14944 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14946 (set (match_operand:SI 0 "register_operand" "=r")
14947 (popcount:SI (match_dup 1)))]
14948 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14949 "popcnt{l}\t{%1, %0|%0, %1}"
14950 [(set_attr "prefix_rep" "1")
14951 (set_attr "type" "bitmanip")
14952 (set_attr "mode" "SI")])
14954 (define_insn "*popcountsi2_cmp_zext"
14955 [(set (reg FLAGS_REG)
14957 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14959 (set (match_operand:DI 0 "register_operand" "=r")
14960 (zero_extend:DI(popcount:SI (match_dup 1))))]
14961 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14962 "popcnt{l}\t{%1, %0|%0, %1}"
14963 [(set_attr "prefix_rep" "1")
14964 (set_attr "type" "bitmanip")
14965 (set_attr "mode" "SI")])
14967 (define_insn "bswapsi2"
14968 [(set (match_operand:SI 0 "register_operand" "=r")
14969 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14970 (clobber (reg:CC FLAGS_REG))]
14973 [(set_attr "prefix_0f" "1")
14974 (set_attr "length" "2")])
14976 (define_insn "*bswapdi2_rex"
14977 [(set (match_operand:DI 0 "register_operand" "=r")
14978 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14979 (clobber (reg:CC FLAGS_REG))]
14980 "TARGET_64BIT && TARGET_BSWAP"
14982 [(set_attr "prefix_0f" "1")
14983 (set_attr "length" "3")])
14985 (define_expand "bswapdi2"
14986 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14987 (bswap:DI (match_operand:DI 1 "register_operand" "")))
14988 (clobber (reg:CC FLAGS_REG))])]
14994 tmp1 = gen_reg_rtx (SImode);
14995 tmp2 = gen_reg_rtx (SImode);
14996 emit_insn (gen_bswapsi2 (tmp1, gen_lowpart (SImode, operands[1])));
14997 emit_insn (gen_bswapsi2 (tmp2, gen_highpart (SImode, operands[1])));
14998 emit_move_insn (gen_lowpart (SImode, operands[0]), tmp2);
14999 emit_move_insn (gen_highpart (SImode, operands[0]), tmp1);
15004 (define_expand "clzdi2"
15006 [(set (match_operand:DI 0 "register_operand" "")
15007 (minus:DI (const_int 63)
15008 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15009 (clobber (reg:CC FLAGS_REG))])
15011 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15012 (clobber (reg:CC FLAGS_REG))])]
15017 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15022 (define_insn "clzdi2_abm"
15023 [(set (match_operand:DI 0 "register_operand" "=r")
15024 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15025 (clobber (reg:CC FLAGS_REG))]
15026 "TARGET_64BIT && TARGET_ABM"
15027 "lzcnt{q}\t{%1, %0|%0, %1}"
15028 [(set_attr "prefix_rep" "1")
15029 (set_attr "type" "bitmanip")
15030 (set_attr "mode" "DI")])
15032 (define_insn "*bsr_rex64"
15033 [(set (match_operand:DI 0 "register_operand" "=r")
15034 (minus:DI (const_int 63)
15035 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15036 (clobber (reg:CC FLAGS_REG))]
15038 "bsr{q}\t{%1, %0|%0, %1}"
15039 [(set_attr "prefix_0f" "1")
15040 (set_attr "mode" "DI")])
15042 (define_insn "popcountdi2"
15043 [(set (match_operand:DI 0 "register_operand" "=r")
15044 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15045 (clobber (reg:CC FLAGS_REG))]
15046 "TARGET_64BIT && TARGET_POPCNT"
15047 "popcnt{q}\t{%1, %0|%0, %1}"
15048 [(set_attr "prefix_rep" "1")
15049 (set_attr "type" "bitmanip")
15050 (set_attr "mode" "DI")])
15052 (define_insn "*popcountdi2_cmp"
15053 [(set (reg FLAGS_REG)
15055 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15057 (set (match_operand:DI 0 "register_operand" "=r")
15058 (popcount:DI (match_dup 1)))]
15059 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15060 "popcnt{q}\t{%1, %0|%0, %1}"
15061 [(set_attr "prefix_rep" "1")
15062 (set_attr "type" "bitmanip")
15063 (set_attr "mode" "DI")])
15065 (define_expand "clzhi2"
15067 [(set (match_operand:HI 0 "register_operand" "")
15068 (minus:HI (const_int 15)
15069 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15070 (clobber (reg:CC FLAGS_REG))])
15072 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15073 (clobber (reg:CC FLAGS_REG))])]
15078 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15083 (define_insn "clzhi2_abm"
15084 [(set (match_operand:HI 0 "register_operand" "=r")
15085 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15086 (clobber (reg:CC FLAGS_REG))]
15088 "lzcnt{w}\t{%1, %0|%0, %1}"
15089 [(set_attr "prefix_rep" "1")
15090 (set_attr "type" "bitmanip")
15091 (set_attr "mode" "HI")])
15093 (define_insn "*bsrhi"
15094 [(set (match_operand:HI 0 "register_operand" "=r")
15095 (minus:HI (const_int 15)
15096 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15097 (clobber (reg:CC FLAGS_REG))]
15099 "bsr{w}\t{%1, %0|%0, %1}"
15100 [(set_attr "prefix_0f" "1")
15101 (set_attr "mode" "HI")])
15103 (define_insn "popcounthi2"
15104 [(set (match_operand:HI 0 "register_operand" "=r")
15105 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15106 (clobber (reg:CC FLAGS_REG))]
15108 "popcnt{w}\t{%1, %0|%0, %1}"
15109 [(set_attr "prefix_rep" "1")
15110 (set_attr "type" "bitmanip")
15111 (set_attr "mode" "HI")])
15113 (define_insn "*popcounthi2_cmp"
15114 [(set (reg FLAGS_REG)
15116 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15118 (set (match_operand:HI 0 "register_operand" "=r")
15119 (popcount:HI (match_dup 1)))]
15120 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15121 "popcnt{w}\t{%1, %0|%0, %1}"
15122 [(set_attr "prefix_rep" "1")
15123 (set_attr "type" "bitmanip")
15124 (set_attr "mode" "HI")])
15126 (define_expand "paritydi2"
15127 [(set (match_operand:DI 0 "register_operand" "")
15128 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15131 rtx scratch = gen_reg_rtx (QImode);
15134 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15135 NULL_RTX, operands[1]));
15137 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15138 gen_rtx_REG (CCmode, FLAGS_REG),
15140 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15143 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15146 rtx tmp = gen_reg_rtx (SImode);
15148 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15149 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15154 (define_insn_and_split "paritydi2_cmp"
15155 [(set (reg:CC FLAGS_REG)
15156 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15157 (clobber (match_scratch:DI 0 "=r,X"))
15158 (clobber (match_scratch:SI 1 "=r,r"))
15159 (clobber (match_scratch:HI 2 "=Q,Q"))]
15162 "&& reload_completed"
15164 [(set (match_dup 1)
15165 (xor:SI (match_dup 1) (match_dup 4)))
15166 (clobber (reg:CC FLAGS_REG))])
15168 [(set (reg:CC FLAGS_REG)
15169 (parity:CC (match_dup 1)))
15170 (clobber (match_dup 1))
15171 (clobber (match_dup 2))])]
15173 operands[4] = gen_lowpart (SImode, operands[3]);
15175 if (MEM_P (operands[3]))
15176 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15177 else if (! TARGET_64BIT)
15178 operands[1] = gen_highpart (SImode, operands[3]);
15181 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15182 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15186 (define_expand "paritysi2"
15187 [(set (match_operand:SI 0 "register_operand" "")
15188 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15191 rtx scratch = gen_reg_rtx (QImode);
15194 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15196 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15197 gen_rtx_REG (CCmode, FLAGS_REG),
15199 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15201 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15205 (define_insn_and_split "paritysi2_cmp"
15206 [(set (reg:CC FLAGS_REG)
15207 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15208 (clobber (match_scratch:SI 0 "=r,X"))
15209 (clobber (match_scratch:HI 1 "=Q,Q"))]
15212 "&& reload_completed"
15214 [(set (match_dup 1)
15215 (xor:HI (match_dup 1) (match_dup 3)))
15216 (clobber (reg:CC FLAGS_REG))])
15218 [(set (reg:CC FLAGS_REG)
15219 (parity:CC (match_dup 1)))
15220 (clobber (match_dup 1))])]
15222 operands[3] = gen_lowpart (HImode, operands[2]);
15224 if (MEM_P (operands[2]))
15225 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15228 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15229 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15233 (define_insn "*parityhi2_cmp"
15234 [(set (reg:CC FLAGS_REG)
15235 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15236 (clobber (match_scratch:HI 0 "=Q"))]
15238 "xor{b}\t{%h0, %b0|%b0, %h0}"
15239 [(set_attr "length" "2")
15240 (set_attr "mode" "HI")])
15242 (define_insn "*parityqi2_cmp"
15243 [(set (reg:CC FLAGS_REG)
15244 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15247 [(set_attr "length" "2")
15248 (set_attr "mode" "QI")])
15250 ;; Thread-local storage patterns for ELF.
15252 ;; Note that these code sequences must appear exactly as shown
15253 ;; in order to allow linker relaxation.
15255 (define_insn "*tls_global_dynamic_32_gnu"
15256 [(set (match_operand:SI 0 "register_operand" "=a")
15257 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15258 (match_operand:SI 2 "tls_symbolic_operand" "")
15259 (match_operand:SI 3 "call_insn_operand" "")]
15261 (clobber (match_scratch:SI 4 "=d"))
15262 (clobber (match_scratch:SI 5 "=c"))
15263 (clobber (reg:CC FLAGS_REG))]
15264 "!TARGET_64BIT && TARGET_GNU_TLS"
15265 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15266 [(set_attr "type" "multi")
15267 (set_attr "length" "12")])
15269 (define_insn "*tls_global_dynamic_32_sun"
15270 [(set (match_operand:SI 0 "register_operand" "=a")
15271 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15272 (match_operand:SI 2 "tls_symbolic_operand" "")
15273 (match_operand:SI 3 "call_insn_operand" "")]
15275 (clobber (match_scratch:SI 4 "=d"))
15276 (clobber (match_scratch:SI 5 "=c"))
15277 (clobber (reg:CC FLAGS_REG))]
15278 "!TARGET_64BIT && TARGET_SUN_TLS"
15279 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15280 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15281 [(set_attr "type" "multi")
15282 (set_attr "length" "14")])
15284 (define_expand "tls_global_dynamic_32"
15285 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15288 (match_operand:SI 1 "tls_symbolic_operand" "")
15291 (clobber (match_scratch:SI 4 ""))
15292 (clobber (match_scratch:SI 5 ""))
15293 (clobber (reg:CC FLAGS_REG))])]
15297 operands[2] = pic_offset_table_rtx;
15300 operands[2] = gen_reg_rtx (Pmode);
15301 emit_insn (gen_set_got (operands[2]));
15303 if (TARGET_GNU2_TLS)
15305 emit_insn (gen_tls_dynamic_gnu2_32
15306 (operands[0], operands[1], operands[2]));
15309 operands[3] = ix86_tls_get_addr ();
15312 (define_insn "*tls_global_dynamic_64"
15313 [(set (match_operand:DI 0 "register_operand" "=a")
15314 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15315 (match_operand:DI 3 "" "")))
15316 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15319 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15320 [(set_attr "type" "multi")
15321 (set_attr "length" "16")])
15323 (define_expand "tls_global_dynamic_64"
15324 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15325 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15326 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15330 if (TARGET_GNU2_TLS)
15332 emit_insn (gen_tls_dynamic_gnu2_64
15333 (operands[0], operands[1]));
15336 operands[2] = ix86_tls_get_addr ();
15339 (define_insn "*tls_local_dynamic_base_32_gnu"
15340 [(set (match_operand:SI 0 "register_operand" "=a")
15341 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15342 (match_operand:SI 2 "call_insn_operand" "")]
15343 UNSPEC_TLS_LD_BASE))
15344 (clobber (match_scratch:SI 3 "=d"))
15345 (clobber (match_scratch:SI 4 "=c"))
15346 (clobber (reg:CC FLAGS_REG))]
15347 "!TARGET_64BIT && TARGET_GNU_TLS"
15348 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15349 [(set_attr "type" "multi")
15350 (set_attr "length" "11")])
15352 (define_insn "*tls_local_dynamic_base_32_sun"
15353 [(set (match_operand:SI 0 "register_operand" "=a")
15354 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15355 (match_operand:SI 2 "call_insn_operand" "")]
15356 UNSPEC_TLS_LD_BASE))
15357 (clobber (match_scratch:SI 3 "=d"))
15358 (clobber (match_scratch:SI 4 "=c"))
15359 (clobber (reg:CC FLAGS_REG))]
15360 "!TARGET_64BIT && TARGET_SUN_TLS"
15361 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15362 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15363 [(set_attr "type" "multi")
15364 (set_attr "length" "13")])
15366 (define_expand "tls_local_dynamic_base_32"
15367 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15368 (unspec:SI [(match_dup 1) (match_dup 2)]
15369 UNSPEC_TLS_LD_BASE))
15370 (clobber (match_scratch:SI 3 ""))
15371 (clobber (match_scratch:SI 4 ""))
15372 (clobber (reg:CC FLAGS_REG))])]
15376 operands[1] = pic_offset_table_rtx;
15379 operands[1] = gen_reg_rtx (Pmode);
15380 emit_insn (gen_set_got (operands[1]));
15382 if (TARGET_GNU2_TLS)
15384 emit_insn (gen_tls_dynamic_gnu2_32
15385 (operands[0], ix86_tls_module_base (), operands[1]));
15388 operands[2] = ix86_tls_get_addr ();
15391 (define_insn "*tls_local_dynamic_base_64"
15392 [(set (match_operand:DI 0 "register_operand" "=a")
15393 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15394 (match_operand:DI 2 "" "")))
15395 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15397 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15398 [(set_attr "type" "multi")
15399 (set_attr "length" "12")])
15401 (define_expand "tls_local_dynamic_base_64"
15402 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15403 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15404 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15407 if (TARGET_GNU2_TLS)
15409 emit_insn (gen_tls_dynamic_gnu2_64
15410 (operands[0], ix86_tls_module_base ()));
15413 operands[1] = ix86_tls_get_addr ();
15416 ;; Local dynamic of a single variable is a lose. Show combine how
15417 ;; to convert that back to global dynamic.
15419 (define_insn_and_split "*tls_local_dynamic_32_once"
15420 [(set (match_operand:SI 0 "register_operand" "=a")
15421 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15422 (match_operand:SI 2 "call_insn_operand" "")]
15423 UNSPEC_TLS_LD_BASE)
15424 (const:SI (unspec:SI
15425 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15427 (clobber (match_scratch:SI 4 "=d"))
15428 (clobber (match_scratch:SI 5 "=c"))
15429 (clobber (reg:CC FLAGS_REG))]
15433 [(parallel [(set (match_dup 0)
15434 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15436 (clobber (match_dup 4))
15437 (clobber (match_dup 5))
15438 (clobber (reg:CC FLAGS_REG))])]
15441 ;; Load and add the thread base pointer from %gs:0.
15443 (define_insn "*load_tp_si"
15444 [(set (match_operand:SI 0 "register_operand" "=r")
15445 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15447 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15448 [(set_attr "type" "imov")
15449 (set_attr "modrm" "0")
15450 (set_attr "length" "7")
15451 (set_attr "memory" "load")
15452 (set_attr "imm_disp" "false")])
15454 (define_insn "*add_tp_si"
15455 [(set (match_operand:SI 0 "register_operand" "=r")
15456 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15457 (match_operand:SI 1 "register_operand" "0")))
15458 (clobber (reg:CC FLAGS_REG))]
15460 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15461 [(set_attr "type" "alu")
15462 (set_attr "modrm" "0")
15463 (set_attr "length" "7")
15464 (set_attr "memory" "load")
15465 (set_attr "imm_disp" "false")])
15467 (define_insn "*load_tp_di"
15468 [(set (match_operand:DI 0 "register_operand" "=r")
15469 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15471 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15472 [(set_attr "type" "imov")
15473 (set_attr "modrm" "0")
15474 (set_attr "length" "7")
15475 (set_attr "memory" "load")
15476 (set_attr "imm_disp" "false")])
15478 (define_insn "*add_tp_di"
15479 [(set (match_operand:DI 0 "register_operand" "=r")
15480 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15481 (match_operand:DI 1 "register_operand" "0")))
15482 (clobber (reg:CC FLAGS_REG))]
15484 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15485 [(set_attr "type" "alu")
15486 (set_attr "modrm" "0")
15487 (set_attr "length" "7")
15488 (set_attr "memory" "load")
15489 (set_attr "imm_disp" "false")])
15491 ;; GNU2 TLS patterns can be split.
15493 (define_expand "tls_dynamic_gnu2_32"
15494 [(set (match_dup 3)
15495 (plus:SI (match_operand:SI 2 "register_operand" "")
15497 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15500 [(set (match_operand:SI 0 "register_operand" "")
15501 (unspec:SI [(match_dup 1) (match_dup 3)
15502 (match_dup 2) (reg:SI SP_REG)]
15504 (clobber (reg:CC FLAGS_REG))])]
15505 "!TARGET_64BIT && TARGET_GNU2_TLS"
15507 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15508 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15511 (define_insn "*tls_dynamic_lea_32"
15512 [(set (match_operand:SI 0 "register_operand" "=r")
15513 (plus:SI (match_operand:SI 1 "register_operand" "b")
15515 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15516 UNSPEC_TLSDESC))))]
15517 "!TARGET_64BIT && TARGET_GNU2_TLS"
15518 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15519 [(set_attr "type" "lea")
15520 (set_attr "mode" "SI")
15521 (set_attr "length" "6")
15522 (set_attr "length_address" "4")])
15524 (define_insn "*tls_dynamic_call_32"
15525 [(set (match_operand:SI 0 "register_operand" "=a")
15526 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15527 (match_operand:SI 2 "register_operand" "0")
15528 ;; we have to make sure %ebx still points to the GOT
15529 (match_operand:SI 3 "register_operand" "b")
15532 (clobber (reg:CC FLAGS_REG))]
15533 "!TARGET_64BIT && TARGET_GNU2_TLS"
15534 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15535 [(set_attr "type" "call")
15536 (set_attr "length" "2")
15537 (set_attr "length_address" "0")])
15539 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15540 [(set (match_operand:SI 0 "register_operand" "=&a")
15542 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15543 (match_operand:SI 4 "" "")
15544 (match_operand:SI 2 "register_operand" "b")
15547 (const:SI (unspec:SI
15548 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15550 (clobber (reg:CC FLAGS_REG))]
15551 "!TARGET_64BIT && TARGET_GNU2_TLS"
15554 [(set (match_dup 0) (match_dup 5))]
15556 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15557 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15560 (define_expand "tls_dynamic_gnu2_64"
15561 [(set (match_dup 2)
15562 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15565 [(set (match_operand:DI 0 "register_operand" "")
15566 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15568 (clobber (reg:CC FLAGS_REG))])]
15569 "TARGET_64BIT && TARGET_GNU2_TLS"
15571 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15572 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15575 (define_insn "*tls_dynamic_lea_64"
15576 [(set (match_operand:DI 0 "register_operand" "=r")
15577 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15579 "TARGET_64BIT && TARGET_GNU2_TLS"
15580 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15581 [(set_attr "type" "lea")
15582 (set_attr "mode" "DI")
15583 (set_attr "length" "7")
15584 (set_attr "length_address" "4")])
15586 (define_insn "*tls_dynamic_call_64"
15587 [(set (match_operand:DI 0 "register_operand" "=a")
15588 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15589 (match_operand:DI 2 "register_operand" "0")
15592 (clobber (reg:CC FLAGS_REG))]
15593 "TARGET_64BIT && TARGET_GNU2_TLS"
15594 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15595 [(set_attr "type" "call")
15596 (set_attr "length" "2")
15597 (set_attr "length_address" "0")])
15599 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15600 [(set (match_operand:DI 0 "register_operand" "=&a")
15602 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15603 (match_operand:DI 3 "" "")
15606 (const:DI (unspec:DI
15607 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15609 (clobber (reg:CC FLAGS_REG))]
15610 "TARGET_64BIT && TARGET_GNU2_TLS"
15613 [(set (match_dup 0) (match_dup 4))]
15615 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15616 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15621 ;; These patterns match the binary 387 instructions for addM3, subM3,
15622 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15623 ;; SFmode. The first is the normal insn, the second the same insn but
15624 ;; with one operand a conversion, and the third the same insn but with
15625 ;; the other operand a conversion. The conversion may be SFmode or
15626 ;; SImode if the target mode DFmode, but only SImode if the target mode
15629 ;; Gcc is slightly more smart about handling normal two address instructions
15630 ;; so use special patterns for add and mull.
15632 (define_insn "*fop_sf_comm_mixed"
15633 [(set (match_operand:SF 0 "register_operand" "=f,x")
15634 (match_operator:SF 3 "binary_fp_operator"
15635 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15636 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15637 "TARGET_MIX_SSE_I387
15638 && COMMUTATIVE_ARITH_P (operands[3])
15639 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15640 "* return output_387_binary_op (insn, operands);"
15641 [(set (attr "type")
15642 (if_then_else (eq_attr "alternative" "1")
15643 (if_then_else (match_operand:SF 3 "mult_operator" "")
15644 (const_string "ssemul")
15645 (const_string "sseadd"))
15646 (if_then_else (match_operand:SF 3 "mult_operator" "")
15647 (const_string "fmul")
15648 (const_string "fop"))))
15649 (set_attr "mode" "SF")])
15651 (define_insn "*fop_sf_comm_sse"
15652 [(set (match_operand:SF 0 "register_operand" "=x")
15653 (match_operator:SF 3 "binary_fp_operator"
15654 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15655 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15657 && COMMUTATIVE_ARITH_P (operands[3])
15658 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15659 "* return output_387_binary_op (insn, operands);"
15660 [(set (attr "type")
15661 (if_then_else (match_operand:SF 3 "mult_operator" "")
15662 (const_string "ssemul")
15663 (const_string "sseadd")))
15664 (set_attr "mode" "SF")])
15666 (define_insn "*fop_sf_comm_i387"
15667 [(set (match_operand:SF 0 "register_operand" "=f")
15668 (match_operator:SF 3 "binary_fp_operator"
15669 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15670 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15672 && COMMUTATIVE_ARITH_P (operands[3])
15673 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15674 "* return output_387_binary_op (insn, operands);"
15675 [(set (attr "type")
15676 (if_then_else (match_operand:SF 3 "mult_operator" "")
15677 (const_string "fmul")
15678 (const_string "fop")))
15679 (set_attr "mode" "SF")])
15681 (define_insn "*fop_sf_1_mixed"
15682 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15683 (match_operator:SF 3 "binary_fp_operator"
15684 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15685 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15686 "TARGET_MIX_SSE_I387
15687 && !COMMUTATIVE_ARITH_P (operands[3])
15688 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15689 "* return output_387_binary_op (insn, operands);"
15690 [(set (attr "type")
15691 (cond [(and (eq_attr "alternative" "2")
15692 (match_operand:SF 3 "mult_operator" ""))
15693 (const_string "ssemul")
15694 (and (eq_attr "alternative" "2")
15695 (match_operand:SF 3 "div_operator" ""))
15696 (const_string "ssediv")
15697 (eq_attr "alternative" "2")
15698 (const_string "sseadd")
15699 (match_operand:SF 3 "mult_operator" "")
15700 (const_string "fmul")
15701 (match_operand:SF 3 "div_operator" "")
15702 (const_string "fdiv")
15704 (const_string "fop")))
15705 (set_attr "mode" "SF")])
15707 (define_insn "*fop_sf_1_sse"
15708 [(set (match_operand:SF 0 "register_operand" "=x")
15709 (match_operator:SF 3 "binary_fp_operator"
15710 [(match_operand:SF 1 "register_operand" "0")
15711 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15713 && !COMMUTATIVE_ARITH_P (operands[3])"
15714 "* return output_387_binary_op (insn, operands);"
15715 [(set (attr "type")
15716 (cond [(match_operand:SF 3 "mult_operator" "")
15717 (const_string "ssemul")
15718 (match_operand:SF 3 "div_operator" "")
15719 (const_string "ssediv")
15721 (const_string "sseadd")))
15722 (set_attr "mode" "SF")])
15724 ;; This pattern is not fully shadowed by the pattern above.
15725 (define_insn "*fop_sf_1_i387"
15726 [(set (match_operand:SF 0 "register_operand" "=f,f")
15727 (match_operator:SF 3 "binary_fp_operator"
15728 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15729 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15730 "TARGET_80387 && !TARGET_SSE_MATH
15731 && !COMMUTATIVE_ARITH_P (operands[3])
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:SF 3 "mult_operator" "")
15736 (const_string "fmul")
15737 (match_operand:SF 3 "div_operator" "")
15738 (const_string "fdiv")
15740 (const_string "fop")))
15741 (set_attr "mode" "SF")])
15743 ;; ??? Add SSE splitters for these!
15744 (define_insn "*fop_sf_2<mode>_i387"
15745 [(set (match_operand:SF 0 "register_operand" "=f,f")
15746 (match_operator:SF 3 "binary_fp_operator"
15747 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15748 (match_operand:SF 2 "register_operand" "0,0")]))]
15749 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15750 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15751 [(set (attr "type")
15752 (cond [(match_operand:SF 3 "mult_operator" "")
15753 (const_string "fmul")
15754 (match_operand:SF 3 "div_operator" "")
15755 (const_string "fdiv")
15757 (const_string "fop")))
15758 (set_attr "fp_int_src" "true")
15759 (set_attr "mode" "<MODE>")])
15761 (define_insn "*fop_sf_3<mode>_i387"
15762 [(set (match_operand:SF 0 "register_operand" "=f,f")
15763 (match_operator:SF 3 "binary_fp_operator"
15764 [(match_operand:SF 1 "register_operand" "0,0")
15765 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15766 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15767 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15768 [(set (attr "type")
15769 (cond [(match_operand:SF 3 "mult_operator" "")
15770 (const_string "fmul")
15771 (match_operand:SF 3 "div_operator" "")
15772 (const_string "fdiv")
15774 (const_string "fop")))
15775 (set_attr "fp_int_src" "true")
15776 (set_attr "mode" "<MODE>")])
15778 (define_insn "*fop_df_comm_mixed"
15779 [(set (match_operand:DF 0 "register_operand" "=f,x")
15780 (match_operator:DF 3 "binary_fp_operator"
15781 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15782 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15783 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15784 && COMMUTATIVE_ARITH_P (operands[3])
15785 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15786 "* return output_387_binary_op (insn, operands);"
15787 [(set (attr "type")
15788 (if_then_else (eq_attr "alternative" "1")
15789 (if_then_else (match_operand:DF 3 "mult_operator" "")
15790 (const_string "ssemul")
15791 (const_string "sseadd"))
15792 (if_then_else (match_operand:DF 3 "mult_operator" "")
15793 (const_string "fmul")
15794 (const_string "fop"))))
15795 (set_attr "mode" "DF")])
15797 (define_insn "*fop_df_comm_sse"
15798 [(set (match_operand:DF 0 "register_operand" "=x")
15799 (match_operator:DF 3 "binary_fp_operator"
15800 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15801 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15802 "TARGET_SSE2 && TARGET_SSE_MATH
15803 && COMMUTATIVE_ARITH_P (operands[3])
15804 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15805 "* return output_387_binary_op (insn, operands);"
15806 [(set (attr "type")
15807 (if_then_else (match_operand:DF 3 "mult_operator" "")
15808 (const_string "ssemul")
15809 (const_string "sseadd")))
15810 (set_attr "mode" "DF")])
15812 (define_insn "*fop_df_comm_i387"
15813 [(set (match_operand:DF 0 "register_operand" "=f")
15814 (match_operator:DF 3 "binary_fp_operator"
15815 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15816 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15818 && COMMUTATIVE_ARITH_P (operands[3])
15819 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15820 "* return output_387_binary_op (insn, operands);"
15821 [(set (attr "type")
15822 (if_then_else (match_operand:DF 3 "mult_operator" "")
15823 (const_string "fmul")
15824 (const_string "fop")))
15825 (set_attr "mode" "DF")])
15827 (define_insn "*fop_df_1_mixed"
15828 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15829 (match_operator:DF 3 "binary_fp_operator"
15830 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15831 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15832 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15833 && !COMMUTATIVE_ARITH_P (operands[3])
15834 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15835 "* return output_387_binary_op (insn, operands);"
15836 [(set (attr "type")
15837 (cond [(and (eq_attr "alternative" "2")
15838 (match_operand:DF 3 "mult_operator" ""))
15839 (const_string "ssemul")
15840 (and (eq_attr "alternative" "2")
15841 (match_operand:DF 3 "div_operator" ""))
15842 (const_string "ssediv")
15843 (eq_attr "alternative" "2")
15844 (const_string "sseadd")
15845 (match_operand:DF 3 "mult_operator" "")
15846 (const_string "fmul")
15847 (match_operand:DF 3 "div_operator" "")
15848 (const_string "fdiv")
15850 (const_string "fop")))
15851 (set_attr "mode" "DF")])
15853 (define_insn "*fop_df_1_sse"
15854 [(set (match_operand:DF 0 "register_operand" "=x")
15855 (match_operator:DF 3 "binary_fp_operator"
15856 [(match_operand:DF 1 "register_operand" "0")
15857 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15858 "TARGET_SSE2 && TARGET_SSE_MATH
15859 && !COMMUTATIVE_ARITH_P (operands[3])"
15860 "* return output_387_binary_op (insn, operands);"
15861 [(set_attr "mode" "DF")
15863 (cond [(match_operand:DF 3 "mult_operator" "")
15864 (const_string "ssemul")
15865 (match_operand:DF 3 "div_operator" "")
15866 (const_string "ssediv")
15868 (const_string "sseadd")))])
15870 ;; This pattern is not fully shadowed by the pattern above.
15871 (define_insn "*fop_df_1_i387"
15872 [(set (match_operand:DF 0 "register_operand" "=f,f")
15873 (match_operator:DF 3 "binary_fp_operator"
15874 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15875 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15876 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15877 && !COMMUTATIVE_ARITH_P (operands[3])
15878 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15879 "* return output_387_binary_op (insn, operands);"
15880 [(set (attr "type")
15881 (cond [(match_operand:DF 3 "mult_operator" "")
15882 (const_string "fmul")
15883 (match_operand:DF 3 "div_operator" "")
15884 (const_string "fdiv")
15886 (const_string "fop")))
15887 (set_attr "mode" "DF")])
15889 ;; ??? Add SSE splitters for these!
15890 (define_insn "*fop_df_2<mode>_i387"
15891 [(set (match_operand:DF 0 "register_operand" "=f,f")
15892 (match_operator:DF 3 "binary_fp_operator"
15893 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15894 (match_operand:DF 2 "register_operand" "0,0")]))]
15895 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15896 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15897 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15898 [(set (attr "type")
15899 (cond [(match_operand:DF 3 "mult_operator" "")
15900 (const_string "fmul")
15901 (match_operand:DF 3 "div_operator" "")
15902 (const_string "fdiv")
15904 (const_string "fop")))
15905 (set_attr "fp_int_src" "true")
15906 (set_attr "mode" "<MODE>")])
15908 (define_insn "*fop_df_3<mode>_i387"
15909 [(set (match_operand:DF 0 "register_operand" "=f,f")
15910 (match_operator:DF 3 "binary_fp_operator"
15911 [(match_operand:DF 1 "register_operand" "0,0")
15912 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15913 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15914 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15915 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15916 [(set (attr "type")
15917 (cond [(match_operand:DF 3 "mult_operator" "")
15918 (const_string "fmul")
15919 (match_operand:DF 3 "div_operator" "")
15920 (const_string "fdiv")
15922 (const_string "fop")))
15923 (set_attr "fp_int_src" "true")
15924 (set_attr "mode" "<MODE>")])
15926 (define_insn "*fop_df_4_i387"
15927 [(set (match_operand:DF 0 "register_operand" "=f,f")
15928 (match_operator:DF 3 "binary_fp_operator"
15929 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15930 (match_operand:DF 2 "register_operand" "0,f")]))]
15931 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15932 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15933 "* return output_387_binary_op (insn, operands);"
15934 [(set (attr "type")
15935 (cond [(match_operand:DF 3 "mult_operator" "")
15936 (const_string "fmul")
15937 (match_operand:DF 3 "div_operator" "")
15938 (const_string "fdiv")
15940 (const_string "fop")))
15941 (set_attr "mode" "SF")])
15943 (define_insn "*fop_df_5_i387"
15944 [(set (match_operand:DF 0 "register_operand" "=f,f")
15945 (match_operator:DF 3 "binary_fp_operator"
15946 [(match_operand:DF 1 "register_operand" "0,f")
15948 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15949 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15950 "* return output_387_binary_op (insn, operands);"
15951 [(set (attr "type")
15952 (cond [(match_operand:DF 3 "mult_operator" "")
15953 (const_string "fmul")
15954 (match_operand:DF 3 "div_operator" "")
15955 (const_string "fdiv")
15957 (const_string "fop")))
15958 (set_attr "mode" "SF")])
15960 (define_insn "*fop_df_6_i387"
15961 [(set (match_operand:DF 0 "register_operand" "=f,f")
15962 (match_operator:DF 3 "binary_fp_operator"
15964 (match_operand:SF 1 "register_operand" "0,f"))
15966 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15967 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15968 "* return output_387_binary_op (insn, operands);"
15969 [(set (attr "type")
15970 (cond [(match_operand:DF 3 "mult_operator" "")
15971 (const_string "fmul")
15972 (match_operand:DF 3 "div_operator" "")
15973 (const_string "fdiv")
15975 (const_string "fop")))
15976 (set_attr "mode" "SF")])
15978 (define_insn "*fop_xf_comm_i387"
15979 [(set (match_operand:XF 0 "register_operand" "=f")
15980 (match_operator:XF 3 "binary_fp_operator"
15981 [(match_operand:XF 1 "register_operand" "%0")
15982 (match_operand:XF 2 "register_operand" "f")]))]
15984 && COMMUTATIVE_ARITH_P (operands[3])"
15985 "* return output_387_binary_op (insn, operands);"
15986 [(set (attr "type")
15987 (if_then_else (match_operand:XF 3 "mult_operator" "")
15988 (const_string "fmul")
15989 (const_string "fop")))
15990 (set_attr "mode" "XF")])
15992 (define_insn "*fop_xf_1_i387"
15993 [(set (match_operand:XF 0 "register_operand" "=f,f")
15994 (match_operator:XF 3 "binary_fp_operator"
15995 [(match_operand:XF 1 "register_operand" "0,f")
15996 (match_operand:XF 2 "register_operand" "f,0")]))]
15998 && !COMMUTATIVE_ARITH_P (operands[3])"
15999 "* return output_387_binary_op (insn, operands);"
16000 [(set (attr "type")
16001 (cond [(match_operand:XF 3 "mult_operator" "")
16002 (const_string "fmul")
16003 (match_operand:XF 3 "div_operator" "")
16004 (const_string "fdiv")
16006 (const_string "fop")))
16007 (set_attr "mode" "XF")])
16009 (define_insn "*fop_xf_2<mode>_i387"
16010 [(set (match_operand:XF 0 "register_operand" "=f,f")
16011 (match_operator:XF 3 "binary_fp_operator"
16012 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16013 (match_operand:XF 2 "register_operand" "0,0")]))]
16014 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16015 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16016 [(set (attr "type")
16017 (cond [(match_operand:XF 3 "mult_operator" "")
16018 (const_string "fmul")
16019 (match_operand:XF 3 "div_operator" "")
16020 (const_string "fdiv")
16022 (const_string "fop")))
16023 (set_attr "fp_int_src" "true")
16024 (set_attr "mode" "<MODE>")])
16026 (define_insn "*fop_xf_3<mode>_i387"
16027 [(set (match_operand:XF 0 "register_operand" "=f,f")
16028 (match_operator:XF 3 "binary_fp_operator"
16029 [(match_operand:XF 1 "register_operand" "0,0")
16030 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16031 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16032 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16033 [(set (attr "type")
16034 (cond [(match_operand:XF 3 "mult_operator" "")
16035 (const_string "fmul")
16036 (match_operand:XF 3 "div_operator" "")
16037 (const_string "fdiv")
16039 (const_string "fop")))
16040 (set_attr "fp_int_src" "true")
16041 (set_attr "mode" "<MODE>")])
16043 (define_insn "*fop_xf_4_i387"
16044 [(set (match_operand:XF 0 "register_operand" "=f,f")
16045 (match_operator:XF 3 "binary_fp_operator"
16047 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16048 (match_operand:XF 2 "register_operand" "0,f")]))]
16050 "* return output_387_binary_op (insn, operands);"
16051 [(set (attr "type")
16052 (cond [(match_operand:XF 3 "mult_operator" "")
16053 (const_string "fmul")
16054 (match_operand:XF 3 "div_operator" "")
16055 (const_string "fdiv")
16057 (const_string "fop")))
16058 (set_attr "mode" "SF")])
16060 (define_insn "*fop_xf_5_i387"
16061 [(set (match_operand:XF 0 "register_operand" "=f,f")
16062 (match_operator:XF 3 "binary_fp_operator"
16063 [(match_operand:XF 1 "register_operand" "0,f")
16065 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16067 "* return output_387_binary_op (insn, operands);"
16068 [(set (attr "type")
16069 (cond [(match_operand:XF 3 "mult_operator" "")
16070 (const_string "fmul")
16071 (match_operand:XF 3 "div_operator" "")
16072 (const_string "fdiv")
16074 (const_string "fop")))
16075 (set_attr "mode" "SF")])
16077 (define_insn "*fop_xf_6_i387"
16078 [(set (match_operand:XF 0 "register_operand" "=f,f")
16079 (match_operator:XF 3 "binary_fp_operator"
16081 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16083 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16085 "* return output_387_binary_op (insn, operands);"
16086 [(set (attr "type")
16087 (cond [(match_operand:XF 3 "mult_operator" "")
16088 (const_string "fmul")
16089 (match_operand:XF 3 "div_operator" "")
16090 (const_string "fdiv")
16092 (const_string "fop")))
16093 (set_attr "mode" "SF")])
16096 [(set (match_operand 0 "register_operand" "")
16097 (match_operator 3 "binary_fp_operator"
16098 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16099 (match_operand 2 "register_operand" "")]))]
16100 "TARGET_80387 && reload_completed
16101 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16104 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16105 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16106 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16107 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16108 GET_MODE (operands[3]),
16111 ix86_free_from_memory (GET_MODE (operands[1]));
16116 [(set (match_operand 0 "register_operand" "")
16117 (match_operator 3 "binary_fp_operator"
16118 [(match_operand 1 "register_operand" "")
16119 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16120 "TARGET_80387 && reload_completed
16121 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16124 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16125 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16126 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16127 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16128 GET_MODE (operands[3]),
16131 ix86_free_from_memory (GET_MODE (operands[2]));
16135 ;; FPU special functions.
16137 ;; This pattern implements a no-op XFmode truncation for
16138 ;; all fancy i386 XFmode math functions.
16140 (define_insn "truncxf<mode>2_i387_noop_unspec"
16141 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16142 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16143 UNSPEC_TRUNC_NOOP))]
16144 "TARGET_USE_FANCY_MATH_387"
16145 "* return output_387_reg_move (insn, operands);"
16146 [(set_attr "type" "fmov")
16147 (set_attr "mode" "<MODE>")])
16149 (define_insn "sqrtxf2"
16150 [(set (match_operand:XF 0 "register_operand" "=f")
16151 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16152 "TARGET_USE_FANCY_MATH_387"
16154 [(set_attr "type" "fpspc")
16155 (set_attr "mode" "XF")
16156 (set_attr "athlon_decode" "direct")
16157 (set_attr "amdfam10_decode" "direct")])
16159 (define_insn "sqrt_extend<mode>xf2_i387"
16160 [(set (match_operand:XF 0 "register_operand" "=f")
16163 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16164 "TARGET_USE_FANCY_MATH_387"
16166 [(set_attr "type" "fpspc")
16167 (set_attr "mode" "XF")
16168 (set_attr "athlon_decode" "direct")
16169 (set_attr "amdfam10_decode" "direct")])
16171 (define_insn "*sqrt<mode>2_sse"
16172 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16174 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16175 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16176 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16177 [(set_attr "type" "sse")
16178 (set_attr "mode" "<MODE>")
16179 (set_attr "athlon_decode" "*")
16180 (set_attr "amdfam10_decode" "*")])
16182 (define_expand "sqrt<mode>2"
16183 [(set (match_operand:X87MODEF12 0 "register_operand" "")
16185 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16186 "TARGET_USE_FANCY_MATH_387
16187 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16189 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16191 rtx op0 = gen_reg_rtx (XFmode);
16192 rtx op1 = force_reg (<MODE>mode, operands[1]);
16194 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16195 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16200 (define_insn "fpremxf4_i387"
16201 [(set (match_operand:XF 0 "register_operand" "=f")
16202 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16203 (match_operand:XF 3 "register_operand" "1")]
16205 (set (match_operand:XF 1 "register_operand" "=u")
16206 (unspec:XF [(match_dup 2) (match_dup 3)]
16208 (set (reg:CCFP FPSR_REG)
16209 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16210 "TARGET_USE_FANCY_MATH_387"
16212 [(set_attr "type" "fpspc")
16213 (set_attr "mode" "XF")])
16215 (define_expand "fmodxf3"
16216 [(use (match_operand:XF 0 "register_operand" ""))
16217 (use (match_operand:XF 1 "register_operand" ""))
16218 (use (match_operand:XF 2 "register_operand" ""))]
16219 "TARGET_USE_FANCY_MATH_387"
16221 rtx label = gen_label_rtx ();
16223 emit_label (label);
16225 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16226 operands[1], operands[2]));
16227 ix86_emit_fp_unordered_jump (label);
16229 emit_move_insn (operands[0], operands[1]);
16233 (define_expand "fmod<mode>3"
16234 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16235 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16236 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16237 "TARGET_USE_FANCY_MATH_387"
16239 rtx label = gen_label_rtx ();
16241 rtx op1 = gen_reg_rtx (XFmode);
16242 rtx op2 = gen_reg_rtx (XFmode);
16244 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16245 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16247 emit_label (label);
16248 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16249 ix86_emit_fp_unordered_jump (label);
16251 /* Truncate the result properly for strict SSE math. */
16252 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16253 && !TARGET_MIX_SSE_I387)
16254 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16256 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16261 (define_insn "fprem1xf4_i387"
16262 [(set (match_operand:XF 0 "register_operand" "=f")
16263 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16264 (match_operand:XF 3 "register_operand" "1")]
16266 (set (match_operand:XF 1 "register_operand" "=u")
16267 (unspec:XF [(match_dup 2) (match_dup 3)]
16269 (set (reg:CCFP FPSR_REG)
16270 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16271 "TARGET_USE_FANCY_MATH_387"
16273 [(set_attr "type" "fpspc")
16274 (set_attr "mode" "XF")])
16276 (define_expand "remainderxf3"
16277 [(use (match_operand:XF 0 "register_operand" ""))
16278 (use (match_operand:XF 1 "register_operand" ""))
16279 (use (match_operand:XF 2 "register_operand" ""))]
16280 "TARGET_USE_FANCY_MATH_387"
16282 rtx label = gen_label_rtx ();
16284 emit_label (label);
16286 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16287 operands[1], operands[2]));
16288 ix86_emit_fp_unordered_jump (label);
16290 emit_move_insn (operands[0], operands[1]);
16294 (define_expand "remainder<mode>3"
16295 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16296 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16297 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16298 "TARGET_USE_FANCY_MATH_387"
16300 rtx label = gen_label_rtx ();
16302 rtx op1 = gen_reg_rtx (XFmode);
16303 rtx op2 = gen_reg_rtx (XFmode);
16305 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16306 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16308 emit_label (label);
16310 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16311 ix86_emit_fp_unordered_jump (label);
16313 /* Truncate the result properly for strict SSE math. */
16314 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16315 && !TARGET_MIX_SSE_I387)
16316 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16318 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16323 (define_insn "*sinxf2_i387"
16324 [(set (match_operand:XF 0 "register_operand" "=f")
16325 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16326 "TARGET_USE_FANCY_MATH_387
16327 && flag_unsafe_math_optimizations"
16329 [(set_attr "type" "fpspc")
16330 (set_attr "mode" "XF")])
16332 (define_insn "*sin_extend<mode>xf2_i387"
16333 [(set (match_operand:XF 0 "register_operand" "=f")
16334 (unspec:XF [(float_extend:XF
16335 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16337 "TARGET_USE_FANCY_MATH_387
16338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16339 || TARGET_MIX_SSE_I387)
16340 && flag_unsafe_math_optimizations"
16342 [(set_attr "type" "fpspc")
16343 (set_attr "mode" "XF")])
16345 (define_insn "*cosxf2_i387"
16346 [(set (match_operand:XF 0 "register_operand" "=f")
16347 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16348 "TARGET_USE_FANCY_MATH_387
16349 && flag_unsafe_math_optimizations"
16351 [(set_attr "type" "fpspc")
16352 (set_attr "mode" "XF")])
16354 (define_insn "*cos_extend<mode>xf2_i387"
16355 [(set (match_operand:XF 0 "register_operand" "=f")
16356 (unspec:XF [(float_extend:XF
16357 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16359 "TARGET_USE_FANCY_MATH_387
16360 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16361 || TARGET_MIX_SSE_I387)
16362 && flag_unsafe_math_optimizations"
16364 [(set_attr "type" "fpspc")
16365 (set_attr "mode" "XF")])
16367 ;; When sincos pattern is defined, sin and cos builtin functions will be
16368 ;; expanded to sincos pattern with one of its outputs left unused.
16369 ;; CSE pass will figure out if two sincos patterns can be combined,
16370 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16371 ;; depending on the unused output.
16373 (define_insn "sincosxf3"
16374 [(set (match_operand:XF 0 "register_operand" "=f")
16375 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16376 UNSPEC_SINCOS_COS))
16377 (set (match_operand:XF 1 "register_operand" "=u")
16378 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16379 "TARGET_USE_FANCY_MATH_387
16380 && flag_unsafe_math_optimizations"
16382 [(set_attr "type" "fpspc")
16383 (set_attr "mode" "XF")])
16386 [(set (match_operand:XF 0 "register_operand" "")
16387 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16388 UNSPEC_SINCOS_COS))
16389 (set (match_operand:XF 1 "register_operand" "")
16390 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16391 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16392 && !reload_completed && !reload_in_progress"
16393 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16397 [(set (match_operand:XF 0 "register_operand" "")
16398 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16399 UNSPEC_SINCOS_COS))
16400 (set (match_operand:XF 1 "register_operand" "")
16401 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16402 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16403 && !reload_completed && !reload_in_progress"
16404 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16407 (define_insn "sincos_extend<mode>xf3_i387"
16408 [(set (match_operand:XF 0 "register_operand" "=f")
16409 (unspec:XF [(float_extend:XF
16410 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16411 UNSPEC_SINCOS_COS))
16412 (set (match_operand:XF 1 "register_operand" "=u")
16413 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16414 "TARGET_USE_FANCY_MATH_387
16415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16416 || TARGET_MIX_SSE_I387)
16417 && flag_unsafe_math_optimizations"
16419 [(set_attr "type" "fpspc")
16420 (set_attr "mode" "XF")])
16423 [(set (match_operand:XF 0 "register_operand" "")
16424 (unspec:XF [(float_extend:XF
16425 (match_operand:X87MODEF12 2 "register_operand" ""))]
16426 UNSPEC_SINCOS_COS))
16427 (set (match_operand:XF 1 "register_operand" "")
16428 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16429 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16430 && !reload_completed && !reload_in_progress"
16431 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16435 [(set (match_operand:XF 0 "register_operand" "")
16436 (unspec:XF [(float_extend:XF
16437 (match_operand:X87MODEF12 2 "register_operand" ""))]
16438 UNSPEC_SINCOS_COS))
16439 (set (match_operand:XF 1 "register_operand" "")
16440 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16441 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16442 && !reload_completed && !reload_in_progress"
16443 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16446 (define_expand "sincos<mode>3"
16447 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16448 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16449 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16452 || TARGET_MIX_SSE_I387)
16453 && flag_unsafe_math_optimizations"
16455 rtx op0 = gen_reg_rtx (XFmode);
16456 rtx op1 = gen_reg_rtx (XFmode);
16458 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16459 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16460 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16464 (define_insn "fptanxf4_i387"
16465 [(set (match_operand:XF 0 "register_operand" "=f")
16466 (match_operand:XF 3 "const_double_operand" "F"))
16467 (set (match_operand:XF 1 "register_operand" "=u")
16468 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16470 "TARGET_USE_FANCY_MATH_387
16471 && flag_unsafe_math_optimizations
16472 && standard_80387_constant_p (operands[3]) == 2"
16474 [(set_attr "type" "fpspc")
16475 (set_attr "mode" "XF")])
16477 (define_insn "fptan_extend<mode>xf4_i387"
16478 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16479 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16480 (set (match_operand:XF 1 "register_operand" "=u")
16481 (unspec:XF [(float_extend:XF
16482 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16484 "TARGET_USE_FANCY_MATH_387
16485 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16486 || TARGET_MIX_SSE_I387)
16487 && flag_unsafe_math_optimizations
16488 && standard_80387_constant_p (operands[3]) == 2"
16490 [(set_attr "type" "fpspc")
16491 (set_attr "mode" "XF")])
16493 (define_expand "tanxf2"
16494 [(use (match_operand:XF 0 "register_operand" ""))
16495 (use (match_operand:XF 1 "register_operand" ""))]
16496 "TARGET_USE_FANCY_MATH_387
16497 && flag_unsafe_math_optimizations"
16499 rtx one = gen_reg_rtx (XFmode);
16500 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16502 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16506 (define_expand "tan<mode>2"
16507 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16508 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16509 "TARGET_USE_FANCY_MATH_387
16510 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16511 || TARGET_MIX_SSE_I387)
16512 && flag_unsafe_math_optimizations"
16514 rtx op0 = gen_reg_rtx (XFmode);
16516 rtx one = gen_reg_rtx (<MODE>mode);
16517 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16519 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16520 operands[1], op2));
16521 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16525 (define_insn "*fpatanxf3_i387"
16526 [(set (match_operand:XF 0 "register_operand" "=f")
16527 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16528 (match_operand:XF 2 "register_operand" "u")]
16530 (clobber (match_scratch:XF 3 "=2"))]
16531 "TARGET_USE_FANCY_MATH_387
16532 && flag_unsafe_math_optimizations"
16534 [(set_attr "type" "fpspc")
16535 (set_attr "mode" "XF")])
16537 (define_insn "fpatan_extend<mode>xf3_i387"
16538 [(set (match_operand:XF 0 "register_operand" "=f")
16539 (unspec:XF [(float_extend:XF
16540 (match_operand:X87MODEF12 1 "register_operand" "0"))
16542 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16544 (clobber (match_scratch:XF 3 "=2"))]
16545 "TARGET_USE_FANCY_MATH_387
16546 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16547 || TARGET_MIX_SSE_I387)
16548 && flag_unsafe_math_optimizations"
16550 [(set_attr "type" "fpspc")
16551 (set_attr "mode" "XF")])
16553 (define_expand "atan2xf3"
16554 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16555 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16556 (match_operand:XF 1 "register_operand" "")]
16558 (clobber (match_scratch:XF 3 ""))])]
16559 "TARGET_USE_FANCY_MATH_387
16560 && flag_unsafe_math_optimizations"
16563 (define_expand "atan2<mode>3"
16564 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16565 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16566 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16567 "TARGET_USE_FANCY_MATH_387
16568 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16569 || TARGET_MIX_SSE_I387)
16570 && flag_unsafe_math_optimizations"
16572 rtx op0 = gen_reg_rtx (XFmode);
16574 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16575 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16579 (define_expand "atanxf2"
16580 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16581 (unspec:XF [(match_dup 2)
16582 (match_operand:XF 1 "register_operand" "")]
16584 (clobber (match_scratch:XF 3 ""))])]
16585 "TARGET_USE_FANCY_MATH_387
16586 && flag_unsafe_math_optimizations"
16588 operands[2] = gen_reg_rtx (XFmode);
16589 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16592 (define_expand "atan<mode>2"
16593 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16594 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16595 "TARGET_USE_FANCY_MATH_387
16596 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16597 || TARGET_MIX_SSE_I387)
16598 && flag_unsafe_math_optimizations"
16600 rtx op0 = gen_reg_rtx (XFmode);
16602 rtx op2 = gen_reg_rtx (<MODE>mode);
16603 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16605 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16606 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16610 (define_expand "asinxf2"
16611 [(set (match_dup 2)
16612 (mult:XF (match_operand:XF 1 "register_operand" "")
16614 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16615 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16616 (parallel [(set (match_operand:XF 0 "register_operand" "")
16617 (unspec:XF [(match_dup 5) (match_dup 1)]
16619 (clobber (match_scratch:XF 6 ""))])]
16620 "TARGET_USE_FANCY_MATH_387
16621 && flag_unsafe_math_optimizations && !optimize_size"
16625 for (i = 2; i < 6; i++)
16626 operands[i] = gen_reg_rtx (XFmode);
16628 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16631 (define_expand "asin<mode>2"
16632 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16633 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16634 "TARGET_USE_FANCY_MATH_387
16635 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16636 || TARGET_MIX_SSE_I387)
16637 && flag_unsafe_math_optimizations && !optimize_size"
16639 rtx op0 = gen_reg_rtx (XFmode);
16640 rtx op1 = gen_reg_rtx (XFmode);
16642 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16643 emit_insn (gen_asinxf2 (op0, op1));
16644 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16648 (define_expand "acosxf2"
16649 [(set (match_dup 2)
16650 (mult:XF (match_operand:XF 1 "register_operand" "")
16652 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16653 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16654 (parallel [(set (match_operand:XF 0 "register_operand" "")
16655 (unspec:XF [(match_dup 1) (match_dup 5)]
16657 (clobber (match_scratch:XF 6 ""))])]
16658 "TARGET_USE_FANCY_MATH_387
16659 && flag_unsafe_math_optimizations && !optimize_size"
16663 for (i = 2; i < 6; i++)
16664 operands[i] = gen_reg_rtx (XFmode);
16666 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16669 (define_expand "acos<mode>2"
16670 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16671 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16672 "TARGET_USE_FANCY_MATH_387
16673 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16674 || TARGET_MIX_SSE_I387)
16675 && flag_unsafe_math_optimizations && !optimize_size"
16677 rtx op0 = gen_reg_rtx (XFmode);
16678 rtx op1 = gen_reg_rtx (XFmode);
16680 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16681 emit_insn (gen_acosxf2 (op0, op1));
16682 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16686 (define_insn "fyl2xxf3_i387"
16687 [(set (match_operand:XF 0 "register_operand" "=f")
16688 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16689 (match_operand:XF 2 "register_operand" "u")]
16691 (clobber (match_scratch:XF 3 "=2"))]
16692 "TARGET_USE_FANCY_MATH_387
16693 && flag_unsafe_math_optimizations"
16695 [(set_attr "type" "fpspc")
16696 (set_attr "mode" "XF")])
16698 (define_insn "fyl2x_extend<mode>xf3_i387"
16699 [(set (match_operand:XF 0 "register_operand" "=f")
16700 (unspec:XF [(float_extend:XF
16701 (match_operand:X87MODEF12 1 "register_operand" "0"))
16702 (match_operand:XF 2 "register_operand" "u")]
16704 (clobber (match_scratch:XF 3 "=2"))]
16705 "TARGET_USE_FANCY_MATH_387
16706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16707 || TARGET_MIX_SSE_I387)
16708 && flag_unsafe_math_optimizations"
16710 [(set_attr "type" "fpspc")
16711 (set_attr "mode" "XF")])
16713 (define_expand "logxf2"
16714 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16715 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16716 (match_dup 2)] UNSPEC_FYL2X))
16717 (clobber (match_scratch:XF 3 ""))])]
16718 "TARGET_USE_FANCY_MATH_387
16719 && flag_unsafe_math_optimizations"
16721 operands[2] = gen_reg_rtx (XFmode);
16722 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16725 (define_expand "log<mode>2"
16726 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16727 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16728 "TARGET_USE_FANCY_MATH_387
16729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16730 || TARGET_MIX_SSE_I387)
16731 && flag_unsafe_math_optimizations"
16733 rtx op0 = gen_reg_rtx (XFmode);
16735 rtx op2 = gen_reg_rtx (XFmode);
16736 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16738 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16739 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16743 (define_expand "log10xf2"
16744 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16745 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16746 (match_dup 2)] UNSPEC_FYL2X))
16747 (clobber (match_scratch:XF 3 ""))])]
16748 "TARGET_USE_FANCY_MATH_387
16749 && flag_unsafe_math_optimizations"
16751 operands[2] = gen_reg_rtx (XFmode);
16752 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16755 (define_expand "log10<mode>2"
16756 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16757 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16758 "TARGET_USE_FANCY_MATH_387
16759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16760 || TARGET_MIX_SSE_I387)
16761 && flag_unsafe_math_optimizations"
16763 rtx op0 = gen_reg_rtx (XFmode);
16765 rtx op2 = gen_reg_rtx (XFmode);
16766 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16768 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16769 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16773 (define_expand "log2xf2"
16774 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16775 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16776 (match_dup 2)] UNSPEC_FYL2X))
16777 (clobber (match_scratch:XF 3 ""))])]
16778 "TARGET_USE_FANCY_MATH_387
16779 && flag_unsafe_math_optimizations"
16781 operands[2] = gen_reg_rtx (XFmode);
16782 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16785 (define_expand "log2<mode>2"
16786 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16787 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16788 "TARGET_USE_FANCY_MATH_387
16789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16790 || TARGET_MIX_SSE_I387)
16791 && flag_unsafe_math_optimizations"
16793 rtx op0 = gen_reg_rtx (XFmode);
16795 rtx op2 = gen_reg_rtx (XFmode);
16796 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16798 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16803 (define_insn "fyl2xp1xf3_i387"
16804 [(set (match_operand:XF 0 "register_operand" "=f")
16805 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16806 (match_operand:XF 2 "register_operand" "u")]
16808 (clobber (match_scratch:XF 3 "=2"))]
16809 "TARGET_USE_FANCY_MATH_387
16810 && flag_unsafe_math_optimizations"
16812 [(set_attr "type" "fpspc")
16813 (set_attr "mode" "XF")])
16815 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16816 [(set (match_operand:XF 0 "register_operand" "=f")
16817 (unspec:XF [(float_extend:XF
16818 (match_operand:X87MODEF12 1 "register_operand" "0"))
16819 (match_operand:XF 2 "register_operand" "u")]
16821 (clobber (match_scratch:XF 3 "=2"))]
16822 "TARGET_USE_FANCY_MATH_387
16823 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16824 || TARGET_MIX_SSE_I387)
16825 && flag_unsafe_math_optimizations"
16827 [(set_attr "type" "fpspc")
16828 (set_attr "mode" "XF")])
16830 (define_expand "log1pxf2"
16831 [(use (match_operand:XF 0 "register_operand" ""))
16832 (use (match_operand:XF 1 "register_operand" ""))]
16833 "TARGET_USE_FANCY_MATH_387
16834 && flag_unsafe_math_optimizations && !optimize_size"
16836 ix86_emit_i387_log1p (operands[0], operands[1]);
16840 (define_expand "log1p<mode>2"
16841 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16842 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16843 "TARGET_USE_FANCY_MATH_387
16844 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16845 || TARGET_MIX_SSE_I387)
16846 && flag_unsafe_math_optimizations && !optimize_size"
16848 rtx op0 = gen_reg_rtx (XFmode);
16850 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16852 ix86_emit_i387_log1p (op0, operands[1]);
16853 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16857 (define_insn "fxtractxf3_i387"
16858 [(set (match_operand:XF 0 "register_operand" "=f")
16859 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16860 UNSPEC_XTRACT_FRACT))
16861 (set (match_operand:XF 1 "register_operand" "=u")
16862 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16863 "TARGET_USE_FANCY_MATH_387
16864 && flag_unsafe_math_optimizations"
16866 [(set_attr "type" "fpspc")
16867 (set_attr "mode" "XF")])
16869 (define_insn "fxtract_extend<mode>xf3_i387"
16870 [(set (match_operand:XF 0 "register_operand" "=f")
16871 (unspec:XF [(float_extend:XF
16872 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16873 UNSPEC_XTRACT_FRACT))
16874 (set (match_operand:XF 1 "register_operand" "=u")
16875 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16876 "TARGET_USE_FANCY_MATH_387
16877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16878 || TARGET_MIX_SSE_I387)
16879 && flag_unsafe_math_optimizations"
16881 [(set_attr "type" "fpspc")
16882 (set_attr "mode" "XF")])
16884 (define_expand "logbxf2"
16885 [(parallel [(set (match_dup 2)
16886 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16887 UNSPEC_XTRACT_FRACT))
16888 (set (match_operand:XF 0 "register_operand" "")
16889 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16890 "TARGET_USE_FANCY_MATH_387
16891 && flag_unsafe_math_optimizations"
16893 operands[2] = gen_reg_rtx (XFmode);
16896 (define_expand "logb<mode>2"
16897 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16898 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16899 "TARGET_USE_FANCY_MATH_387
16900 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16901 || TARGET_MIX_SSE_I387)
16902 && flag_unsafe_math_optimizations"
16904 rtx op0 = gen_reg_rtx (XFmode);
16905 rtx op1 = gen_reg_rtx (XFmode);
16907 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16908 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16912 (define_expand "ilogbxf2"
16913 [(use (match_operand:SI 0 "register_operand" ""))
16914 (use (match_operand:XF 1 "register_operand" ""))]
16915 "TARGET_USE_FANCY_MATH_387
16916 && flag_unsafe_math_optimizations && !optimize_size"
16918 rtx op0 = gen_reg_rtx (XFmode);
16919 rtx op1 = gen_reg_rtx (XFmode);
16921 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16922 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16926 (define_expand "ilogb<mode>2"
16927 [(use (match_operand:SI 0 "register_operand" ""))
16928 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16929 "TARGET_USE_FANCY_MATH_387
16930 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16931 || TARGET_MIX_SSE_I387)
16932 && flag_unsafe_math_optimizations && !optimize_size"
16934 rtx op0 = gen_reg_rtx (XFmode);
16935 rtx op1 = gen_reg_rtx (XFmode);
16937 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16938 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16942 (define_insn "*f2xm1xf2_i387"
16943 [(set (match_operand:XF 0 "register_operand" "=f")
16944 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16946 "TARGET_USE_FANCY_MATH_387
16947 && flag_unsafe_math_optimizations"
16949 [(set_attr "type" "fpspc")
16950 (set_attr "mode" "XF")])
16952 (define_insn "*fscalexf4_i387"
16953 [(set (match_operand:XF 0 "register_operand" "=f")
16954 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16955 (match_operand:XF 3 "register_operand" "1")]
16956 UNSPEC_FSCALE_FRACT))
16957 (set (match_operand:XF 1 "register_operand" "=u")
16958 (unspec:XF [(match_dup 2) (match_dup 3)]
16959 UNSPEC_FSCALE_EXP))]
16960 "TARGET_USE_FANCY_MATH_387
16961 && flag_unsafe_math_optimizations"
16963 [(set_attr "type" "fpspc")
16964 (set_attr "mode" "XF")])
16966 (define_expand "expNcorexf3"
16967 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16968 (match_operand:XF 2 "register_operand" "")))
16969 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16970 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16971 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16972 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16973 (parallel [(set (match_operand:XF 0 "register_operand" "")
16974 (unspec:XF [(match_dup 8) (match_dup 4)]
16975 UNSPEC_FSCALE_FRACT))
16977 (unspec:XF [(match_dup 8) (match_dup 4)]
16978 UNSPEC_FSCALE_EXP))])]
16979 "TARGET_USE_FANCY_MATH_387
16980 && flag_unsafe_math_optimizations && !optimize_size"
16984 for (i = 3; i < 10; i++)
16985 operands[i] = gen_reg_rtx (XFmode);
16987 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16990 (define_expand "expxf2"
16991 [(use (match_operand:XF 0 "register_operand" ""))
16992 (use (match_operand:XF 1 "register_operand" ""))]
16993 "TARGET_USE_FANCY_MATH_387
16994 && flag_unsafe_math_optimizations && !optimize_size"
16996 rtx op2 = gen_reg_rtx (XFmode);
16997 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16999 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17003 (define_expand "exp<mode>2"
17004 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17005 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17006 "TARGET_USE_FANCY_MATH_387
17007 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17008 || TARGET_MIX_SSE_I387)
17009 && flag_unsafe_math_optimizations && !optimize_size"
17011 rtx op0 = gen_reg_rtx (XFmode);
17012 rtx op1 = gen_reg_rtx (XFmode);
17014 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17015 emit_insn (gen_expxf2 (op0, op1));
17016 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17020 (define_expand "exp10xf2"
17021 [(use (match_operand:XF 0 "register_operand" ""))
17022 (use (match_operand:XF 1 "register_operand" ""))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && flag_unsafe_math_optimizations && !optimize_size"
17026 rtx op2 = gen_reg_rtx (XFmode);
17027 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17029 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17033 (define_expand "exp10<mode>2"
17034 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17035 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17036 "TARGET_USE_FANCY_MATH_387
17037 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17038 || TARGET_MIX_SSE_I387)
17039 && flag_unsafe_math_optimizations && !optimize_size"
17041 rtx op0 = gen_reg_rtx (XFmode);
17042 rtx op1 = gen_reg_rtx (XFmode);
17044 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17045 emit_insn (gen_exp10xf2 (op0, op1));
17046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17050 (define_expand "exp2xf2"
17051 [(use (match_operand:XF 0 "register_operand" ""))
17052 (use (match_operand:XF 1 "register_operand" ""))]
17053 "TARGET_USE_FANCY_MATH_387
17054 && flag_unsafe_math_optimizations && !optimize_size"
17056 rtx op2 = gen_reg_rtx (XFmode);
17057 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17059 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17063 (define_expand "exp2<mode>2"
17064 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17065 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17066 "TARGET_USE_FANCY_MATH_387
17067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17068 || TARGET_MIX_SSE_I387)
17069 && flag_unsafe_math_optimizations && !optimize_size"
17071 rtx op0 = gen_reg_rtx (XFmode);
17072 rtx op1 = gen_reg_rtx (XFmode);
17074 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17075 emit_insn (gen_exp2xf2 (op0, op1));
17076 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17080 (define_expand "expm1xf2"
17081 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17083 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17084 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17085 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17086 (parallel [(set (match_dup 7)
17087 (unspec:XF [(match_dup 6) (match_dup 4)]
17088 UNSPEC_FSCALE_FRACT))
17090 (unspec:XF [(match_dup 6) (match_dup 4)]
17091 UNSPEC_FSCALE_EXP))])
17092 (parallel [(set (match_dup 10)
17093 (unspec:XF [(match_dup 9) (match_dup 8)]
17094 UNSPEC_FSCALE_FRACT))
17095 (set (match_dup 11)
17096 (unspec:XF [(match_dup 9) (match_dup 8)]
17097 UNSPEC_FSCALE_EXP))])
17098 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17099 (set (match_operand:XF 0 "register_operand" "")
17100 (plus:XF (match_dup 12) (match_dup 7)))]
17101 "TARGET_USE_FANCY_MATH_387
17102 && flag_unsafe_math_optimizations && !optimize_size"
17106 for (i = 2; i < 13; i++)
17107 operands[i] = gen_reg_rtx (XFmode);
17109 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17110 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17113 (define_expand "expm1<mode>2"
17114 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17115 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17116 "TARGET_USE_FANCY_MATH_387
17117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17118 || TARGET_MIX_SSE_I387)
17119 && flag_unsafe_math_optimizations && !optimize_size"
17121 rtx op0 = gen_reg_rtx (XFmode);
17122 rtx op1 = gen_reg_rtx (XFmode);
17124 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17125 emit_insn (gen_expm1xf2 (op0, op1));
17126 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17130 (define_expand "ldexpxf3"
17131 [(set (match_dup 3)
17132 (float:XF (match_operand:SI 2 "register_operand" "")))
17133 (parallel [(set (match_operand:XF 0 " register_operand" "")
17134 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17136 UNSPEC_FSCALE_FRACT))
17138 (unspec:XF [(match_dup 1) (match_dup 3)]
17139 UNSPEC_FSCALE_EXP))])]
17140 "TARGET_USE_FANCY_MATH_387
17141 && flag_unsafe_math_optimizations && !optimize_size"
17143 operands[3] = gen_reg_rtx (XFmode);
17144 operands[4] = gen_reg_rtx (XFmode);
17147 (define_expand "ldexp<mode>3"
17148 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17149 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17150 (use (match_operand:SI 2 "register_operand" ""))]
17151 "TARGET_USE_FANCY_MATH_387
17152 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17153 || TARGET_MIX_SSE_I387)
17154 && flag_unsafe_math_optimizations && !optimize_size"
17156 rtx op0 = gen_reg_rtx (XFmode);
17157 rtx op1 = gen_reg_rtx (XFmode);
17159 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17160 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17161 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17166 (define_insn "frndintxf2"
17167 [(set (match_operand:XF 0 "register_operand" "=f")
17168 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17170 "TARGET_USE_FANCY_MATH_387
17171 && flag_unsafe_math_optimizations"
17173 [(set_attr "type" "fpspc")
17174 (set_attr "mode" "XF")])
17176 (define_expand "rintdf2"
17177 [(use (match_operand:DF 0 "register_operand" ""))
17178 (use (match_operand:DF 1 "register_operand" ""))]
17179 "(TARGET_USE_FANCY_MATH_387
17180 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17181 && flag_unsafe_math_optimizations)
17182 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17183 && !flag_trapping_math
17184 && !optimize_size)"
17186 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17187 && !flag_trapping_math
17189 ix86_expand_rint (operand0, operand1);
17192 rtx op0 = gen_reg_rtx (XFmode);
17193 rtx op1 = gen_reg_rtx (XFmode);
17195 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17196 emit_insn (gen_frndintxf2 (op0, op1));
17198 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17203 (define_expand "rintsf2"
17204 [(use (match_operand:SF 0 "register_operand" ""))
17205 (use (match_operand:SF 1 "register_operand" ""))]
17206 "(TARGET_USE_FANCY_MATH_387
17207 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17208 && flag_unsafe_math_optimizations)
17209 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17210 && !flag_trapping_math
17211 && !optimize_size)"
17213 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17214 && !flag_trapping_math
17216 ix86_expand_rint (operand0, operand1);
17219 rtx op0 = gen_reg_rtx (XFmode);
17220 rtx op1 = gen_reg_rtx (XFmode);
17222 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17223 emit_insn (gen_frndintxf2 (op0, op1));
17225 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17230 (define_expand "rintxf2"
17231 [(use (match_operand:XF 0 "register_operand" ""))
17232 (use (match_operand:XF 1 "register_operand" ""))]
17233 "TARGET_USE_FANCY_MATH_387
17234 && flag_unsafe_math_optimizations && !optimize_size"
17236 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17240 (define_expand "roundsf2"
17241 [(match_operand:SF 0 "register_operand" "")
17242 (match_operand:SF 1 "nonimmediate_operand" "")]
17243 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17244 && !flag_trapping_math && !flag_rounding_math
17247 ix86_expand_round (operand0, operand1);
17251 (define_expand "rounddf2"
17252 [(match_operand:DF 0 "register_operand" "")
17253 (match_operand:DF 1 "nonimmediate_operand" "")]
17254 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17255 && !flag_trapping_math && !flag_rounding_math
17259 ix86_expand_round (operand0, operand1);
17261 ix86_expand_rounddf_32 (operand0, operand1);
17265 (define_insn_and_split "*fistdi2_1"
17266 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17267 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17269 "TARGET_USE_FANCY_MATH_387
17270 && !(reload_completed || reload_in_progress)"
17275 if (memory_operand (operands[0], VOIDmode))
17276 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17279 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17280 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17285 [(set_attr "type" "fpspc")
17286 (set_attr "mode" "DI")])
17288 (define_insn "fistdi2"
17289 [(set (match_operand:DI 0 "memory_operand" "=m")
17290 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17292 (clobber (match_scratch:XF 2 "=&1f"))]
17293 "TARGET_USE_FANCY_MATH_387"
17294 "* return output_fix_trunc (insn, operands, 0);"
17295 [(set_attr "type" "fpspc")
17296 (set_attr "mode" "DI")])
17298 (define_insn "fistdi2_with_temp"
17299 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17300 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17302 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17303 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17304 "TARGET_USE_FANCY_MATH_387"
17306 [(set_attr "type" "fpspc")
17307 (set_attr "mode" "DI")])
17310 [(set (match_operand:DI 0 "register_operand" "")
17311 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17313 (clobber (match_operand:DI 2 "memory_operand" ""))
17314 (clobber (match_scratch 3 ""))]
17316 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17317 (clobber (match_dup 3))])
17318 (set (match_dup 0) (match_dup 2))]
17322 [(set (match_operand:DI 0 "memory_operand" "")
17323 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17325 (clobber (match_operand:DI 2 "memory_operand" ""))
17326 (clobber (match_scratch 3 ""))]
17328 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17329 (clobber (match_dup 3))])]
17332 (define_insn_and_split "*fist<mode>2_1"
17333 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17334 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17336 "TARGET_USE_FANCY_MATH_387
17337 && !(reload_completed || reload_in_progress)"
17342 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17343 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17347 [(set_attr "type" "fpspc")
17348 (set_attr "mode" "<MODE>")])
17350 (define_insn "fist<mode>2"
17351 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17352 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17354 "TARGET_USE_FANCY_MATH_387"
17355 "* return output_fix_trunc (insn, operands, 0);"
17356 [(set_attr "type" "fpspc")
17357 (set_attr "mode" "<MODE>")])
17359 (define_insn "fist<mode>2_with_temp"
17360 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17361 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17363 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17364 "TARGET_USE_FANCY_MATH_387"
17366 [(set_attr "type" "fpspc")
17367 (set_attr "mode" "<MODE>")])
17370 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17371 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17373 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17375 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17377 (set (match_dup 0) (match_dup 2))]
17381 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17382 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17384 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17386 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17390 (define_expand "lrintxf<mode>2"
17391 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17392 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17394 "TARGET_USE_FANCY_MATH_387"
17397 (define_expand "lrint<mode>di2"
17398 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17399 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17400 UNSPEC_FIX_NOTRUNC))]
17401 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17404 (define_expand "lrint<mode>si2"
17405 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17406 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17407 UNSPEC_FIX_NOTRUNC))]
17408 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17411 (define_expand "lround<mode>di2"
17412 [(match_operand:DI 0 "nonimmediate_operand" "")
17413 (match_operand:SSEMODEF 1 "register_operand" "")]
17414 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17415 && !flag_trapping_math && !flag_rounding_math
17418 ix86_expand_lround (operand0, operand1);
17422 (define_expand "lround<mode>si2"
17423 [(match_operand:SI 0 "nonimmediate_operand" "")
17424 (match_operand:SSEMODEF 1 "register_operand" "")]
17425 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17426 && !flag_trapping_math && !flag_rounding_math
17429 ix86_expand_lround (operand0, operand1);
17433 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17434 (define_insn_and_split "frndintxf2_floor"
17435 [(set (match_operand:XF 0 "register_operand" "=f")
17436 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17437 UNSPEC_FRNDINT_FLOOR))
17438 (clobber (reg:CC FLAGS_REG))]
17439 "TARGET_USE_FANCY_MATH_387
17440 && flag_unsafe_math_optimizations
17441 && !(reload_completed || reload_in_progress)"
17446 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17448 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17449 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17451 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17452 operands[2], operands[3]));
17455 [(set_attr "type" "frndint")
17456 (set_attr "i387_cw" "floor")
17457 (set_attr "mode" "XF")])
17459 (define_insn "frndintxf2_floor_i387"
17460 [(set (match_operand:XF 0 "register_operand" "=f")
17461 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17462 UNSPEC_FRNDINT_FLOOR))
17463 (use (match_operand:HI 2 "memory_operand" "m"))
17464 (use (match_operand:HI 3 "memory_operand" "m"))]
17465 "TARGET_USE_FANCY_MATH_387
17466 && flag_unsafe_math_optimizations"
17467 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17468 [(set_attr "type" "frndint")
17469 (set_attr "i387_cw" "floor")
17470 (set_attr "mode" "XF")])
17472 (define_expand "floorxf2"
17473 [(use (match_operand:XF 0 "register_operand" ""))
17474 (use (match_operand:XF 1 "register_operand" ""))]
17475 "TARGET_USE_FANCY_MATH_387
17476 && flag_unsafe_math_optimizations && !optimize_size"
17478 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17482 (define_expand "floordf2"
17483 [(use (match_operand:DF 0 "register_operand" ""))
17484 (use (match_operand:DF 1 "register_operand" ""))]
17485 "((TARGET_USE_FANCY_MATH_387
17486 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17487 && flag_unsafe_math_optimizations)
17488 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17489 && !flag_trapping_math))
17492 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17493 && !flag_trapping_math)
17496 ix86_expand_floorceil (operand0, operand1, true);
17498 ix86_expand_floorceildf_32 (operand0, operand1, true);
17502 rtx op0 = gen_reg_rtx (XFmode);
17503 rtx op1 = gen_reg_rtx (XFmode);
17505 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17506 emit_insn (gen_frndintxf2_floor (op0, op1));
17508 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17513 (define_expand "floorsf2"
17514 [(use (match_operand:SF 0 "register_operand" ""))
17515 (use (match_operand:SF 1 "register_operand" ""))]
17516 "((TARGET_USE_FANCY_MATH_387
17517 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17518 && flag_unsafe_math_optimizations)
17519 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17520 && !flag_trapping_math))
17523 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17524 && !flag_trapping_math)
17525 ix86_expand_floorceil (operand0, operand1, true);
17528 rtx op0 = gen_reg_rtx (XFmode);
17529 rtx op1 = gen_reg_rtx (XFmode);
17531 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17532 emit_insn (gen_frndintxf2_floor (op0, op1));
17534 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17539 (define_insn_and_split "*fist<mode>2_floor_1"
17540 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17541 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17542 UNSPEC_FIST_FLOOR))
17543 (clobber (reg:CC FLAGS_REG))]
17544 "TARGET_USE_FANCY_MATH_387
17545 && flag_unsafe_math_optimizations
17546 && !(reload_completed || reload_in_progress)"
17551 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17553 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17554 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17555 if (memory_operand (operands[0], VOIDmode))
17556 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17557 operands[2], operands[3]));
17560 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17561 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17562 operands[2], operands[3],
17567 [(set_attr "type" "fistp")
17568 (set_attr "i387_cw" "floor")
17569 (set_attr "mode" "<MODE>")])
17571 (define_insn "fistdi2_floor"
17572 [(set (match_operand:DI 0 "memory_operand" "=m")
17573 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17574 UNSPEC_FIST_FLOOR))
17575 (use (match_operand:HI 2 "memory_operand" "m"))
17576 (use (match_operand:HI 3 "memory_operand" "m"))
17577 (clobber (match_scratch:XF 4 "=&1f"))]
17578 "TARGET_USE_FANCY_MATH_387
17579 && flag_unsafe_math_optimizations"
17580 "* return output_fix_trunc (insn, operands, 0);"
17581 [(set_attr "type" "fistp")
17582 (set_attr "i387_cw" "floor")
17583 (set_attr "mode" "DI")])
17585 (define_insn "fistdi2_floor_with_temp"
17586 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17587 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17588 UNSPEC_FIST_FLOOR))
17589 (use (match_operand:HI 2 "memory_operand" "m,m"))
17590 (use (match_operand:HI 3 "memory_operand" "m,m"))
17591 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17592 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17593 "TARGET_USE_FANCY_MATH_387
17594 && flag_unsafe_math_optimizations"
17596 [(set_attr "type" "fistp")
17597 (set_attr "i387_cw" "floor")
17598 (set_attr "mode" "DI")])
17601 [(set (match_operand:DI 0 "register_operand" "")
17602 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17603 UNSPEC_FIST_FLOOR))
17604 (use (match_operand:HI 2 "memory_operand" ""))
17605 (use (match_operand:HI 3 "memory_operand" ""))
17606 (clobber (match_operand:DI 4 "memory_operand" ""))
17607 (clobber (match_scratch 5 ""))]
17609 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17610 (use (match_dup 2))
17611 (use (match_dup 3))
17612 (clobber (match_dup 5))])
17613 (set (match_dup 0) (match_dup 4))]
17617 [(set (match_operand:DI 0 "memory_operand" "")
17618 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17619 UNSPEC_FIST_FLOOR))
17620 (use (match_operand:HI 2 "memory_operand" ""))
17621 (use (match_operand:HI 3 "memory_operand" ""))
17622 (clobber (match_operand:DI 4 "memory_operand" ""))
17623 (clobber (match_scratch 5 ""))]
17625 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17626 (use (match_dup 2))
17627 (use (match_dup 3))
17628 (clobber (match_dup 5))])]
17631 (define_insn "fist<mode>2_floor"
17632 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17633 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17634 UNSPEC_FIST_FLOOR))
17635 (use (match_operand:HI 2 "memory_operand" "m"))
17636 (use (match_operand:HI 3 "memory_operand" "m"))]
17637 "TARGET_USE_FANCY_MATH_387
17638 && flag_unsafe_math_optimizations"
17639 "* return output_fix_trunc (insn, operands, 0);"
17640 [(set_attr "type" "fistp")
17641 (set_attr "i387_cw" "floor")
17642 (set_attr "mode" "<MODE>")])
17644 (define_insn "fist<mode>2_floor_with_temp"
17645 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17646 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17647 UNSPEC_FIST_FLOOR))
17648 (use (match_operand:HI 2 "memory_operand" "m,m"))
17649 (use (match_operand:HI 3 "memory_operand" "m,m"))
17650 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17651 "TARGET_USE_FANCY_MATH_387
17652 && flag_unsafe_math_optimizations"
17654 [(set_attr "type" "fistp")
17655 (set_attr "i387_cw" "floor")
17656 (set_attr "mode" "<MODE>")])
17659 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17660 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17661 UNSPEC_FIST_FLOOR))
17662 (use (match_operand:HI 2 "memory_operand" ""))
17663 (use (match_operand:HI 3 "memory_operand" ""))
17664 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17666 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17667 UNSPEC_FIST_FLOOR))
17668 (use (match_dup 2))
17669 (use (match_dup 3))])
17670 (set (match_dup 0) (match_dup 4))]
17674 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17675 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17676 UNSPEC_FIST_FLOOR))
17677 (use (match_operand:HI 2 "memory_operand" ""))
17678 (use (match_operand:HI 3 "memory_operand" ""))
17679 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17681 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17682 UNSPEC_FIST_FLOOR))
17683 (use (match_dup 2))
17684 (use (match_dup 3))])]
17687 (define_expand "lfloorxf<mode>2"
17688 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17689 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17690 UNSPEC_FIST_FLOOR))
17691 (clobber (reg:CC FLAGS_REG))])]
17692 "TARGET_USE_FANCY_MATH_387
17693 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17694 && flag_unsafe_math_optimizations"
17697 (define_expand "lfloor<mode>di2"
17698 [(match_operand:DI 0 "nonimmediate_operand" "")
17699 (match_operand:SSEMODEF 1 "register_operand" "")]
17700 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17701 && !flag_trapping_math
17704 ix86_expand_lfloorceil (operand0, operand1, true);
17708 (define_expand "lfloor<mode>si2"
17709 [(match_operand:SI 0 "nonimmediate_operand" "")
17710 (match_operand:SSEMODEF 1 "register_operand" "")]
17711 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17712 && !flag_trapping_math
17713 && (!optimize_size || !TARGET_64BIT)"
17715 ix86_expand_lfloorceil (operand0, operand1, true);
17719 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17720 (define_insn_and_split "frndintxf2_ceil"
17721 [(set (match_operand:XF 0 "register_operand" "=f")
17722 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17723 UNSPEC_FRNDINT_CEIL))
17724 (clobber (reg:CC FLAGS_REG))]
17725 "TARGET_USE_FANCY_MATH_387
17726 && flag_unsafe_math_optimizations
17727 && !(reload_completed || reload_in_progress)"
17732 ix86_optimize_mode_switching[I387_CEIL] = 1;
17734 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17735 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17737 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17738 operands[2], operands[3]));
17741 [(set_attr "type" "frndint")
17742 (set_attr "i387_cw" "ceil")
17743 (set_attr "mode" "XF")])
17745 (define_insn "frndintxf2_ceil_i387"
17746 [(set (match_operand:XF 0 "register_operand" "=f")
17747 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17748 UNSPEC_FRNDINT_CEIL))
17749 (use (match_operand:HI 2 "memory_operand" "m"))
17750 (use (match_operand:HI 3 "memory_operand" "m"))]
17751 "TARGET_USE_FANCY_MATH_387
17752 && flag_unsafe_math_optimizations"
17753 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17754 [(set_attr "type" "frndint")
17755 (set_attr "i387_cw" "ceil")
17756 (set_attr "mode" "XF")])
17758 (define_expand "ceilxf2"
17759 [(use (match_operand:XF 0 "register_operand" ""))
17760 (use (match_operand:XF 1 "register_operand" ""))]
17761 "TARGET_USE_FANCY_MATH_387
17762 && flag_unsafe_math_optimizations && !optimize_size"
17764 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17768 (define_expand "ceildf2"
17769 [(use (match_operand:DF 0 "register_operand" ""))
17770 (use (match_operand:DF 1 "register_operand" ""))]
17771 "((TARGET_USE_FANCY_MATH_387
17772 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17773 && flag_unsafe_math_optimizations)
17774 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17775 && !flag_trapping_math))
17778 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17779 && !flag_trapping_math)
17782 ix86_expand_floorceil (operand0, operand1, false);
17784 ix86_expand_floorceildf_32 (operand0, operand1, false);
17788 rtx op0 = gen_reg_rtx (XFmode);
17789 rtx op1 = gen_reg_rtx (XFmode);
17791 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17792 emit_insn (gen_frndintxf2_ceil (op0, op1));
17794 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17799 (define_expand "ceilsf2"
17800 [(use (match_operand:SF 0 "register_operand" ""))
17801 (use (match_operand:SF 1 "register_operand" ""))]
17802 "((TARGET_USE_FANCY_MATH_387
17803 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17804 && flag_unsafe_math_optimizations)
17805 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17806 && !flag_trapping_math))
17809 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17810 && !flag_trapping_math)
17811 ix86_expand_floorceil (operand0, operand1, false);
17814 rtx op0 = gen_reg_rtx (XFmode);
17815 rtx op1 = gen_reg_rtx (XFmode);
17817 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17818 emit_insn (gen_frndintxf2_ceil (op0, op1));
17820 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17825 (define_insn_and_split "*fist<mode>2_ceil_1"
17826 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17827 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17829 (clobber (reg:CC FLAGS_REG))]
17830 "TARGET_USE_FANCY_MATH_387
17831 && flag_unsafe_math_optimizations
17832 && !(reload_completed || reload_in_progress)"
17837 ix86_optimize_mode_switching[I387_CEIL] = 1;
17839 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17840 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17841 if (memory_operand (operands[0], VOIDmode))
17842 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17843 operands[2], operands[3]));
17846 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17847 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17848 operands[2], operands[3],
17853 [(set_attr "type" "fistp")
17854 (set_attr "i387_cw" "ceil")
17855 (set_attr "mode" "<MODE>")])
17857 (define_insn "fistdi2_ceil"
17858 [(set (match_operand:DI 0 "memory_operand" "=m")
17859 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17861 (use (match_operand:HI 2 "memory_operand" "m"))
17862 (use (match_operand:HI 3 "memory_operand" "m"))
17863 (clobber (match_scratch:XF 4 "=&1f"))]
17864 "TARGET_USE_FANCY_MATH_387
17865 && flag_unsafe_math_optimizations"
17866 "* return output_fix_trunc (insn, operands, 0);"
17867 [(set_attr "type" "fistp")
17868 (set_attr "i387_cw" "ceil")
17869 (set_attr "mode" "DI")])
17871 (define_insn "fistdi2_ceil_with_temp"
17872 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17873 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17875 (use (match_operand:HI 2 "memory_operand" "m,m"))
17876 (use (match_operand:HI 3 "memory_operand" "m,m"))
17877 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17878 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17879 "TARGET_USE_FANCY_MATH_387
17880 && flag_unsafe_math_optimizations"
17882 [(set_attr "type" "fistp")
17883 (set_attr "i387_cw" "ceil")
17884 (set_attr "mode" "DI")])
17887 [(set (match_operand:DI 0 "register_operand" "")
17888 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17890 (use (match_operand:HI 2 "memory_operand" ""))
17891 (use (match_operand:HI 3 "memory_operand" ""))
17892 (clobber (match_operand:DI 4 "memory_operand" ""))
17893 (clobber (match_scratch 5 ""))]
17895 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17896 (use (match_dup 2))
17897 (use (match_dup 3))
17898 (clobber (match_dup 5))])
17899 (set (match_dup 0) (match_dup 4))]
17903 [(set (match_operand:DI 0 "memory_operand" "")
17904 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17906 (use (match_operand:HI 2 "memory_operand" ""))
17907 (use (match_operand:HI 3 "memory_operand" ""))
17908 (clobber (match_operand:DI 4 "memory_operand" ""))
17909 (clobber (match_scratch 5 ""))]
17911 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17912 (use (match_dup 2))
17913 (use (match_dup 3))
17914 (clobber (match_dup 5))])]
17917 (define_insn "fist<mode>2_ceil"
17918 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17919 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17921 (use (match_operand:HI 2 "memory_operand" "m"))
17922 (use (match_operand:HI 3 "memory_operand" "m"))]
17923 "TARGET_USE_FANCY_MATH_387
17924 && flag_unsafe_math_optimizations"
17925 "* return output_fix_trunc (insn, operands, 0);"
17926 [(set_attr "type" "fistp")
17927 (set_attr "i387_cw" "ceil")
17928 (set_attr "mode" "<MODE>")])
17930 (define_insn "fist<mode>2_ceil_with_temp"
17931 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17932 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17934 (use (match_operand:HI 2 "memory_operand" "m,m"))
17935 (use (match_operand:HI 3 "memory_operand" "m,m"))
17936 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17937 "TARGET_USE_FANCY_MATH_387
17938 && flag_unsafe_math_optimizations"
17940 [(set_attr "type" "fistp")
17941 (set_attr "i387_cw" "ceil")
17942 (set_attr "mode" "<MODE>")])
17945 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17946 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17948 (use (match_operand:HI 2 "memory_operand" ""))
17949 (use (match_operand:HI 3 "memory_operand" ""))
17950 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17952 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17954 (use (match_dup 2))
17955 (use (match_dup 3))])
17956 (set (match_dup 0) (match_dup 4))]
17960 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17961 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17963 (use (match_operand:HI 2 "memory_operand" ""))
17964 (use (match_operand:HI 3 "memory_operand" ""))
17965 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17967 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17969 (use (match_dup 2))
17970 (use (match_dup 3))])]
17973 (define_expand "lceilxf<mode>2"
17974 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17975 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17977 (clobber (reg:CC FLAGS_REG))])]
17978 "TARGET_USE_FANCY_MATH_387
17979 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17980 && flag_unsafe_math_optimizations"
17983 (define_expand "lceil<mode>di2"
17984 [(match_operand:DI 0 "nonimmediate_operand" "")
17985 (match_operand:SSEMODEF 1 "register_operand" "")]
17986 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17987 && !flag_trapping_math"
17989 ix86_expand_lfloorceil (operand0, operand1, false);
17993 (define_expand "lceil<mode>si2"
17994 [(match_operand:SI 0 "nonimmediate_operand" "")
17995 (match_operand:SSEMODEF 1 "register_operand" "")]
17996 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17997 && !flag_trapping_math"
17999 ix86_expand_lfloorceil (operand0, operand1, false);
18003 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18004 (define_insn_and_split "frndintxf2_trunc"
18005 [(set (match_operand:XF 0 "register_operand" "=f")
18006 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18007 UNSPEC_FRNDINT_TRUNC))
18008 (clobber (reg:CC FLAGS_REG))]
18009 "TARGET_USE_FANCY_MATH_387
18010 && flag_unsafe_math_optimizations
18011 && !(reload_completed || reload_in_progress)"
18016 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18018 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18019 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18021 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18022 operands[2], operands[3]));
18025 [(set_attr "type" "frndint")
18026 (set_attr "i387_cw" "trunc")
18027 (set_attr "mode" "XF")])
18029 (define_insn "frndintxf2_trunc_i387"
18030 [(set (match_operand:XF 0 "register_operand" "=f")
18031 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18032 UNSPEC_FRNDINT_TRUNC))
18033 (use (match_operand:HI 2 "memory_operand" "m"))
18034 (use (match_operand:HI 3 "memory_operand" "m"))]
18035 "TARGET_USE_FANCY_MATH_387
18036 && flag_unsafe_math_optimizations"
18037 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18038 [(set_attr "type" "frndint")
18039 (set_attr "i387_cw" "trunc")
18040 (set_attr "mode" "XF")])
18042 (define_expand "btruncxf2"
18043 [(use (match_operand:XF 0 "register_operand" ""))
18044 (use (match_operand:XF 1 "register_operand" ""))]
18045 "TARGET_USE_FANCY_MATH_387
18046 && flag_unsafe_math_optimizations && !optimize_size"
18048 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18052 (define_expand "btruncdf2"
18053 [(use (match_operand:DF 0 "register_operand" ""))
18054 (use (match_operand:DF 1 "register_operand" ""))]
18055 "((TARGET_USE_FANCY_MATH_387
18056 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18057 && flag_unsafe_math_optimizations)
18058 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18059 && !flag_trapping_math))
18062 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18063 && !flag_trapping_math)
18066 ix86_expand_trunc (operand0, operand1);
18068 ix86_expand_truncdf_32 (operand0, operand1);
18072 rtx op0 = gen_reg_rtx (XFmode);
18073 rtx op1 = gen_reg_rtx (XFmode);
18075 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18076 emit_insn (gen_frndintxf2_trunc (op0, op1));
18078 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18083 (define_expand "btruncsf2"
18084 [(use (match_operand:SF 0 "register_operand" ""))
18085 (use (match_operand:SF 1 "register_operand" ""))]
18086 "((TARGET_USE_FANCY_MATH_387
18087 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18088 && flag_unsafe_math_optimizations)
18089 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18090 && !flag_trapping_math))
18093 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18094 && !flag_trapping_math)
18095 ix86_expand_trunc (operand0, operand1);
18098 rtx op0 = gen_reg_rtx (XFmode);
18099 rtx op1 = gen_reg_rtx (XFmode);
18101 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18102 emit_insn (gen_frndintxf2_trunc (op0, op1));
18104 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18109 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18110 (define_insn_and_split "frndintxf2_mask_pm"
18111 [(set (match_operand:XF 0 "register_operand" "=f")
18112 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18113 UNSPEC_FRNDINT_MASK_PM))
18114 (clobber (reg:CC FLAGS_REG))]
18115 "TARGET_USE_FANCY_MATH_387
18116 && flag_unsafe_math_optimizations
18117 && !(reload_completed || reload_in_progress)"
18122 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18124 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18125 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18127 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18128 operands[2], operands[3]));
18131 [(set_attr "type" "frndint")
18132 (set_attr "i387_cw" "mask_pm")
18133 (set_attr "mode" "XF")])
18135 (define_insn "frndintxf2_mask_pm_i387"
18136 [(set (match_operand:XF 0 "register_operand" "=f")
18137 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18138 UNSPEC_FRNDINT_MASK_PM))
18139 (use (match_operand:HI 2 "memory_operand" "m"))
18140 (use (match_operand:HI 3 "memory_operand" "m"))]
18141 "TARGET_USE_FANCY_MATH_387
18142 && flag_unsafe_math_optimizations"
18143 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18144 [(set_attr "type" "frndint")
18145 (set_attr "i387_cw" "mask_pm")
18146 (set_attr "mode" "XF")])
18148 (define_expand "nearbyintxf2"
18149 [(use (match_operand:XF 0 "register_operand" ""))
18150 (use (match_operand:XF 1 "register_operand" ""))]
18151 "TARGET_USE_FANCY_MATH_387
18152 && flag_unsafe_math_optimizations"
18154 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18159 (define_expand "nearbyintdf2"
18160 [(use (match_operand:DF 0 "register_operand" ""))
18161 (use (match_operand:DF 1 "register_operand" ""))]
18162 "TARGET_USE_FANCY_MATH_387
18163 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18164 && flag_unsafe_math_optimizations"
18166 rtx op0 = gen_reg_rtx (XFmode);
18167 rtx op1 = gen_reg_rtx (XFmode);
18169 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18170 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18172 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18176 (define_expand "nearbyintsf2"
18177 [(use (match_operand:SF 0 "register_operand" ""))
18178 (use (match_operand:SF 1 "register_operand" ""))]
18179 "TARGET_USE_FANCY_MATH_387
18180 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18181 && flag_unsafe_math_optimizations"
18183 rtx op0 = gen_reg_rtx (XFmode);
18184 rtx op1 = gen_reg_rtx (XFmode);
18186 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18187 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18189 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18193 (define_insn "fxam<mode>2_i387"
18194 [(set (match_operand:HI 0 "register_operand" "=a")
18196 [(match_operand:X87MODEF 1 "register_operand" "f")]
18198 "TARGET_USE_FANCY_MATH_387"
18199 "fxam\n\tfnstsw\t%0"
18200 [(set_attr "type" "multi")
18201 (set_attr "unit" "i387")
18202 (set_attr "mode" "<MODE>")])
18204 (define_expand "isinf<mode>2"
18205 [(use (match_operand:SI 0 "register_operand" ""))
18206 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18207 "TARGET_USE_FANCY_MATH_387
18208 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18209 || TARGET_MIX_SSE_I387)"
18211 rtx mask = GEN_INT (0x45);
18212 rtx val = GEN_INT (0x05);
18216 rtx scratch = gen_reg_rtx (HImode);
18217 rtx res = gen_reg_rtx (QImode);
18219 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18220 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18221 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18222 cond = gen_rtx_fmt_ee (EQ, QImode,
18223 gen_rtx_REG (CCmode, FLAGS_REG),
18225 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18226 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18231 ;; Block operation instructions
18233 (define_expand "movmemsi"
18234 [(use (match_operand:BLK 0 "memory_operand" ""))
18235 (use (match_operand:BLK 1 "memory_operand" ""))
18236 (use (match_operand:SI 2 "nonmemory_operand" ""))
18237 (use (match_operand:SI 3 "const_int_operand" ""))
18238 (use (match_operand:SI 4 "const_int_operand" ""))
18239 (use (match_operand:SI 5 "const_int_operand" ""))]
18242 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18243 operands[4], operands[5]))
18249 (define_expand "movmemdi"
18250 [(use (match_operand:BLK 0 "memory_operand" ""))
18251 (use (match_operand:BLK 1 "memory_operand" ""))
18252 (use (match_operand:DI 2 "nonmemory_operand" ""))
18253 (use (match_operand:DI 3 "const_int_operand" ""))
18254 (use (match_operand:SI 4 "const_int_operand" ""))
18255 (use (match_operand:SI 5 "const_int_operand" ""))]
18258 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18259 operands[4], operands[5]))
18265 ;; Most CPUs don't like single string operations
18266 ;; Handle this case here to simplify previous expander.
18268 (define_expand "strmov"
18269 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18270 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18271 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18272 (clobber (reg:CC FLAGS_REG))])
18273 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18274 (clobber (reg:CC FLAGS_REG))])]
18277 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18279 /* If .md ever supports :P for Pmode, these can be directly
18280 in the pattern above. */
18281 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18282 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18284 if (TARGET_SINGLE_STRINGOP || optimize_size)
18286 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18287 operands[2], operands[3],
18288 operands[5], operands[6]));
18292 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18295 (define_expand "strmov_singleop"
18296 [(parallel [(set (match_operand 1 "memory_operand" "")
18297 (match_operand 3 "memory_operand" ""))
18298 (set (match_operand 0 "register_operand" "")
18299 (match_operand 4 "" ""))
18300 (set (match_operand 2 "register_operand" "")
18301 (match_operand 5 "" ""))])]
18302 "TARGET_SINGLE_STRINGOP || optimize_size"
18305 (define_insn "*strmovdi_rex_1"
18306 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18307 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18308 (set (match_operand:DI 0 "register_operand" "=D")
18309 (plus:DI (match_dup 2)
18311 (set (match_operand:DI 1 "register_operand" "=S")
18312 (plus:DI (match_dup 3)
18314 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18316 [(set_attr "type" "str")
18317 (set_attr "mode" "DI")
18318 (set_attr "memory" "both")])
18320 (define_insn "*strmovsi_1"
18321 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18322 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18323 (set (match_operand:SI 0 "register_operand" "=D")
18324 (plus:SI (match_dup 2)
18326 (set (match_operand:SI 1 "register_operand" "=S")
18327 (plus:SI (match_dup 3)
18329 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18331 [(set_attr "type" "str")
18332 (set_attr "mode" "SI")
18333 (set_attr "memory" "both")])
18335 (define_insn "*strmovsi_rex_1"
18336 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18337 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18338 (set (match_operand:DI 0 "register_operand" "=D")
18339 (plus:DI (match_dup 2)
18341 (set (match_operand:DI 1 "register_operand" "=S")
18342 (plus:DI (match_dup 3)
18344 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18346 [(set_attr "type" "str")
18347 (set_attr "mode" "SI")
18348 (set_attr "memory" "both")])
18350 (define_insn "*strmovhi_1"
18351 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18352 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18353 (set (match_operand:SI 0 "register_operand" "=D")
18354 (plus:SI (match_dup 2)
18356 (set (match_operand:SI 1 "register_operand" "=S")
18357 (plus:SI (match_dup 3)
18359 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18361 [(set_attr "type" "str")
18362 (set_attr "memory" "both")
18363 (set_attr "mode" "HI")])
18365 (define_insn "*strmovhi_rex_1"
18366 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18367 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18368 (set (match_operand:DI 0 "register_operand" "=D")
18369 (plus:DI (match_dup 2)
18371 (set (match_operand:DI 1 "register_operand" "=S")
18372 (plus:DI (match_dup 3)
18374 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18376 [(set_attr "type" "str")
18377 (set_attr "memory" "both")
18378 (set_attr "mode" "HI")])
18380 (define_insn "*strmovqi_1"
18381 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18382 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18383 (set (match_operand:SI 0 "register_operand" "=D")
18384 (plus:SI (match_dup 2)
18386 (set (match_operand:SI 1 "register_operand" "=S")
18387 (plus:SI (match_dup 3)
18389 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18391 [(set_attr "type" "str")
18392 (set_attr "memory" "both")
18393 (set_attr "mode" "QI")])
18395 (define_insn "*strmovqi_rex_1"
18396 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18397 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18398 (set (match_operand:DI 0 "register_operand" "=D")
18399 (plus:DI (match_dup 2)
18401 (set (match_operand:DI 1 "register_operand" "=S")
18402 (plus:DI (match_dup 3)
18404 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18406 [(set_attr "type" "str")
18407 (set_attr "memory" "both")
18408 (set_attr "mode" "QI")])
18410 (define_expand "rep_mov"
18411 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18412 (set (match_operand 0 "register_operand" "")
18413 (match_operand 5 "" ""))
18414 (set (match_operand 2 "register_operand" "")
18415 (match_operand 6 "" ""))
18416 (set (match_operand 1 "memory_operand" "")
18417 (match_operand 3 "memory_operand" ""))
18418 (use (match_dup 4))])]
18422 (define_insn "*rep_movdi_rex64"
18423 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18424 (set (match_operand:DI 0 "register_operand" "=D")
18425 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18427 (match_operand:DI 3 "register_operand" "0")))
18428 (set (match_operand:DI 1 "register_operand" "=S")
18429 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18430 (match_operand:DI 4 "register_operand" "1")))
18431 (set (mem:BLK (match_dup 3))
18432 (mem:BLK (match_dup 4)))
18433 (use (match_dup 5))]
18435 "{rep\;movsq|rep movsq}"
18436 [(set_attr "type" "str")
18437 (set_attr "prefix_rep" "1")
18438 (set_attr "memory" "both")
18439 (set_attr "mode" "DI")])
18441 (define_insn "*rep_movsi"
18442 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18443 (set (match_operand:SI 0 "register_operand" "=D")
18444 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18446 (match_operand:SI 3 "register_operand" "0")))
18447 (set (match_operand:SI 1 "register_operand" "=S")
18448 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18449 (match_operand:SI 4 "register_operand" "1")))
18450 (set (mem:BLK (match_dup 3))
18451 (mem:BLK (match_dup 4)))
18452 (use (match_dup 5))]
18454 "{rep\;movsl|rep movsd}"
18455 [(set_attr "type" "str")
18456 (set_attr "prefix_rep" "1")
18457 (set_attr "memory" "both")
18458 (set_attr "mode" "SI")])
18460 (define_insn "*rep_movsi_rex64"
18461 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18462 (set (match_operand:DI 0 "register_operand" "=D")
18463 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18465 (match_operand:DI 3 "register_operand" "0")))
18466 (set (match_operand:DI 1 "register_operand" "=S")
18467 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18468 (match_operand:DI 4 "register_operand" "1")))
18469 (set (mem:BLK (match_dup 3))
18470 (mem:BLK (match_dup 4)))
18471 (use (match_dup 5))]
18473 "{rep\;movsl|rep movsd}"
18474 [(set_attr "type" "str")
18475 (set_attr "prefix_rep" "1")
18476 (set_attr "memory" "both")
18477 (set_attr "mode" "SI")])
18479 (define_insn "*rep_movqi"
18480 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18481 (set (match_operand:SI 0 "register_operand" "=D")
18482 (plus:SI (match_operand:SI 3 "register_operand" "0")
18483 (match_operand:SI 5 "register_operand" "2")))
18484 (set (match_operand:SI 1 "register_operand" "=S")
18485 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18486 (set (mem:BLK (match_dup 3))
18487 (mem:BLK (match_dup 4)))
18488 (use (match_dup 5))]
18490 "{rep\;movsb|rep movsb}"
18491 [(set_attr "type" "str")
18492 (set_attr "prefix_rep" "1")
18493 (set_attr "memory" "both")
18494 (set_attr "mode" "SI")])
18496 (define_insn "*rep_movqi_rex64"
18497 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18498 (set (match_operand:DI 0 "register_operand" "=D")
18499 (plus:DI (match_operand:DI 3 "register_operand" "0")
18500 (match_operand:DI 5 "register_operand" "2")))
18501 (set (match_operand:DI 1 "register_operand" "=S")
18502 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18503 (set (mem:BLK (match_dup 3))
18504 (mem:BLK (match_dup 4)))
18505 (use (match_dup 5))]
18507 "{rep\;movsb|rep movsb}"
18508 [(set_attr "type" "str")
18509 (set_attr "prefix_rep" "1")
18510 (set_attr "memory" "both")
18511 (set_attr "mode" "SI")])
18513 (define_expand "setmemsi"
18514 [(use (match_operand:BLK 0 "memory_operand" ""))
18515 (use (match_operand:SI 1 "nonmemory_operand" ""))
18516 (use (match_operand 2 "const_int_operand" ""))
18517 (use (match_operand 3 "const_int_operand" ""))
18518 (use (match_operand:SI 4 "const_int_operand" ""))
18519 (use (match_operand:SI 5 "const_int_operand" ""))]
18522 if (ix86_expand_setmem (operands[0], operands[1],
18523 operands[2], operands[3],
18524 operands[4], operands[5]))
18530 (define_expand "setmemdi"
18531 [(use (match_operand:BLK 0 "memory_operand" ""))
18532 (use (match_operand:DI 1 "nonmemory_operand" ""))
18533 (use (match_operand 2 "const_int_operand" ""))
18534 (use (match_operand 3 "const_int_operand" ""))
18535 (use (match_operand 4 "const_int_operand" ""))
18536 (use (match_operand 5 "const_int_operand" ""))]
18539 if (ix86_expand_setmem (operands[0], operands[1],
18540 operands[2], operands[3],
18541 operands[4], operands[5]))
18547 ;; Most CPUs don't like single string operations
18548 ;; Handle this case here to simplify previous expander.
18550 (define_expand "strset"
18551 [(set (match_operand 1 "memory_operand" "")
18552 (match_operand 2 "register_operand" ""))
18553 (parallel [(set (match_operand 0 "register_operand" "")
18555 (clobber (reg:CC FLAGS_REG))])]
18558 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18559 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18561 /* If .md ever supports :P for Pmode, this can be directly
18562 in the pattern above. */
18563 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18564 GEN_INT (GET_MODE_SIZE (GET_MODE
18566 if (TARGET_SINGLE_STRINGOP || optimize_size)
18568 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18574 (define_expand "strset_singleop"
18575 [(parallel [(set (match_operand 1 "memory_operand" "")
18576 (match_operand 2 "register_operand" ""))
18577 (set (match_operand 0 "register_operand" "")
18578 (match_operand 3 "" ""))])]
18579 "TARGET_SINGLE_STRINGOP || optimize_size"
18582 (define_insn "*strsetdi_rex_1"
18583 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18584 (match_operand:DI 2 "register_operand" "a"))
18585 (set (match_operand:DI 0 "register_operand" "=D")
18586 (plus:DI (match_dup 1)
18588 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18590 [(set_attr "type" "str")
18591 (set_attr "memory" "store")
18592 (set_attr "mode" "DI")])
18594 (define_insn "*strsetsi_1"
18595 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18596 (match_operand:SI 2 "register_operand" "a"))
18597 (set (match_operand:SI 0 "register_operand" "=D")
18598 (plus:SI (match_dup 1)
18600 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18602 [(set_attr "type" "str")
18603 (set_attr "memory" "store")
18604 (set_attr "mode" "SI")])
18606 (define_insn "*strsetsi_rex_1"
18607 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18608 (match_operand:SI 2 "register_operand" "a"))
18609 (set (match_operand:DI 0 "register_operand" "=D")
18610 (plus:DI (match_dup 1)
18612 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18614 [(set_attr "type" "str")
18615 (set_attr "memory" "store")
18616 (set_attr "mode" "SI")])
18618 (define_insn "*strsethi_1"
18619 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18620 (match_operand:HI 2 "register_operand" "a"))
18621 (set (match_operand:SI 0 "register_operand" "=D")
18622 (plus:SI (match_dup 1)
18624 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18626 [(set_attr "type" "str")
18627 (set_attr "memory" "store")
18628 (set_attr "mode" "HI")])
18630 (define_insn "*strsethi_rex_1"
18631 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18632 (match_operand:HI 2 "register_operand" "a"))
18633 (set (match_operand:DI 0 "register_operand" "=D")
18634 (plus:DI (match_dup 1)
18636 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18638 [(set_attr "type" "str")
18639 (set_attr "memory" "store")
18640 (set_attr "mode" "HI")])
18642 (define_insn "*strsetqi_1"
18643 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18644 (match_operand:QI 2 "register_operand" "a"))
18645 (set (match_operand:SI 0 "register_operand" "=D")
18646 (plus:SI (match_dup 1)
18648 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18650 [(set_attr "type" "str")
18651 (set_attr "memory" "store")
18652 (set_attr "mode" "QI")])
18654 (define_insn "*strsetqi_rex_1"
18655 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18656 (match_operand:QI 2 "register_operand" "a"))
18657 (set (match_operand:DI 0 "register_operand" "=D")
18658 (plus:DI (match_dup 1)
18660 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18662 [(set_attr "type" "str")
18663 (set_attr "memory" "store")
18664 (set_attr "mode" "QI")])
18666 (define_expand "rep_stos"
18667 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18668 (set (match_operand 0 "register_operand" "")
18669 (match_operand 4 "" ""))
18670 (set (match_operand 2 "memory_operand" "") (const_int 0))
18671 (use (match_operand 3 "register_operand" ""))
18672 (use (match_dup 1))])]
18676 (define_insn "*rep_stosdi_rex64"
18677 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18678 (set (match_operand:DI 0 "register_operand" "=D")
18679 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18681 (match_operand:DI 3 "register_operand" "0")))
18682 (set (mem:BLK (match_dup 3))
18684 (use (match_operand:DI 2 "register_operand" "a"))
18685 (use (match_dup 4))]
18687 "{rep\;stosq|rep stosq}"
18688 [(set_attr "type" "str")
18689 (set_attr "prefix_rep" "1")
18690 (set_attr "memory" "store")
18691 (set_attr "mode" "DI")])
18693 (define_insn "*rep_stossi"
18694 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18695 (set (match_operand:SI 0 "register_operand" "=D")
18696 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18698 (match_operand:SI 3 "register_operand" "0")))
18699 (set (mem:BLK (match_dup 3))
18701 (use (match_operand:SI 2 "register_operand" "a"))
18702 (use (match_dup 4))]
18704 "{rep\;stosl|rep stosd}"
18705 [(set_attr "type" "str")
18706 (set_attr "prefix_rep" "1")
18707 (set_attr "memory" "store")
18708 (set_attr "mode" "SI")])
18710 (define_insn "*rep_stossi_rex64"
18711 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18712 (set (match_operand:DI 0 "register_operand" "=D")
18713 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18715 (match_operand:DI 3 "register_operand" "0")))
18716 (set (mem:BLK (match_dup 3))
18718 (use (match_operand:SI 2 "register_operand" "a"))
18719 (use (match_dup 4))]
18721 "{rep\;stosl|rep stosd}"
18722 [(set_attr "type" "str")
18723 (set_attr "prefix_rep" "1")
18724 (set_attr "memory" "store")
18725 (set_attr "mode" "SI")])
18727 (define_insn "*rep_stosqi"
18728 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18729 (set (match_operand:SI 0 "register_operand" "=D")
18730 (plus:SI (match_operand:SI 3 "register_operand" "0")
18731 (match_operand:SI 4 "register_operand" "1")))
18732 (set (mem:BLK (match_dup 3))
18734 (use (match_operand:QI 2 "register_operand" "a"))
18735 (use (match_dup 4))]
18737 "{rep\;stosb|rep stosb}"
18738 [(set_attr "type" "str")
18739 (set_attr "prefix_rep" "1")
18740 (set_attr "memory" "store")
18741 (set_attr "mode" "QI")])
18743 (define_insn "*rep_stosqi_rex64"
18744 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18745 (set (match_operand:DI 0 "register_operand" "=D")
18746 (plus:DI (match_operand:DI 3 "register_operand" "0")
18747 (match_operand:DI 4 "register_operand" "1")))
18748 (set (mem:BLK (match_dup 3))
18750 (use (match_operand:QI 2 "register_operand" "a"))
18751 (use (match_dup 4))]
18753 "{rep\;stosb|rep stosb}"
18754 [(set_attr "type" "str")
18755 (set_attr "prefix_rep" "1")
18756 (set_attr "memory" "store")
18757 (set_attr "mode" "QI")])
18759 (define_expand "cmpstrnsi"
18760 [(set (match_operand:SI 0 "register_operand" "")
18761 (compare:SI (match_operand:BLK 1 "general_operand" "")
18762 (match_operand:BLK 2 "general_operand" "")))
18763 (use (match_operand 3 "general_operand" ""))
18764 (use (match_operand 4 "immediate_operand" ""))]
18765 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18767 rtx addr1, addr2, out, outlow, count, countreg, align;
18769 /* Can't use this if the user has appropriated esi or edi. */
18770 if (global_regs[4] || global_regs[5])
18775 out = gen_reg_rtx (SImode);
18777 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18778 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18779 if (addr1 != XEXP (operands[1], 0))
18780 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18781 if (addr2 != XEXP (operands[2], 0))
18782 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18784 count = operands[3];
18785 countreg = ix86_zero_extend_to_Pmode (count);
18787 /* %%% Iff we are testing strict equality, we can use known alignment
18788 to good advantage. This may be possible with combine, particularly
18789 once cc0 is dead. */
18790 align = operands[4];
18792 if (CONST_INT_P (count))
18794 if (INTVAL (count) == 0)
18796 emit_move_insn (operands[0], const0_rtx);
18799 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18800 operands[1], operands[2]));
18805 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18807 emit_insn (gen_cmpsi_1 (countreg, countreg));
18808 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18809 operands[1], operands[2]));
18812 outlow = gen_lowpart (QImode, out);
18813 emit_insn (gen_cmpintqi (outlow));
18814 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18816 if (operands[0] != out)
18817 emit_move_insn (operands[0], out);
18822 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18824 (define_expand "cmpintqi"
18825 [(set (match_dup 1)
18826 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18828 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18829 (parallel [(set (match_operand:QI 0 "register_operand" "")
18830 (minus:QI (match_dup 1)
18832 (clobber (reg:CC FLAGS_REG))])]
18834 "operands[1] = gen_reg_rtx (QImode);
18835 operands[2] = gen_reg_rtx (QImode);")
18837 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18838 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18840 (define_expand "cmpstrnqi_nz_1"
18841 [(parallel [(set (reg:CC FLAGS_REG)
18842 (compare:CC (match_operand 4 "memory_operand" "")
18843 (match_operand 5 "memory_operand" "")))
18844 (use (match_operand 2 "register_operand" ""))
18845 (use (match_operand:SI 3 "immediate_operand" ""))
18846 (clobber (match_operand 0 "register_operand" ""))
18847 (clobber (match_operand 1 "register_operand" ""))
18848 (clobber (match_dup 2))])]
18852 (define_insn "*cmpstrnqi_nz_1"
18853 [(set (reg:CC FLAGS_REG)
18854 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18855 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18856 (use (match_operand:SI 6 "register_operand" "2"))
18857 (use (match_operand:SI 3 "immediate_operand" "i"))
18858 (clobber (match_operand:SI 0 "register_operand" "=S"))
18859 (clobber (match_operand:SI 1 "register_operand" "=D"))
18860 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18863 [(set_attr "type" "str")
18864 (set_attr "mode" "QI")
18865 (set_attr "prefix_rep" "1")])
18867 (define_insn "*cmpstrnqi_nz_rex_1"
18868 [(set (reg:CC FLAGS_REG)
18869 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18870 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18871 (use (match_operand:DI 6 "register_operand" "2"))
18872 (use (match_operand:SI 3 "immediate_operand" "i"))
18873 (clobber (match_operand:DI 0 "register_operand" "=S"))
18874 (clobber (match_operand:DI 1 "register_operand" "=D"))
18875 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18878 [(set_attr "type" "str")
18879 (set_attr "mode" "QI")
18880 (set_attr "prefix_rep" "1")])
18882 ;; The same, but the count is not known to not be zero.
18884 (define_expand "cmpstrnqi_1"
18885 [(parallel [(set (reg:CC FLAGS_REG)
18886 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18888 (compare:CC (match_operand 4 "memory_operand" "")
18889 (match_operand 5 "memory_operand" ""))
18891 (use (match_operand:SI 3 "immediate_operand" ""))
18892 (use (reg:CC FLAGS_REG))
18893 (clobber (match_operand 0 "register_operand" ""))
18894 (clobber (match_operand 1 "register_operand" ""))
18895 (clobber (match_dup 2))])]
18899 (define_insn "*cmpstrnqi_1"
18900 [(set (reg:CC FLAGS_REG)
18901 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18903 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18904 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18906 (use (match_operand:SI 3 "immediate_operand" "i"))
18907 (use (reg:CC FLAGS_REG))
18908 (clobber (match_operand:SI 0 "register_operand" "=S"))
18909 (clobber (match_operand:SI 1 "register_operand" "=D"))
18910 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18913 [(set_attr "type" "str")
18914 (set_attr "mode" "QI")
18915 (set_attr "prefix_rep" "1")])
18917 (define_insn "*cmpstrnqi_rex_1"
18918 [(set (reg:CC FLAGS_REG)
18919 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18921 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18922 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18924 (use (match_operand:SI 3 "immediate_operand" "i"))
18925 (use (reg:CC FLAGS_REG))
18926 (clobber (match_operand:DI 0 "register_operand" "=S"))
18927 (clobber (match_operand:DI 1 "register_operand" "=D"))
18928 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18931 [(set_attr "type" "str")
18932 (set_attr "mode" "QI")
18933 (set_attr "prefix_rep" "1")])
18935 (define_expand "strlensi"
18936 [(set (match_operand:SI 0 "register_operand" "")
18937 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18938 (match_operand:QI 2 "immediate_operand" "")
18939 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18942 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18948 (define_expand "strlendi"
18949 [(set (match_operand:DI 0 "register_operand" "")
18950 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18951 (match_operand:QI 2 "immediate_operand" "")
18952 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18955 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18961 (define_expand "strlenqi_1"
18962 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18963 (clobber (match_operand 1 "register_operand" ""))
18964 (clobber (reg:CC FLAGS_REG))])]
18968 (define_insn "*strlenqi_1"
18969 [(set (match_operand:SI 0 "register_operand" "=&c")
18970 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18971 (match_operand:QI 2 "register_operand" "a")
18972 (match_operand:SI 3 "immediate_operand" "i")
18973 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18974 (clobber (match_operand:SI 1 "register_operand" "=D"))
18975 (clobber (reg:CC FLAGS_REG))]
18978 [(set_attr "type" "str")
18979 (set_attr "mode" "QI")
18980 (set_attr "prefix_rep" "1")])
18982 (define_insn "*strlenqi_rex_1"
18983 [(set (match_operand:DI 0 "register_operand" "=&c")
18984 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18985 (match_operand:QI 2 "register_operand" "a")
18986 (match_operand:DI 3 "immediate_operand" "i")
18987 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18988 (clobber (match_operand:DI 1 "register_operand" "=D"))
18989 (clobber (reg:CC FLAGS_REG))]
18992 [(set_attr "type" "str")
18993 (set_attr "mode" "QI")
18994 (set_attr "prefix_rep" "1")])
18996 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18997 ;; handled in combine, but it is not currently up to the task.
18998 ;; When used for their truth value, the cmpstrn* expanders generate
19007 ;; The intermediate three instructions are unnecessary.
19009 ;; This one handles cmpstrn*_nz_1...
19012 (set (reg:CC FLAGS_REG)
19013 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19014 (mem:BLK (match_operand 5 "register_operand" ""))))
19015 (use (match_operand 6 "register_operand" ""))
19016 (use (match_operand:SI 3 "immediate_operand" ""))
19017 (clobber (match_operand 0 "register_operand" ""))
19018 (clobber (match_operand 1 "register_operand" ""))
19019 (clobber (match_operand 2 "register_operand" ""))])
19020 (set (match_operand:QI 7 "register_operand" "")
19021 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19022 (set (match_operand:QI 8 "register_operand" "")
19023 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19024 (set (reg FLAGS_REG)
19025 (compare (match_dup 7) (match_dup 8)))
19027 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19029 (set (reg:CC FLAGS_REG)
19030 (compare:CC (mem:BLK (match_dup 4))
19031 (mem:BLK (match_dup 5))))
19032 (use (match_dup 6))
19033 (use (match_dup 3))
19034 (clobber (match_dup 0))
19035 (clobber (match_dup 1))
19036 (clobber (match_dup 2))])]
19039 ;; ...and this one handles cmpstrn*_1.
19042 (set (reg:CC FLAGS_REG)
19043 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19045 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19046 (mem:BLK (match_operand 5 "register_operand" "")))
19048 (use (match_operand:SI 3 "immediate_operand" ""))
19049 (use (reg:CC FLAGS_REG))
19050 (clobber (match_operand 0 "register_operand" ""))
19051 (clobber (match_operand 1 "register_operand" ""))
19052 (clobber (match_operand 2 "register_operand" ""))])
19053 (set (match_operand:QI 7 "register_operand" "")
19054 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19055 (set (match_operand:QI 8 "register_operand" "")
19056 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19057 (set (reg FLAGS_REG)
19058 (compare (match_dup 7) (match_dup 8)))
19060 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19062 (set (reg:CC FLAGS_REG)
19063 (if_then_else:CC (ne (match_dup 6)
19065 (compare:CC (mem:BLK (match_dup 4))
19066 (mem:BLK (match_dup 5)))
19068 (use (match_dup 3))
19069 (use (reg:CC FLAGS_REG))
19070 (clobber (match_dup 0))
19071 (clobber (match_dup 1))
19072 (clobber (match_dup 2))])]
19077 ;; Conditional move instructions.
19079 (define_expand "movdicc"
19080 [(set (match_operand:DI 0 "register_operand" "")
19081 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19082 (match_operand:DI 2 "general_operand" "")
19083 (match_operand:DI 3 "general_operand" "")))]
19085 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19087 (define_insn "x86_movdicc_0_m1_rex64"
19088 [(set (match_operand:DI 0 "register_operand" "=r")
19089 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19092 (clobber (reg:CC FLAGS_REG))]
19095 ; Since we don't have the proper number of operands for an alu insn,
19096 ; fill in all the blanks.
19097 [(set_attr "type" "alu")
19098 (set_attr "pent_pair" "pu")
19099 (set_attr "memory" "none")
19100 (set_attr "imm_disp" "false")
19101 (set_attr "mode" "DI")
19102 (set_attr "length_immediate" "0")])
19104 (define_insn "*movdicc_c_rex64"
19105 [(set (match_operand:DI 0 "register_operand" "=r,r")
19106 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19107 [(reg FLAGS_REG) (const_int 0)])
19108 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19109 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19110 "TARGET_64BIT && TARGET_CMOVE
19111 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19113 cmov%O2%C1\t{%2, %0|%0, %2}
19114 cmov%O2%c1\t{%3, %0|%0, %3}"
19115 [(set_attr "type" "icmov")
19116 (set_attr "mode" "DI")])
19118 (define_expand "movsicc"
19119 [(set (match_operand:SI 0 "register_operand" "")
19120 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19121 (match_operand:SI 2 "general_operand" "")
19122 (match_operand:SI 3 "general_operand" "")))]
19124 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19126 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19127 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19128 ;; So just document what we're doing explicitly.
19130 (define_insn "x86_movsicc_0_m1"
19131 [(set (match_operand:SI 0 "register_operand" "=r")
19132 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19135 (clobber (reg:CC FLAGS_REG))]
19138 ; Since we don't have the proper number of operands for an alu insn,
19139 ; fill in all the blanks.
19140 [(set_attr "type" "alu")
19141 (set_attr "pent_pair" "pu")
19142 (set_attr "memory" "none")
19143 (set_attr "imm_disp" "false")
19144 (set_attr "mode" "SI")
19145 (set_attr "length_immediate" "0")])
19147 (define_insn "*movsicc_noc"
19148 [(set (match_operand:SI 0 "register_operand" "=r,r")
19149 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19150 [(reg FLAGS_REG) (const_int 0)])
19151 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19152 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19154 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19156 cmov%O2%C1\t{%2, %0|%0, %2}
19157 cmov%O2%c1\t{%3, %0|%0, %3}"
19158 [(set_attr "type" "icmov")
19159 (set_attr "mode" "SI")])
19161 (define_expand "movhicc"
19162 [(set (match_operand:HI 0 "register_operand" "")
19163 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19164 (match_operand:HI 2 "general_operand" "")
19165 (match_operand:HI 3 "general_operand" "")))]
19166 "TARGET_HIMODE_MATH"
19167 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19169 (define_insn "*movhicc_noc"
19170 [(set (match_operand:HI 0 "register_operand" "=r,r")
19171 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19172 [(reg FLAGS_REG) (const_int 0)])
19173 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19174 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19176 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19178 cmov%O2%C1\t{%2, %0|%0, %2}
19179 cmov%O2%c1\t{%3, %0|%0, %3}"
19180 [(set_attr "type" "icmov")
19181 (set_attr "mode" "HI")])
19183 (define_expand "movqicc"
19184 [(set (match_operand:QI 0 "register_operand" "")
19185 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19186 (match_operand:QI 2 "general_operand" "")
19187 (match_operand:QI 3 "general_operand" "")))]
19188 "TARGET_QIMODE_MATH"
19189 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19191 (define_insn_and_split "*movqicc_noc"
19192 [(set (match_operand:QI 0 "register_operand" "=r,r")
19193 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19194 [(match_operand 4 "flags_reg_operand" "")
19196 (match_operand:QI 2 "register_operand" "r,0")
19197 (match_operand:QI 3 "register_operand" "0,r")))]
19198 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19200 "&& reload_completed"
19201 [(set (match_dup 0)
19202 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19205 "operands[0] = gen_lowpart (SImode, operands[0]);
19206 operands[2] = gen_lowpart (SImode, operands[2]);
19207 operands[3] = gen_lowpart (SImode, operands[3]);"
19208 [(set_attr "type" "icmov")
19209 (set_attr "mode" "SI")])
19211 (define_expand "movsfcc"
19212 [(set (match_operand:SF 0 "register_operand" "")
19213 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19214 (match_operand:SF 2 "register_operand" "")
19215 (match_operand:SF 3 "register_operand" "")))]
19216 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19217 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19219 (define_insn "*movsfcc_1_387"
19220 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19221 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19222 [(reg FLAGS_REG) (const_int 0)])
19223 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19224 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19225 "TARGET_80387 && TARGET_CMOVE
19226 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19228 fcmov%F1\t{%2, %0|%0, %2}
19229 fcmov%f1\t{%3, %0|%0, %3}
19230 cmov%O2%C1\t{%2, %0|%0, %2}
19231 cmov%O2%c1\t{%3, %0|%0, %3}"
19232 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19233 (set_attr "mode" "SF,SF,SI,SI")])
19235 (define_expand "movdfcc"
19236 [(set (match_operand:DF 0 "register_operand" "")
19237 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19238 (match_operand:DF 2 "register_operand" "")
19239 (match_operand:DF 3 "register_operand" "")))]
19240 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19241 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19243 (define_insn "*movdfcc_1"
19244 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19245 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19246 [(reg FLAGS_REG) (const_int 0)])
19247 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19248 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19249 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19250 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19252 fcmov%F1\t{%2, %0|%0, %2}
19253 fcmov%f1\t{%3, %0|%0, %3}
19256 [(set_attr "type" "fcmov,fcmov,multi,multi")
19257 (set_attr "mode" "DF")])
19259 (define_insn "*movdfcc_1_rex64"
19260 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19261 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19262 [(reg FLAGS_REG) (const_int 0)])
19263 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19264 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19265 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19266 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19268 fcmov%F1\t{%2, %0|%0, %2}
19269 fcmov%f1\t{%3, %0|%0, %3}
19270 cmov%O2%C1\t{%2, %0|%0, %2}
19271 cmov%O2%c1\t{%3, %0|%0, %3}"
19272 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19273 (set_attr "mode" "DF")])
19276 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19277 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19278 [(match_operand 4 "flags_reg_operand" "")
19280 (match_operand:DF 2 "nonimmediate_operand" "")
19281 (match_operand:DF 3 "nonimmediate_operand" "")))]
19282 "!TARGET_64BIT && reload_completed"
19283 [(set (match_dup 2)
19284 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19288 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19291 "split_di (operands+2, 1, operands+5, operands+6);
19292 split_di (operands+3, 1, operands+7, operands+8);
19293 split_di (operands, 1, operands+2, operands+3);")
19295 (define_expand "movxfcc"
19296 [(set (match_operand:XF 0 "register_operand" "")
19297 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19298 (match_operand:XF 2 "register_operand" "")
19299 (match_operand:XF 3 "register_operand" "")))]
19300 "TARGET_80387 && TARGET_CMOVE"
19301 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19303 (define_insn "*movxfcc_1"
19304 [(set (match_operand:XF 0 "register_operand" "=f,f")
19305 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19306 [(reg FLAGS_REG) (const_int 0)])
19307 (match_operand:XF 2 "register_operand" "f,0")
19308 (match_operand:XF 3 "register_operand" "0,f")))]
19309 "TARGET_80387 && TARGET_CMOVE"
19311 fcmov%F1\t{%2, %0|%0, %2}
19312 fcmov%f1\t{%3, %0|%0, %3}"
19313 [(set_attr "type" "fcmov")
19314 (set_attr "mode" "XF")])
19316 ;; These versions of the min/max patterns are intentionally ignorant of
19317 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19318 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19319 ;; are undefined in this condition, we're certain this is correct.
19321 (define_insn "sminsf3"
19322 [(set (match_operand:SF 0 "register_operand" "=x")
19323 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19324 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19326 "minss\t{%2, %0|%0, %2}"
19327 [(set_attr "type" "sseadd")
19328 (set_attr "mode" "SF")])
19330 (define_insn "smaxsf3"
19331 [(set (match_operand:SF 0 "register_operand" "=x")
19332 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19333 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19335 "maxss\t{%2, %0|%0, %2}"
19336 [(set_attr "type" "sseadd")
19337 (set_attr "mode" "SF")])
19339 (define_insn "smindf3"
19340 [(set (match_operand:DF 0 "register_operand" "=x")
19341 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19342 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19343 "TARGET_SSE2 && TARGET_SSE_MATH"
19344 "minsd\t{%2, %0|%0, %2}"
19345 [(set_attr "type" "sseadd")
19346 (set_attr "mode" "DF")])
19348 (define_insn "smaxdf3"
19349 [(set (match_operand:DF 0 "register_operand" "=x")
19350 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19351 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19352 "TARGET_SSE2 && TARGET_SSE_MATH"
19353 "maxsd\t{%2, %0|%0, %2}"
19354 [(set_attr "type" "sseadd")
19355 (set_attr "mode" "DF")])
19357 ;; These versions of the min/max patterns implement exactly the operations
19358 ;; min = (op1 < op2 ? op1 : op2)
19359 ;; max = (!(op1 < op2) ? op1 : op2)
19360 ;; Their operands are not commutative, and thus they may be used in the
19361 ;; presence of -0.0 and NaN.
19363 (define_insn "*ieee_sminsf3"
19364 [(set (match_operand:SF 0 "register_operand" "=x")
19365 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19366 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19369 "minss\t{%2, %0|%0, %2}"
19370 [(set_attr "type" "sseadd")
19371 (set_attr "mode" "SF")])
19373 (define_insn "*ieee_smaxsf3"
19374 [(set (match_operand:SF 0 "register_operand" "=x")
19375 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19376 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19379 "maxss\t{%2, %0|%0, %2}"
19380 [(set_attr "type" "sseadd")
19381 (set_attr "mode" "SF")])
19383 (define_insn "*ieee_smindf3"
19384 [(set (match_operand:DF 0 "register_operand" "=x")
19385 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19386 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19388 "TARGET_SSE2 && TARGET_SSE_MATH"
19389 "minsd\t{%2, %0|%0, %2}"
19390 [(set_attr "type" "sseadd")
19391 (set_attr "mode" "DF")])
19393 (define_insn "*ieee_smaxdf3"
19394 [(set (match_operand:DF 0 "register_operand" "=x")
19395 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19396 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19398 "TARGET_SSE2 && TARGET_SSE_MATH"
19399 "maxsd\t{%2, %0|%0, %2}"
19400 [(set_attr "type" "sseadd")
19401 (set_attr "mode" "DF")])
19403 ;; Make two stack loads independent:
19405 ;; fld %st(0) -> fld bb
19406 ;; fmul bb fmul %st(1), %st
19408 ;; Actually we only match the last two instructions for simplicity.
19410 [(set (match_operand 0 "fp_register_operand" "")
19411 (match_operand 1 "fp_register_operand" ""))
19413 (match_operator 2 "binary_fp_operator"
19415 (match_operand 3 "memory_operand" "")]))]
19416 "REGNO (operands[0]) != REGNO (operands[1])"
19417 [(set (match_dup 0) (match_dup 3))
19418 (set (match_dup 0) (match_dup 4))]
19420 ;; The % modifier is not operational anymore in peephole2's, so we have to
19421 ;; swap the operands manually in the case of addition and multiplication.
19422 "if (COMMUTATIVE_ARITH_P (operands[2]))
19423 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19424 operands[0], operands[1]);
19426 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19427 operands[1], operands[0]);")
19429 ;; Conditional addition patterns
19430 (define_expand "addqicc"
19431 [(match_operand:QI 0 "register_operand" "")
19432 (match_operand 1 "comparison_operator" "")
19433 (match_operand:QI 2 "register_operand" "")
19434 (match_operand:QI 3 "const_int_operand" "")]
19436 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19438 (define_expand "addhicc"
19439 [(match_operand:HI 0 "register_operand" "")
19440 (match_operand 1 "comparison_operator" "")
19441 (match_operand:HI 2 "register_operand" "")
19442 (match_operand:HI 3 "const_int_operand" "")]
19444 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19446 (define_expand "addsicc"
19447 [(match_operand:SI 0 "register_operand" "")
19448 (match_operand 1 "comparison_operator" "")
19449 (match_operand:SI 2 "register_operand" "")
19450 (match_operand:SI 3 "const_int_operand" "")]
19452 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19454 (define_expand "adddicc"
19455 [(match_operand:DI 0 "register_operand" "")
19456 (match_operand 1 "comparison_operator" "")
19457 (match_operand:DI 2 "register_operand" "")
19458 (match_operand:DI 3 "const_int_operand" "")]
19460 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19463 ;; Misc patterns (?)
19465 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19466 ;; Otherwise there will be nothing to keep
19468 ;; [(set (reg ebp) (reg esp))]
19469 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19470 ;; (clobber (eflags)]
19471 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19473 ;; in proper program order.
19474 (define_insn "pro_epilogue_adjust_stack_1"
19475 [(set (match_operand:SI 0 "register_operand" "=r,r")
19476 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19477 (match_operand:SI 2 "immediate_operand" "i,i")))
19478 (clobber (reg:CC FLAGS_REG))
19479 (clobber (mem:BLK (scratch)))]
19482 switch (get_attr_type (insn))
19485 return "mov{l}\t{%1, %0|%0, %1}";
19488 if (CONST_INT_P (operands[2])
19489 && (INTVAL (operands[2]) == 128
19490 || (INTVAL (operands[2]) < 0
19491 && INTVAL (operands[2]) != -128)))
19493 operands[2] = GEN_INT (-INTVAL (operands[2]));
19494 return "sub{l}\t{%2, %0|%0, %2}";
19496 return "add{l}\t{%2, %0|%0, %2}";
19499 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19500 return "lea{l}\t{%a2, %0|%0, %a2}";
19503 gcc_unreachable ();
19506 [(set (attr "type")
19507 (cond [(eq_attr "alternative" "0")
19508 (const_string "alu")
19509 (match_operand:SI 2 "const0_operand" "")
19510 (const_string "imov")
19512 (const_string "lea")))
19513 (set_attr "mode" "SI")])
19515 (define_insn "pro_epilogue_adjust_stack_rex64"
19516 [(set (match_operand:DI 0 "register_operand" "=r,r")
19517 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19518 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19519 (clobber (reg:CC FLAGS_REG))
19520 (clobber (mem:BLK (scratch)))]
19523 switch (get_attr_type (insn))
19526 return "mov{q}\t{%1, %0|%0, %1}";
19529 if (CONST_INT_P (operands[2])
19530 /* Avoid overflows. */
19531 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19532 && (INTVAL (operands[2]) == 128
19533 || (INTVAL (operands[2]) < 0
19534 && INTVAL (operands[2]) != -128)))
19536 operands[2] = GEN_INT (-INTVAL (operands[2]));
19537 return "sub{q}\t{%2, %0|%0, %2}";
19539 return "add{q}\t{%2, %0|%0, %2}";
19542 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19543 return "lea{q}\t{%a2, %0|%0, %a2}";
19546 gcc_unreachable ();
19549 [(set (attr "type")
19550 (cond [(eq_attr "alternative" "0")
19551 (const_string "alu")
19552 (match_operand:DI 2 "const0_operand" "")
19553 (const_string "imov")
19555 (const_string "lea")))
19556 (set_attr "mode" "DI")])
19558 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19559 [(set (match_operand:DI 0 "register_operand" "=r,r")
19560 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19561 (match_operand:DI 3 "immediate_operand" "i,i")))
19562 (use (match_operand:DI 2 "register_operand" "r,r"))
19563 (clobber (reg:CC FLAGS_REG))
19564 (clobber (mem:BLK (scratch)))]
19567 switch (get_attr_type (insn))
19570 return "add{q}\t{%2, %0|%0, %2}";
19573 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19574 return "lea{q}\t{%a2, %0|%0, %a2}";
19577 gcc_unreachable ();
19580 [(set_attr "type" "alu,lea")
19581 (set_attr "mode" "DI")])
19583 (define_expand "allocate_stack_worker"
19584 [(match_operand:SI 0 "register_operand" "")]
19585 "TARGET_STACK_PROBE"
19587 if (reload_completed)
19590 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19592 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19597 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19599 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19604 (define_insn "allocate_stack_worker_1"
19605 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19606 UNSPECV_STACK_PROBE)
19607 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19608 (clobber (match_scratch:SI 1 "=0"))
19609 (clobber (reg:CC FLAGS_REG))]
19610 "!TARGET_64BIT && TARGET_STACK_PROBE"
19612 [(set_attr "type" "multi")
19613 (set_attr "length" "5")])
19615 (define_expand "allocate_stack_worker_postreload"
19616 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19617 UNSPECV_STACK_PROBE)
19618 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19619 (clobber (match_dup 0))
19620 (clobber (reg:CC FLAGS_REG))])]
19624 (define_insn "allocate_stack_worker_rex64"
19625 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19626 UNSPECV_STACK_PROBE)
19627 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19628 (clobber (match_scratch:DI 1 "=0"))
19629 (clobber (reg:CC FLAGS_REG))]
19630 "TARGET_64BIT && TARGET_STACK_PROBE"
19632 [(set_attr "type" "multi")
19633 (set_attr "length" "5")])
19635 (define_expand "allocate_stack_worker_rex64_postreload"
19636 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19637 UNSPECV_STACK_PROBE)
19638 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19639 (clobber (match_dup 0))
19640 (clobber (reg:CC FLAGS_REG))])]
19644 (define_expand "allocate_stack"
19645 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19646 (minus:SI (reg:SI SP_REG)
19647 (match_operand:SI 1 "general_operand" "")))
19648 (clobber (reg:CC FLAGS_REG))])
19649 (parallel [(set (reg:SI SP_REG)
19650 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19651 (clobber (reg:CC FLAGS_REG))])]
19652 "TARGET_STACK_PROBE"
19654 #ifdef CHECK_STACK_LIMIT
19655 if (CONST_INT_P (operands[1])
19656 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19657 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19661 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19664 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19668 (define_expand "builtin_setjmp_receiver"
19669 [(label_ref (match_operand 0 "" ""))]
19670 "!TARGET_64BIT && flag_pic"
19675 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19676 rtx label_rtx = gen_label_rtx ();
19677 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19678 xops[0] = xops[1] = picreg;
19679 xops[2] = gen_rtx_CONST (SImode,
19680 gen_rtx_MINUS (SImode,
19681 gen_rtx_LABEL_REF (SImode, label_rtx),
19682 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19683 ix86_expand_binary_operator (MINUS, SImode, xops);
19686 emit_insn (gen_set_got (pic_offset_table_rtx));
19690 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19693 [(set (match_operand 0 "register_operand" "")
19694 (match_operator 3 "promotable_binary_operator"
19695 [(match_operand 1 "register_operand" "")
19696 (match_operand 2 "aligned_operand" "")]))
19697 (clobber (reg:CC FLAGS_REG))]
19698 "! TARGET_PARTIAL_REG_STALL && reload_completed
19699 && ((GET_MODE (operands[0]) == HImode
19700 && ((!optimize_size && !TARGET_FAST_PREFIX)
19701 /* ??? next two lines just !satisfies_constraint_K (...) */
19702 || !CONST_INT_P (operands[2])
19703 || satisfies_constraint_K (operands[2])))
19704 || (GET_MODE (operands[0]) == QImode
19705 && (TARGET_PROMOTE_QImode || optimize_size)))"
19706 [(parallel [(set (match_dup 0)
19707 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19708 (clobber (reg:CC FLAGS_REG))])]
19709 "operands[0] = gen_lowpart (SImode, operands[0]);
19710 operands[1] = gen_lowpart (SImode, operands[1]);
19711 if (GET_CODE (operands[3]) != ASHIFT)
19712 operands[2] = gen_lowpart (SImode, operands[2]);
19713 PUT_MODE (operands[3], SImode);")
19715 ; Promote the QImode tests, as i386 has encoding of the AND
19716 ; instruction with 32-bit sign-extended immediate and thus the
19717 ; instruction size is unchanged, except in the %eax case for
19718 ; which it is increased by one byte, hence the ! optimize_size.
19720 [(set (match_operand 0 "flags_reg_operand" "")
19721 (match_operator 2 "compare_operator"
19722 [(and (match_operand 3 "aligned_operand" "")
19723 (match_operand 4 "const_int_operand" ""))
19725 (set (match_operand 1 "register_operand" "")
19726 (and (match_dup 3) (match_dup 4)))]
19727 "! TARGET_PARTIAL_REG_STALL && reload_completed
19728 /* Ensure that the operand will remain sign-extended immediate. */
19729 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19731 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19732 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19733 [(parallel [(set (match_dup 0)
19734 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19737 (and:SI (match_dup 3) (match_dup 4)))])]
19740 = gen_int_mode (INTVAL (operands[4])
19741 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19742 operands[1] = gen_lowpart (SImode, operands[1]);
19743 operands[3] = gen_lowpart (SImode, operands[3]);
19746 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19747 ; the TEST instruction with 32-bit sign-extended immediate and thus
19748 ; the instruction size would at least double, which is not what we
19749 ; want even with ! optimize_size.
19751 [(set (match_operand 0 "flags_reg_operand" "")
19752 (match_operator 1 "compare_operator"
19753 [(and (match_operand:HI 2 "aligned_operand" "")
19754 (match_operand:HI 3 "const_int_operand" ""))
19756 "! TARGET_PARTIAL_REG_STALL && reload_completed
19757 /* Ensure that the operand will remain sign-extended immediate. */
19758 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19759 && ! TARGET_FAST_PREFIX
19760 && ! optimize_size"
19761 [(set (match_dup 0)
19762 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19766 = gen_int_mode (INTVAL (operands[3])
19767 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19768 operands[2] = gen_lowpart (SImode, operands[2]);
19772 [(set (match_operand 0 "register_operand" "")
19773 (neg (match_operand 1 "register_operand" "")))
19774 (clobber (reg:CC FLAGS_REG))]
19775 "! TARGET_PARTIAL_REG_STALL && reload_completed
19776 && (GET_MODE (operands[0]) == HImode
19777 || (GET_MODE (operands[0]) == QImode
19778 && (TARGET_PROMOTE_QImode || optimize_size)))"
19779 [(parallel [(set (match_dup 0)
19780 (neg:SI (match_dup 1)))
19781 (clobber (reg:CC FLAGS_REG))])]
19782 "operands[0] = gen_lowpart (SImode, operands[0]);
19783 operands[1] = gen_lowpart (SImode, operands[1]);")
19786 [(set (match_operand 0 "register_operand" "")
19787 (not (match_operand 1 "register_operand" "")))]
19788 "! TARGET_PARTIAL_REG_STALL && reload_completed
19789 && (GET_MODE (operands[0]) == HImode
19790 || (GET_MODE (operands[0]) == QImode
19791 && (TARGET_PROMOTE_QImode || optimize_size)))"
19792 [(set (match_dup 0)
19793 (not:SI (match_dup 1)))]
19794 "operands[0] = gen_lowpart (SImode, operands[0]);
19795 operands[1] = gen_lowpart (SImode, operands[1]);")
19798 [(set (match_operand 0 "register_operand" "")
19799 (if_then_else (match_operator 1 "comparison_operator"
19800 [(reg FLAGS_REG) (const_int 0)])
19801 (match_operand 2 "register_operand" "")
19802 (match_operand 3 "register_operand" "")))]
19803 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19804 && (GET_MODE (operands[0]) == HImode
19805 || (GET_MODE (operands[0]) == QImode
19806 && (TARGET_PROMOTE_QImode || optimize_size)))"
19807 [(set (match_dup 0)
19808 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19809 "operands[0] = gen_lowpart (SImode, operands[0]);
19810 operands[2] = gen_lowpart (SImode, operands[2]);
19811 operands[3] = gen_lowpart (SImode, operands[3]);")
19814 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19815 ;; transform a complex memory operation into two memory to register operations.
19817 ;; Don't push memory operands
19819 [(set (match_operand:SI 0 "push_operand" "")
19820 (match_operand:SI 1 "memory_operand" ""))
19821 (match_scratch:SI 2 "r")]
19822 "!optimize_size && !TARGET_PUSH_MEMORY
19823 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19824 [(set (match_dup 2) (match_dup 1))
19825 (set (match_dup 0) (match_dup 2))]
19829 [(set (match_operand:DI 0 "push_operand" "")
19830 (match_operand:DI 1 "memory_operand" ""))
19831 (match_scratch:DI 2 "r")]
19832 "!optimize_size && !TARGET_PUSH_MEMORY
19833 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19834 [(set (match_dup 2) (match_dup 1))
19835 (set (match_dup 0) (match_dup 2))]
19838 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19841 [(set (match_operand:SF 0 "push_operand" "")
19842 (match_operand:SF 1 "memory_operand" ""))
19843 (match_scratch:SF 2 "r")]
19844 "!optimize_size && !TARGET_PUSH_MEMORY
19845 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19846 [(set (match_dup 2) (match_dup 1))
19847 (set (match_dup 0) (match_dup 2))]
19851 [(set (match_operand:HI 0 "push_operand" "")
19852 (match_operand:HI 1 "memory_operand" ""))
19853 (match_scratch:HI 2 "r")]
19854 "!optimize_size && !TARGET_PUSH_MEMORY
19855 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19856 [(set (match_dup 2) (match_dup 1))
19857 (set (match_dup 0) (match_dup 2))]
19861 [(set (match_operand:QI 0 "push_operand" "")
19862 (match_operand:QI 1 "memory_operand" ""))
19863 (match_scratch:QI 2 "q")]
19864 "!optimize_size && !TARGET_PUSH_MEMORY
19865 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19866 [(set (match_dup 2) (match_dup 1))
19867 (set (match_dup 0) (match_dup 2))]
19870 ;; Don't move an immediate directly to memory when the instruction
19873 [(match_scratch:SI 1 "r")
19874 (set (match_operand:SI 0 "memory_operand" "")
19877 && ! TARGET_USE_MOV0
19878 && TARGET_SPLIT_LONG_MOVES
19879 && get_attr_length (insn) >= ix86_cost->large_insn
19880 && peep2_regno_dead_p (0, FLAGS_REG)"
19881 [(parallel [(set (match_dup 1) (const_int 0))
19882 (clobber (reg:CC FLAGS_REG))])
19883 (set (match_dup 0) (match_dup 1))]
19887 [(match_scratch:HI 1 "r")
19888 (set (match_operand:HI 0 "memory_operand" "")
19891 && ! TARGET_USE_MOV0
19892 && TARGET_SPLIT_LONG_MOVES
19893 && get_attr_length (insn) >= ix86_cost->large_insn
19894 && peep2_regno_dead_p (0, FLAGS_REG)"
19895 [(parallel [(set (match_dup 2) (const_int 0))
19896 (clobber (reg:CC FLAGS_REG))])
19897 (set (match_dup 0) (match_dup 1))]
19898 "operands[2] = gen_lowpart (SImode, operands[1]);")
19901 [(match_scratch:QI 1 "q")
19902 (set (match_operand:QI 0 "memory_operand" "")
19905 && ! TARGET_USE_MOV0
19906 && TARGET_SPLIT_LONG_MOVES
19907 && get_attr_length (insn) >= ix86_cost->large_insn
19908 && peep2_regno_dead_p (0, FLAGS_REG)"
19909 [(parallel [(set (match_dup 2) (const_int 0))
19910 (clobber (reg:CC FLAGS_REG))])
19911 (set (match_dup 0) (match_dup 1))]
19912 "operands[2] = gen_lowpart (SImode, operands[1]);")
19915 [(match_scratch:SI 2 "r")
19916 (set (match_operand:SI 0 "memory_operand" "")
19917 (match_operand:SI 1 "immediate_operand" ""))]
19919 && get_attr_length (insn) >= ix86_cost->large_insn
19920 && TARGET_SPLIT_LONG_MOVES"
19921 [(set (match_dup 2) (match_dup 1))
19922 (set (match_dup 0) (match_dup 2))]
19926 [(match_scratch:HI 2 "r")
19927 (set (match_operand:HI 0 "memory_operand" "")
19928 (match_operand:HI 1 "immediate_operand" ""))]
19929 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19930 && TARGET_SPLIT_LONG_MOVES"
19931 [(set (match_dup 2) (match_dup 1))
19932 (set (match_dup 0) (match_dup 2))]
19936 [(match_scratch:QI 2 "q")
19937 (set (match_operand:QI 0 "memory_operand" "")
19938 (match_operand:QI 1 "immediate_operand" ""))]
19939 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19940 && TARGET_SPLIT_LONG_MOVES"
19941 [(set (match_dup 2) (match_dup 1))
19942 (set (match_dup 0) (match_dup 2))]
19945 ;; Don't compare memory with zero, load and use a test instead.
19947 [(set (match_operand 0 "flags_reg_operand" "")
19948 (match_operator 1 "compare_operator"
19949 [(match_operand:SI 2 "memory_operand" "")
19951 (match_scratch:SI 3 "r")]
19952 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19953 [(set (match_dup 3) (match_dup 2))
19954 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19957 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19958 ;; Don't split NOTs with a displacement operand, because resulting XOR
19959 ;; will not be pairable anyway.
19961 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19962 ;; represented using a modRM byte. The XOR replacement is long decoded,
19963 ;; so this split helps here as well.
19965 ;; Note: Can't do this as a regular split because we can't get proper
19966 ;; lifetime information then.
19969 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19970 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19972 && peep2_regno_dead_p (0, FLAGS_REG)
19973 && ((TARGET_PENTIUM
19974 && (!MEM_P (operands[0])
19975 || !memory_displacement_operand (operands[0], SImode)))
19976 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19977 [(parallel [(set (match_dup 0)
19978 (xor:SI (match_dup 1) (const_int -1)))
19979 (clobber (reg:CC FLAGS_REG))])]
19983 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19984 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19986 && peep2_regno_dead_p (0, FLAGS_REG)
19987 && ((TARGET_PENTIUM
19988 && (!MEM_P (operands[0])
19989 || !memory_displacement_operand (operands[0], HImode)))
19990 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19991 [(parallel [(set (match_dup 0)
19992 (xor:HI (match_dup 1) (const_int -1)))
19993 (clobber (reg:CC FLAGS_REG))])]
19997 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19998 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20000 && peep2_regno_dead_p (0, FLAGS_REG)
20001 && ((TARGET_PENTIUM
20002 && (!MEM_P (operands[0])
20003 || !memory_displacement_operand (operands[0], QImode)))
20004 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20005 [(parallel [(set (match_dup 0)
20006 (xor:QI (match_dup 1) (const_int -1)))
20007 (clobber (reg:CC FLAGS_REG))])]
20010 ;; Non pairable "test imm, reg" instructions can be translated to
20011 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20012 ;; byte opcode instead of two, have a short form for byte operands),
20013 ;; so do it for other CPUs as well. Given that the value was dead,
20014 ;; this should not create any new dependencies. Pass on the sub-word
20015 ;; versions if we're concerned about partial register stalls.
20018 [(set (match_operand 0 "flags_reg_operand" "")
20019 (match_operator 1 "compare_operator"
20020 [(and:SI (match_operand:SI 2 "register_operand" "")
20021 (match_operand:SI 3 "immediate_operand" ""))
20023 "ix86_match_ccmode (insn, CCNOmode)
20024 && (true_regnum (operands[2]) != 0
20025 || satisfies_constraint_K (operands[3]))
20026 && peep2_reg_dead_p (1, operands[2])"
20028 [(set (match_dup 0)
20029 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20032 (and:SI (match_dup 2) (match_dup 3)))])]
20035 ;; We don't need to handle HImode case, because it will be promoted to SImode
20036 ;; on ! TARGET_PARTIAL_REG_STALL
20039 [(set (match_operand 0 "flags_reg_operand" "")
20040 (match_operator 1 "compare_operator"
20041 [(and:QI (match_operand:QI 2 "register_operand" "")
20042 (match_operand:QI 3 "immediate_operand" ""))
20044 "! TARGET_PARTIAL_REG_STALL
20045 && ix86_match_ccmode (insn, CCNOmode)
20046 && true_regnum (operands[2]) != 0
20047 && peep2_reg_dead_p (1, operands[2])"
20049 [(set (match_dup 0)
20050 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20053 (and:QI (match_dup 2) (match_dup 3)))])]
20057 [(set (match_operand 0 "flags_reg_operand" "")
20058 (match_operator 1 "compare_operator"
20061 (match_operand 2 "ext_register_operand" "")
20064 (match_operand 3 "const_int_operand" ""))
20066 "! TARGET_PARTIAL_REG_STALL
20067 && ix86_match_ccmode (insn, CCNOmode)
20068 && true_regnum (operands[2]) != 0
20069 && peep2_reg_dead_p (1, operands[2])"
20070 [(parallel [(set (match_dup 0)
20079 (set (zero_extract:SI (match_dup 2)
20090 ;; Don't do logical operations with memory inputs.
20092 [(match_scratch:SI 2 "r")
20093 (parallel [(set (match_operand:SI 0 "register_operand" "")
20094 (match_operator:SI 3 "arith_or_logical_operator"
20096 (match_operand:SI 1 "memory_operand" "")]))
20097 (clobber (reg:CC FLAGS_REG))])]
20098 "! optimize_size && ! TARGET_READ_MODIFY"
20099 [(set (match_dup 2) (match_dup 1))
20100 (parallel [(set (match_dup 0)
20101 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20102 (clobber (reg:CC FLAGS_REG))])]
20106 [(match_scratch:SI 2 "r")
20107 (parallel [(set (match_operand:SI 0 "register_operand" "")
20108 (match_operator:SI 3 "arith_or_logical_operator"
20109 [(match_operand:SI 1 "memory_operand" "")
20111 (clobber (reg:CC FLAGS_REG))])]
20112 "! optimize_size && ! TARGET_READ_MODIFY"
20113 [(set (match_dup 2) (match_dup 1))
20114 (parallel [(set (match_dup 0)
20115 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20116 (clobber (reg:CC FLAGS_REG))])]
20119 ; Don't do logical operations with memory outputs
20121 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20122 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20123 ; the same decoder scheduling characteristics as the original.
20126 [(match_scratch:SI 2 "r")
20127 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20128 (match_operator:SI 3 "arith_or_logical_operator"
20130 (match_operand:SI 1 "nonmemory_operand" "")]))
20131 (clobber (reg:CC FLAGS_REG))])]
20132 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20133 [(set (match_dup 2) (match_dup 0))
20134 (parallel [(set (match_dup 2)
20135 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20136 (clobber (reg:CC FLAGS_REG))])
20137 (set (match_dup 0) (match_dup 2))]
20141 [(match_scratch:SI 2 "r")
20142 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20143 (match_operator:SI 3 "arith_or_logical_operator"
20144 [(match_operand:SI 1 "nonmemory_operand" "")
20146 (clobber (reg:CC FLAGS_REG))])]
20147 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20148 [(set (match_dup 2) (match_dup 0))
20149 (parallel [(set (match_dup 2)
20150 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20151 (clobber (reg:CC FLAGS_REG))])
20152 (set (match_dup 0) (match_dup 2))]
20155 ;; Attempt to always use XOR for zeroing registers.
20157 [(set (match_operand 0 "register_operand" "")
20158 (match_operand 1 "const0_operand" ""))]
20159 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20160 && (! TARGET_USE_MOV0 || optimize_size)
20161 && GENERAL_REG_P (operands[0])
20162 && peep2_regno_dead_p (0, FLAGS_REG)"
20163 [(parallel [(set (match_dup 0) (const_int 0))
20164 (clobber (reg:CC FLAGS_REG))])]
20166 operands[0] = gen_lowpart (word_mode, operands[0]);
20170 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20172 "(GET_MODE (operands[0]) == QImode
20173 || GET_MODE (operands[0]) == HImode)
20174 && (! TARGET_USE_MOV0 || optimize_size)
20175 && peep2_regno_dead_p (0, FLAGS_REG)"
20176 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20177 (clobber (reg:CC FLAGS_REG))])])
20179 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20181 [(set (match_operand 0 "register_operand" "")
20183 "(GET_MODE (operands[0]) == HImode
20184 || GET_MODE (operands[0]) == SImode
20185 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20186 && (optimize_size || TARGET_PENTIUM)
20187 && peep2_regno_dead_p (0, FLAGS_REG)"
20188 [(parallel [(set (match_dup 0) (const_int -1))
20189 (clobber (reg:CC FLAGS_REG))])]
20190 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20193 ;; Attempt to convert simple leas to adds. These can be created by
20196 [(set (match_operand:SI 0 "register_operand" "")
20197 (plus:SI (match_dup 0)
20198 (match_operand:SI 1 "nonmemory_operand" "")))]
20199 "peep2_regno_dead_p (0, FLAGS_REG)"
20200 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20201 (clobber (reg:CC FLAGS_REG))])]
20205 [(set (match_operand:SI 0 "register_operand" "")
20206 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20207 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20208 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20209 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20210 (clobber (reg:CC FLAGS_REG))])]
20211 "operands[2] = gen_lowpart (SImode, operands[2]);")
20214 [(set (match_operand:DI 0 "register_operand" "")
20215 (plus:DI (match_dup 0)
20216 (match_operand:DI 1 "x86_64_general_operand" "")))]
20217 "peep2_regno_dead_p (0, FLAGS_REG)"
20218 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20219 (clobber (reg:CC FLAGS_REG))])]
20223 [(set (match_operand:SI 0 "register_operand" "")
20224 (mult:SI (match_dup 0)
20225 (match_operand:SI 1 "const_int_operand" "")))]
20226 "exact_log2 (INTVAL (operands[1])) >= 0
20227 && peep2_regno_dead_p (0, FLAGS_REG)"
20228 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20229 (clobber (reg:CC FLAGS_REG))])]
20230 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20233 [(set (match_operand:DI 0 "register_operand" "")
20234 (mult:DI (match_dup 0)
20235 (match_operand:DI 1 "const_int_operand" "")))]
20236 "exact_log2 (INTVAL (operands[1])) >= 0
20237 && peep2_regno_dead_p (0, FLAGS_REG)"
20238 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20239 (clobber (reg:CC FLAGS_REG))])]
20240 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20243 [(set (match_operand:SI 0 "register_operand" "")
20244 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20245 (match_operand:DI 2 "const_int_operand" "")) 0))]
20246 "exact_log2 (INTVAL (operands[2])) >= 0
20247 && REGNO (operands[0]) == REGNO (operands[1])
20248 && peep2_regno_dead_p (0, FLAGS_REG)"
20249 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20250 (clobber (reg:CC FLAGS_REG))])]
20251 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20253 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20254 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20255 ;; many CPUs it is also faster, since special hardware to avoid esp
20256 ;; dependencies is present.
20258 ;; While some of these conversions may be done using splitters, we use peepholes
20259 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20261 ;; Convert prologue esp subtractions to push.
20262 ;; We need register to push. In order to keep verify_flow_info happy we have
20264 ;; - use scratch and clobber it in order to avoid dependencies
20265 ;; - use already live register
20266 ;; We can't use the second way right now, since there is no reliable way how to
20267 ;; verify that given register is live. First choice will also most likely in
20268 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20269 ;; call clobbered registers are dead. We may want to use base pointer as an
20270 ;; alternative when no register is available later.
20273 [(match_scratch:SI 0 "r")
20274 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20275 (clobber (reg:CC FLAGS_REG))
20276 (clobber (mem:BLK (scratch)))])]
20277 "optimize_size || !TARGET_SUB_ESP_4"
20278 [(clobber (match_dup 0))
20279 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20280 (clobber (mem:BLK (scratch)))])])
20283 [(match_scratch:SI 0 "r")
20284 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20285 (clobber (reg:CC FLAGS_REG))
20286 (clobber (mem:BLK (scratch)))])]
20287 "optimize_size || !TARGET_SUB_ESP_8"
20288 [(clobber (match_dup 0))
20289 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20290 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20291 (clobber (mem:BLK (scratch)))])])
20293 ;; Convert esp subtractions to push.
20295 [(match_scratch:SI 0 "r")
20296 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20297 (clobber (reg:CC FLAGS_REG))])]
20298 "optimize_size || !TARGET_SUB_ESP_4"
20299 [(clobber (match_dup 0))
20300 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20303 [(match_scratch:SI 0 "r")
20304 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20305 (clobber (reg:CC FLAGS_REG))])]
20306 "optimize_size || !TARGET_SUB_ESP_8"
20307 [(clobber (match_dup 0))
20308 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20309 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20311 ;; Convert epilogue deallocator to pop.
20313 [(match_scratch:SI 0 "r")
20314 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20315 (clobber (reg:CC FLAGS_REG))
20316 (clobber (mem:BLK (scratch)))])]
20317 "optimize_size || !TARGET_ADD_ESP_4"
20318 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20319 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20320 (clobber (mem:BLK (scratch)))])]
20323 ;; Two pops case is tricky, since pop causes dependency on destination register.
20324 ;; We use two registers if available.
20326 [(match_scratch:SI 0 "r")
20327 (match_scratch:SI 1 "r")
20328 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20329 (clobber (reg:CC FLAGS_REG))
20330 (clobber (mem:BLK (scratch)))])]
20331 "optimize_size || !TARGET_ADD_ESP_8"
20332 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20333 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20334 (clobber (mem:BLK (scratch)))])
20335 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20336 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20340 [(match_scratch:SI 0 "r")
20341 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20342 (clobber (reg:CC FLAGS_REG))
20343 (clobber (mem:BLK (scratch)))])]
20345 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20346 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20347 (clobber (mem:BLK (scratch)))])
20348 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20349 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20352 ;; Convert esp additions to pop.
20354 [(match_scratch:SI 0 "r")
20355 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20356 (clobber (reg:CC FLAGS_REG))])]
20358 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20359 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20362 ;; Two pops case is tricky, since pop causes dependency on destination register.
20363 ;; We use two registers if available.
20365 [(match_scratch:SI 0 "r")
20366 (match_scratch:SI 1 "r")
20367 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20368 (clobber (reg:CC FLAGS_REG))])]
20370 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20371 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20372 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20373 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20377 [(match_scratch:SI 0 "r")
20378 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20379 (clobber (reg:CC FLAGS_REG))])]
20381 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20382 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20383 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20384 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20387 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20388 ;; required and register dies. Similarly for 128 to plus -128.
20390 [(set (match_operand 0 "flags_reg_operand" "")
20391 (match_operator 1 "compare_operator"
20392 [(match_operand 2 "register_operand" "")
20393 (match_operand 3 "const_int_operand" "")]))]
20394 "(INTVAL (operands[3]) == -1
20395 || INTVAL (operands[3]) == 1
20396 || INTVAL (operands[3]) == 128)
20397 && ix86_match_ccmode (insn, CCGCmode)
20398 && peep2_reg_dead_p (1, operands[2])"
20399 [(parallel [(set (match_dup 0)
20400 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20401 (clobber (match_dup 2))])]
20405 [(match_scratch:DI 0 "r")
20406 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20407 (clobber (reg:CC FLAGS_REG))
20408 (clobber (mem:BLK (scratch)))])]
20409 "optimize_size || !TARGET_SUB_ESP_4"
20410 [(clobber (match_dup 0))
20411 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20412 (clobber (mem:BLK (scratch)))])])
20415 [(match_scratch:DI 0 "r")
20416 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20417 (clobber (reg:CC FLAGS_REG))
20418 (clobber (mem:BLK (scratch)))])]
20419 "optimize_size || !TARGET_SUB_ESP_8"
20420 [(clobber (match_dup 0))
20421 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20422 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20423 (clobber (mem:BLK (scratch)))])])
20425 ;; Convert esp subtractions to push.
20427 [(match_scratch:DI 0 "r")
20428 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20429 (clobber (reg:CC FLAGS_REG))])]
20430 "optimize_size || !TARGET_SUB_ESP_4"
20431 [(clobber (match_dup 0))
20432 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20435 [(match_scratch:DI 0 "r")
20436 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20437 (clobber (reg:CC FLAGS_REG))])]
20438 "optimize_size || !TARGET_SUB_ESP_8"
20439 [(clobber (match_dup 0))
20440 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20441 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20443 ;; Convert epilogue deallocator to pop.
20445 [(match_scratch:DI 0 "r")
20446 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20447 (clobber (reg:CC FLAGS_REG))
20448 (clobber (mem:BLK (scratch)))])]
20449 "optimize_size || !TARGET_ADD_ESP_4"
20450 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20451 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20452 (clobber (mem:BLK (scratch)))])]
20455 ;; Two pops case is tricky, since pop causes dependency on destination register.
20456 ;; We use two registers if available.
20458 [(match_scratch:DI 0 "r")
20459 (match_scratch:DI 1 "r")
20460 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20461 (clobber (reg:CC FLAGS_REG))
20462 (clobber (mem:BLK (scratch)))])]
20463 "optimize_size || !TARGET_ADD_ESP_8"
20464 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20465 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20466 (clobber (mem:BLK (scratch)))])
20467 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20468 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20472 [(match_scratch:DI 0 "r")
20473 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20474 (clobber (reg:CC FLAGS_REG))
20475 (clobber (mem:BLK (scratch)))])]
20477 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20478 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20479 (clobber (mem:BLK (scratch)))])
20480 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20481 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20484 ;; Convert esp additions to pop.
20486 [(match_scratch:DI 0 "r")
20487 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20488 (clobber (reg:CC FLAGS_REG))])]
20490 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20491 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20494 ;; Two pops case is tricky, since pop causes dependency on destination register.
20495 ;; We use two registers if available.
20497 [(match_scratch:DI 0 "r")
20498 (match_scratch:DI 1 "r")
20499 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20500 (clobber (reg:CC FLAGS_REG))])]
20502 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20503 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20504 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20505 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20509 [(match_scratch:DI 0 "r")
20510 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20511 (clobber (reg:CC FLAGS_REG))])]
20513 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20514 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20515 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20516 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20519 ;; Convert imul by three, five and nine into lea
20522 [(set (match_operand:SI 0 "register_operand" "")
20523 (mult:SI (match_operand:SI 1 "register_operand" "")
20524 (match_operand:SI 2 "const_int_operand" "")))
20525 (clobber (reg:CC FLAGS_REG))])]
20526 "INTVAL (operands[2]) == 3
20527 || INTVAL (operands[2]) == 5
20528 || INTVAL (operands[2]) == 9"
20529 [(set (match_dup 0)
20530 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20532 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20536 [(set (match_operand:SI 0 "register_operand" "")
20537 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20538 (match_operand:SI 2 "const_int_operand" "")))
20539 (clobber (reg:CC FLAGS_REG))])]
20541 && (INTVAL (operands[2]) == 3
20542 || INTVAL (operands[2]) == 5
20543 || INTVAL (operands[2]) == 9)"
20544 [(set (match_dup 0) (match_dup 1))
20546 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20548 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20552 [(set (match_operand:DI 0 "register_operand" "")
20553 (mult:DI (match_operand:DI 1 "register_operand" "")
20554 (match_operand:DI 2 "const_int_operand" "")))
20555 (clobber (reg:CC FLAGS_REG))])]
20557 && (INTVAL (operands[2]) == 3
20558 || INTVAL (operands[2]) == 5
20559 || INTVAL (operands[2]) == 9)"
20560 [(set (match_dup 0)
20561 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20563 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20567 [(set (match_operand:DI 0 "register_operand" "")
20568 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20569 (match_operand:DI 2 "const_int_operand" "")))
20570 (clobber (reg:CC FLAGS_REG))])]
20573 && (INTVAL (operands[2]) == 3
20574 || INTVAL (operands[2]) == 5
20575 || INTVAL (operands[2]) == 9)"
20576 [(set (match_dup 0) (match_dup 1))
20578 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20580 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20582 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20583 ;; imul $32bit_imm, reg, reg is direct decoded.
20585 [(match_scratch:DI 3 "r")
20586 (parallel [(set (match_operand:DI 0 "register_operand" "")
20587 (mult:DI (match_operand:DI 1 "memory_operand" "")
20588 (match_operand:DI 2 "immediate_operand" "")))
20589 (clobber (reg:CC FLAGS_REG))])]
20590 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20591 && !satisfies_constraint_K (operands[2])"
20592 [(set (match_dup 3) (match_dup 1))
20593 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20594 (clobber (reg:CC FLAGS_REG))])]
20598 [(match_scratch:SI 3 "r")
20599 (parallel [(set (match_operand:SI 0 "register_operand" "")
20600 (mult:SI (match_operand:SI 1 "memory_operand" "")
20601 (match_operand:SI 2 "immediate_operand" "")))
20602 (clobber (reg:CC FLAGS_REG))])]
20603 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20604 && !satisfies_constraint_K (operands[2])"
20605 [(set (match_dup 3) (match_dup 1))
20606 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20607 (clobber (reg:CC FLAGS_REG))])]
20611 [(match_scratch:SI 3 "r")
20612 (parallel [(set (match_operand:DI 0 "register_operand" "")
20614 (mult:SI (match_operand:SI 1 "memory_operand" "")
20615 (match_operand:SI 2 "immediate_operand" ""))))
20616 (clobber (reg:CC FLAGS_REG))])]
20617 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20618 && !satisfies_constraint_K (operands[2])"
20619 [(set (match_dup 3) (match_dup 1))
20620 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20621 (clobber (reg:CC FLAGS_REG))])]
20624 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20625 ;; Convert it into imul reg, reg
20626 ;; It would be better to force assembler to encode instruction using long
20627 ;; immediate, but there is apparently no way to do so.
20629 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20630 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20631 (match_operand:DI 2 "const_int_operand" "")))
20632 (clobber (reg:CC FLAGS_REG))])
20633 (match_scratch:DI 3 "r")]
20634 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20635 && satisfies_constraint_K (operands[2])"
20636 [(set (match_dup 3) (match_dup 2))
20637 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20638 (clobber (reg:CC FLAGS_REG))])]
20640 if (!rtx_equal_p (operands[0], operands[1]))
20641 emit_move_insn (operands[0], operands[1]);
20645 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20646 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20647 (match_operand:SI 2 "const_int_operand" "")))
20648 (clobber (reg:CC FLAGS_REG))])
20649 (match_scratch:SI 3 "r")]
20650 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20651 && satisfies_constraint_K (operands[2])"
20652 [(set (match_dup 3) (match_dup 2))
20653 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20654 (clobber (reg:CC FLAGS_REG))])]
20656 if (!rtx_equal_p (operands[0], operands[1]))
20657 emit_move_insn (operands[0], operands[1]);
20661 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20662 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20663 (match_operand:HI 2 "immediate_operand" "")))
20664 (clobber (reg:CC FLAGS_REG))])
20665 (match_scratch:HI 3 "r")]
20666 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20667 [(set (match_dup 3) (match_dup 2))
20668 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20669 (clobber (reg:CC FLAGS_REG))])]
20671 if (!rtx_equal_p (operands[0], operands[1]))
20672 emit_move_insn (operands[0], operands[1]);
20675 ;; After splitting up read-modify operations, array accesses with memory
20676 ;; operands might end up in form:
20678 ;; movl 4(%esp), %edx
20680 ;; instead of pre-splitting:
20682 ;; addl 4(%esp), %eax
20684 ;; movl 4(%esp), %edx
20685 ;; leal (%edx,%eax,4), %eax
20688 [(parallel [(set (match_operand 0 "register_operand" "")
20689 (ashift (match_operand 1 "register_operand" "")
20690 (match_operand 2 "const_int_operand" "")))
20691 (clobber (reg:CC FLAGS_REG))])
20692 (set (match_operand 3 "register_operand")
20693 (match_operand 4 "x86_64_general_operand" ""))
20694 (parallel [(set (match_operand 5 "register_operand" "")
20695 (plus (match_operand 6 "register_operand" "")
20696 (match_operand 7 "register_operand" "")))
20697 (clobber (reg:CC FLAGS_REG))])]
20698 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20699 /* Validate MODE for lea. */
20700 && ((!TARGET_PARTIAL_REG_STALL
20701 && (GET_MODE (operands[0]) == QImode
20702 || GET_MODE (operands[0]) == HImode))
20703 || GET_MODE (operands[0]) == SImode
20704 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20705 /* We reorder load and the shift. */
20706 && !rtx_equal_p (operands[1], operands[3])
20707 && !reg_overlap_mentioned_p (operands[0], operands[4])
20708 /* Last PLUS must consist of operand 0 and 3. */
20709 && !rtx_equal_p (operands[0], operands[3])
20710 && (rtx_equal_p (operands[3], operands[6])
20711 || rtx_equal_p (operands[3], operands[7]))
20712 && (rtx_equal_p (operands[0], operands[6])
20713 || rtx_equal_p (operands[0], operands[7]))
20714 /* The intermediate operand 0 must die or be same as output. */
20715 && (rtx_equal_p (operands[0], operands[5])
20716 || peep2_reg_dead_p (3, operands[0]))"
20717 [(set (match_dup 3) (match_dup 4))
20718 (set (match_dup 0) (match_dup 1))]
20720 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20721 int scale = 1 << INTVAL (operands[2]);
20722 rtx index = gen_lowpart (Pmode, operands[1]);
20723 rtx base = gen_lowpart (Pmode, operands[3]);
20724 rtx dest = gen_lowpart (mode, operands[5]);
20726 operands[1] = gen_rtx_PLUS (Pmode, base,
20727 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20729 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20730 operands[0] = dest;
20733 ;; Call-value patterns last so that the wildcard operand does not
20734 ;; disrupt insn-recog's switch tables.
20736 (define_insn "*call_value_pop_0"
20737 [(set (match_operand 0 "" "")
20738 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20739 (match_operand:SI 2 "" "")))
20740 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20741 (match_operand:SI 3 "immediate_operand" "")))]
20744 if (SIBLING_CALL_P (insn))
20747 return "call\t%P1";
20749 [(set_attr "type" "callv")])
20751 (define_insn "*call_value_pop_1"
20752 [(set (match_operand 0 "" "")
20753 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20754 (match_operand:SI 2 "" "")))
20755 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20756 (match_operand:SI 3 "immediate_operand" "i")))]
20759 if (constant_call_address_operand (operands[1], Pmode))
20761 if (SIBLING_CALL_P (insn))
20764 return "call\t%P1";
20766 if (SIBLING_CALL_P (insn))
20769 return "call\t%A1";
20771 [(set_attr "type" "callv")])
20773 (define_insn "*call_value_0"
20774 [(set (match_operand 0 "" "")
20775 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20776 (match_operand:SI 2 "" "")))]
20779 if (SIBLING_CALL_P (insn))
20782 return "call\t%P1";
20784 [(set_attr "type" "callv")])
20786 (define_insn "*call_value_0_rex64"
20787 [(set (match_operand 0 "" "")
20788 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20789 (match_operand:DI 2 "const_int_operand" "")))]
20792 if (SIBLING_CALL_P (insn))
20795 return "call\t%P1";
20797 [(set_attr "type" "callv")])
20799 (define_insn "*call_value_1"
20800 [(set (match_operand 0 "" "")
20801 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20802 (match_operand:SI 2 "" "")))]
20803 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20805 if (constant_call_address_operand (operands[1], Pmode))
20806 return "call\t%P1";
20807 return "call\t%A1";
20809 [(set_attr "type" "callv")])
20811 (define_insn "*sibcall_value_1"
20812 [(set (match_operand 0 "" "")
20813 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20814 (match_operand:SI 2 "" "")))]
20815 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20817 if (constant_call_address_operand (operands[1], Pmode))
20821 [(set_attr "type" "callv")])
20823 (define_insn "*call_value_1_rex64"
20824 [(set (match_operand 0 "" "")
20825 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20826 (match_operand:DI 2 "" "")))]
20827 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20829 if (constant_call_address_operand (operands[1], Pmode))
20830 return "call\t%P1";
20831 return "call\t%A1";
20833 [(set_attr "type" "callv")])
20835 (define_insn "*sibcall_value_1_rex64"
20836 [(set (match_operand 0 "" "")
20837 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20838 (match_operand:DI 2 "" "")))]
20839 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20841 [(set_attr "type" "callv")])
20843 (define_insn "*sibcall_value_1_rex64_v"
20844 [(set (match_operand 0 "" "")
20845 (call (mem:QI (reg:DI R11_REG))
20846 (match_operand:DI 1 "" "")))]
20847 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20849 [(set_attr "type" "callv")])
20851 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20852 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20853 ;; caught for use by garbage collectors and the like. Using an insn that
20854 ;; maps to SIGILL makes it more likely the program will rightfully die.
20855 ;; Keeping with tradition, "6" is in honor of #UD.
20856 (define_insn "trap"
20857 [(trap_if (const_int 1) (const_int 6))]
20859 { return ASM_SHORT "0x0b0f"; }
20860 [(set_attr "length" "2")])
20862 (define_expand "sse_prologue_save"
20863 [(parallel [(set (match_operand:BLK 0 "" "")
20864 (unspec:BLK [(reg:DI 21)
20871 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20872 (use (match_operand:DI 1 "register_operand" ""))
20873 (use (match_operand:DI 2 "immediate_operand" ""))
20874 (use (label_ref:DI (match_operand 3 "" "")))])]
20878 (define_insn "*sse_prologue_save_insn"
20879 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20880 (match_operand:DI 4 "const_int_operand" "n")))
20881 (unspec:BLK [(reg:DI 21)
20888 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20889 (use (match_operand:DI 1 "register_operand" "r"))
20890 (use (match_operand:DI 2 "const_int_operand" "i"))
20891 (use (label_ref:DI (match_operand 3 "" "X")))]
20893 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20894 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20898 operands[0] = gen_rtx_MEM (Pmode,
20899 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20900 output_asm_insn (\"jmp\\t%A1\", operands);
20901 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20903 operands[4] = adjust_address (operands[0], DImode, i*16);
20904 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20905 PUT_MODE (operands[4], TImode);
20906 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20907 output_asm_insn (\"rex\", operands);
20908 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20910 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20911 CODE_LABEL_NUMBER (operands[3]));
20915 [(set_attr "type" "other")
20916 (set_attr "length_immediate" "0")
20917 (set_attr "length_address" "0")
20918 (set_attr "length" "135")
20919 (set_attr "memory" "store")
20920 (set_attr "modrm" "0")
20921 (set_attr "mode" "DI")])
20923 (define_expand "prefetch"
20924 [(prefetch (match_operand 0 "address_operand" "")
20925 (match_operand:SI 1 "const_int_operand" "")
20926 (match_operand:SI 2 "const_int_operand" ""))]
20927 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20929 int rw = INTVAL (operands[1]);
20930 int locality = INTVAL (operands[2]);
20932 gcc_assert (rw == 0 || rw == 1);
20933 gcc_assert (locality >= 0 && locality <= 3);
20934 gcc_assert (GET_MODE (operands[0]) == Pmode
20935 || GET_MODE (operands[0]) == VOIDmode);
20937 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20938 supported by SSE counterpart or the SSE prefetch is not available
20939 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20941 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20942 operands[2] = GEN_INT (3);
20944 operands[1] = const0_rtx;
20947 (define_insn "*prefetch_sse"
20948 [(prefetch (match_operand:SI 0 "address_operand" "p")
20950 (match_operand:SI 1 "const_int_operand" ""))]
20951 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20953 static const char * const patterns[4] = {
20954 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20957 int locality = INTVAL (operands[1]);
20958 gcc_assert (locality >= 0 && locality <= 3);
20960 return patterns[locality];
20962 [(set_attr "type" "sse")
20963 (set_attr "memory" "none")])
20965 (define_insn "*prefetch_sse_rex"
20966 [(prefetch (match_operand:DI 0 "address_operand" "p")
20968 (match_operand:SI 1 "const_int_operand" ""))]
20969 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20971 static const char * const patterns[4] = {
20972 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20975 int locality = INTVAL (operands[1]);
20976 gcc_assert (locality >= 0 && locality <= 3);
20978 return patterns[locality];
20980 [(set_attr "type" "sse")
20981 (set_attr "memory" "none")])
20983 (define_insn "*prefetch_3dnow"
20984 [(prefetch (match_operand:SI 0 "address_operand" "p")
20985 (match_operand:SI 1 "const_int_operand" "n")
20987 "TARGET_3DNOW && !TARGET_64BIT"
20989 if (INTVAL (operands[1]) == 0)
20990 return "prefetch\t%a0";
20992 return "prefetchw\t%a0";
20994 [(set_attr "type" "mmx")
20995 (set_attr "memory" "none")])
20997 (define_insn "*prefetch_3dnow_rex"
20998 [(prefetch (match_operand:DI 0 "address_operand" "p")
20999 (match_operand:SI 1 "const_int_operand" "n")
21001 "TARGET_3DNOW && TARGET_64BIT"
21003 if (INTVAL (operands[1]) == 0)
21004 return "prefetch\t%a0";
21006 return "prefetchw\t%a0";
21008 [(set_attr "type" "mmx")
21009 (set_attr "memory" "none")])
21011 (define_expand "stack_protect_set"
21012 [(match_operand 0 "memory_operand" "")
21013 (match_operand 1 "memory_operand" "")]
21016 #ifdef TARGET_THREAD_SSP_OFFSET
21018 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21019 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21021 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21022 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21025 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21027 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21032 (define_insn "stack_protect_set_si"
21033 [(set (match_operand:SI 0 "memory_operand" "=m")
21034 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21035 (set (match_scratch:SI 2 "=&r") (const_int 0))
21036 (clobber (reg:CC FLAGS_REG))]
21038 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21039 [(set_attr "type" "multi")])
21041 (define_insn "stack_protect_set_di"
21042 [(set (match_operand:DI 0 "memory_operand" "=m")
21043 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21044 (set (match_scratch:DI 2 "=&r") (const_int 0))
21045 (clobber (reg:CC FLAGS_REG))]
21047 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21048 [(set_attr "type" "multi")])
21050 (define_insn "stack_tls_protect_set_si"
21051 [(set (match_operand:SI 0 "memory_operand" "=m")
21052 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21053 (set (match_scratch:SI 2 "=&r") (const_int 0))
21054 (clobber (reg:CC FLAGS_REG))]
21056 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21057 [(set_attr "type" "multi")])
21059 (define_insn "stack_tls_protect_set_di"
21060 [(set (match_operand:DI 0 "memory_operand" "=m")
21061 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21062 (set (match_scratch:DI 2 "=&r") (const_int 0))
21063 (clobber (reg:CC FLAGS_REG))]
21066 /* The kernel uses a different segment register for performance reasons; a
21067 system call would not have to trash the userspace segment register,
21068 which would be expensive */
21069 if (ix86_cmodel != CM_KERNEL)
21070 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21072 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21074 [(set_attr "type" "multi")])
21076 (define_expand "stack_protect_test"
21077 [(match_operand 0 "memory_operand" "")
21078 (match_operand 1 "memory_operand" "")
21079 (match_operand 2 "" "")]
21082 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21083 ix86_compare_op0 = operands[0];
21084 ix86_compare_op1 = operands[1];
21085 ix86_compare_emitted = flags;
21087 #ifdef TARGET_THREAD_SSP_OFFSET
21089 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21090 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21092 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21093 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21096 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21098 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21100 emit_jump_insn (gen_beq (operands[2]));
21104 (define_insn "stack_protect_test_si"
21105 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21106 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21107 (match_operand:SI 2 "memory_operand" "m")]
21109 (clobber (match_scratch:SI 3 "=&r"))]
21111 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21112 [(set_attr "type" "multi")])
21114 (define_insn "stack_protect_test_di"
21115 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21116 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21117 (match_operand:DI 2 "memory_operand" "m")]
21119 (clobber (match_scratch:DI 3 "=&r"))]
21121 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21122 [(set_attr "type" "multi")])
21124 (define_insn "stack_tls_protect_test_si"
21125 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21126 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21127 (match_operand:SI 2 "const_int_operand" "i")]
21128 UNSPEC_SP_TLS_TEST))
21129 (clobber (match_scratch:SI 3 "=r"))]
21131 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21132 [(set_attr "type" "multi")])
21134 (define_insn "stack_tls_protect_test_di"
21135 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21136 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21137 (match_operand:DI 2 "const_int_operand" "i")]
21138 UNSPEC_SP_TLS_TEST))
21139 (clobber (match_scratch:DI 3 "=r"))]
21142 /* The kernel uses a different segment register for performance reasons; a
21143 system call would not have to trash the userspace segment register,
21144 which would be expensive */
21145 if (ix86_cmodel != CM_KERNEL)
21146 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21148 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21150 [(set_attr "type" "multi")])
21154 (include "sync.md")