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
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, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, 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)
73 (UNSPEC_TLS_LD_BASE 17)
75 ; Other random patterns
85 ; For SSE/MMX support:
96 (UNSPEC_NOP 45) ; prevents combiner cleverness
123 ; x87 Double output FP
124 (UNSPEC_SINCOS_COS 80)
125 (UNSPEC_SINCOS_SIN 81)
128 (UNSPEC_XTRACT_FRACT 84)
129 (UNSPEC_XTRACT_EXP 85)
130 (UNSPEC_FSCALE_FRACT 86)
131 (UNSPEC_FSCALE_EXP 87)
138 (UNSPEC_FRNDINT_FLOOR 96)
139 (UNSPEC_FRNDINT_CEIL 97)
140 (UNSPEC_FRNDINT_TRUNC 98)
141 (UNSPEC_FRNDINT_MASK_PM 99)
146 (UNSPEC_EH_RETURN 76)
150 [(UNSPECV_BLOCKAGE 0)
151 (UNSPECV_STACK_PROBE 10)
162 ;; Registers by name.
171 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
174 ;; In C guard expressions, put expressions which may be compile-time
175 ;; constants first. This allows for better optimization. For
176 ;; example, write "TARGET_64BIT && reload_completed", not
177 ;; "reload_completed && TARGET_64BIT".
180 ;; Processor type. This attribute must exactly match the processor_type
181 ;; enumeration in i386.h.
182 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
183 (const (symbol_ref "ix86_tune")))
185 ;; A basic instruction type. Refinements due to arguments to be
186 ;; provided in other attributes.
189 alu,alu1,negnot,imov,imovx,lea,
190 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
191 icmp,test,ibr,setcc,icmov,
192 push,pop,call,callv,leave,
194 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
195 sselog,sseiadd,sseishft,sseimul,
196 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
197 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
198 (const_string "other"))
200 ;; Main data type used by the insn
202 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
203 (const_string "unknown"))
205 ;; The CPU unit operations uses.
206 (define_attr "unit" "integer,i387,sse,mmx,unknown"
207 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
208 (const_string "i387")
209 (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
210 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
212 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
214 (eq_attr "type" "other")
215 (const_string "unknown")]
216 (const_string "integer")))
218 ;; The (bounding maximum) length of an instruction immediate.
219 (define_attr "length_immediate" ""
220 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
222 (eq_attr "unit" "i387,sse,mmx")
224 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
226 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
227 (eq_attr "type" "imov,test")
228 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
229 (eq_attr "type" "call")
230 (if_then_else (match_operand 0 "constant_call_address_operand" "")
233 (eq_attr "type" "callv")
234 (if_then_else (match_operand 1 "constant_call_address_operand" "")
237 ;; We don't know the size before shorten_branches. Expect
238 ;; the instruction to fit for better scheduling.
239 (eq_attr "type" "ibr")
242 (symbol_ref "/* Update immediate_length and other attributes! */
245 ;; The (bounding maximum) length of an instruction address.
246 (define_attr "length_address" ""
247 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
249 (and (eq_attr "type" "call")
250 (match_operand 0 "constant_call_address_operand" ""))
252 (and (eq_attr "type" "callv")
253 (match_operand 1 "constant_call_address_operand" ""))
256 (symbol_ref "ix86_attr_length_address_default (insn)")))
258 ;; Set when length prefix is used.
259 (define_attr "prefix_data16" ""
260 (if_then_else (ior (eq_attr "mode" "HI")
261 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
265 ;; Set when string REP prefix is used.
266 (define_attr "prefix_rep" ""
267 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
271 ;; Set when 0f opcode prefix is used.
272 (define_attr "prefix_0f" ""
274 (ior (eq_attr "type" "imovx,setcc,icmov")
275 (eq_attr "unit" "sse,mmx"))
279 ;; Set when REX opcode prefix is used.
280 (define_attr "prefix_rex" ""
281 (cond [(and (eq_attr "mode" "DI")
282 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
284 (and (eq_attr "mode" "QI")
285 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
288 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
294 ;; Set when modrm byte is used.
295 (define_attr "modrm" ""
296 (cond [(eq_attr "type" "str,cld,leave")
298 (eq_attr "unit" "i387")
300 (and (eq_attr "type" "incdec")
301 (ior (match_operand:SI 1 "register_operand" "")
302 (match_operand:HI 1 "register_operand" "")))
304 (and (eq_attr "type" "push")
305 (not (match_operand 1 "memory_operand" "")))
307 (and (eq_attr "type" "pop")
308 (not (match_operand 0 "memory_operand" "")))
310 (and (eq_attr "type" "imov")
311 (and (match_operand 0 "register_operand" "")
312 (match_operand 1 "immediate_operand" "")))
314 (and (eq_attr "type" "call")
315 (match_operand 0 "constant_call_address_operand" ""))
317 (and (eq_attr "type" "callv")
318 (match_operand 1 "constant_call_address_operand" ""))
323 ;; The (bounding maximum) length of an instruction in bytes.
324 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
325 ;; Later we may want to split them and compute proper length as for
327 (define_attr "length" ""
328 (cond [(eq_attr "type" "other,multi,fistp,frndint")
330 (eq_attr "type" "fcmp")
332 (eq_attr "unit" "i387")
334 (plus (attr "prefix_data16")
335 (attr "length_address")))]
336 (plus (plus (attr "modrm")
337 (plus (attr "prefix_0f")
338 (plus (attr "prefix_rex")
340 (plus (attr "prefix_rep")
341 (plus (attr "prefix_data16")
342 (plus (attr "length_immediate")
343 (attr "length_address")))))))
345 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
346 ;; `store' if there is a simple memory reference therein, or `unknown'
347 ;; if the instruction is complex.
349 (define_attr "memory" "none,load,store,both,unknown"
350 (cond [(eq_attr "type" "other,multi,str")
351 (const_string "unknown")
352 (eq_attr "type" "lea,fcmov,fpspc,cld")
353 (const_string "none")
354 (eq_attr "type" "fistp,leave")
355 (const_string "both")
356 (eq_attr "type" "frndint")
357 (const_string "load")
358 (eq_attr "type" "push")
359 (if_then_else (match_operand 1 "memory_operand" "")
360 (const_string "both")
361 (const_string "store"))
362 (eq_attr "type" "pop")
363 (if_then_else (match_operand 0 "memory_operand" "")
364 (const_string "both")
365 (const_string "load"))
366 (eq_attr "type" "setcc")
367 (if_then_else (match_operand 0 "memory_operand" "")
368 (const_string "store")
369 (const_string "none"))
370 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
371 (if_then_else (ior (match_operand 0 "memory_operand" "")
372 (match_operand 1 "memory_operand" ""))
373 (const_string "load")
374 (const_string "none"))
375 (eq_attr "type" "ibr")
376 (if_then_else (match_operand 0 "memory_operand" "")
377 (const_string "load")
378 (const_string "none"))
379 (eq_attr "type" "call")
380 (if_then_else (match_operand 0 "constant_call_address_operand" "")
381 (const_string "none")
382 (const_string "load"))
383 (eq_attr "type" "callv")
384 (if_then_else (match_operand 1 "constant_call_address_operand" "")
385 (const_string "none")
386 (const_string "load"))
387 (and (eq_attr "type" "alu1,negnot,ishift1")
388 (match_operand 1 "memory_operand" ""))
389 (const_string "both")
390 (and (match_operand 0 "memory_operand" "")
391 (match_operand 1 "memory_operand" ""))
392 (const_string "both")
393 (match_operand 0 "memory_operand" "")
394 (const_string "store")
395 (match_operand 1 "memory_operand" "")
396 (const_string "load")
398 "!alu1,negnot,ishift1,
399 imov,imovx,icmp,test,
401 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
402 mmx,mmxmov,mmxcmp,mmxcvt")
403 (match_operand 2 "memory_operand" ""))
404 (const_string "load")
405 (and (eq_attr "type" "icmov")
406 (match_operand 3 "memory_operand" ""))
407 (const_string "load")
409 (const_string "none")))
411 ;; Indicates if an instruction has both an immediate and a displacement.
413 (define_attr "imm_disp" "false,true,unknown"
414 (cond [(eq_attr "type" "other,multi")
415 (const_string "unknown")
416 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
417 (and (match_operand 0 "memory_displacement_operand" "")
418 (match_operand 1 "immediate_operand" "")))
419 (const_string "true")
420 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
421 (and (match_operand 0 "memory_displacement_operand" "")
422 (match_operand 2 "immediate_operand" "")))
423 (const_string "true")
425 (const_string "false")))
427 ;; Indicates if an FP operation has an integer source.
429 (define_attr "fp_int_src" "false,true"
430 (const_string "false"))
432 ;; Defines rounding mode of an FP operation.
434 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
435 (const_string "any"))
437 ;; Describe a user's asm statement.
438 (define_asm_attributes
439 [(set_attr "length" "128")
440 (set_attr "type" "multi")])
442 ;; Scheduling descriptions
444 (include "pentium.md")
447 (include "athlon.md")
450 ;; Operand and operator predicates
452 (include "predicates.md")
455 ;; Compare instructions.
457 ;; All compare insns have expanders that save the operands away without
458 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
459 ;; after the cmp) will actually emit the cmpM.
461 (define_expand "cmpdi"
462 [(set (reg:CC FLAGS_REG)
463 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
464 (match_operand:DI 1 "x86_64_general_operand" "")))]
467 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
468 operands[0] = force_reg (DImode, operands[0]);
469 ix86_compare_op0 = operands[0];
470 ix86_compare_op1 = operands[1];
474 (define_expand "cmpsi"
475 [(set (reg:CC FLAGS_REG)
476 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
477 (match_operand:SI 1 "general_operand" "")))]
480 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
481 operands[0] = force_reg (SImode, operands[0]);
482 ix86_compare_op0 = operands[0];
483 ix86_compare_op1 = operands[1];
487 (define_expand "cmphi"
488 [(set (reg:CC FLAGS_REG)
489 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
490 (match_operand:HI 1 "general_operand" "")))]
493 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494 operands[0] = force_reg (HImode, operands[0]);
495 ix86_compare_op0 = operands[0];
496 ix86_compare_op1 = operands[1];
500 (define_expand "cmpqi"
501 [(set (reg:CC FLAGS_REG)
502 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
503 (match_operand:QI 1 "general_operand" "")))]
506 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507 operands[0] = force_reg (QImode, operands[0]);
508 ix86_compare_op0 = operands[0];
509 ix86_compare_op1 = operands[1];
513 (define_insn "cmpdi_ccno_1_rex64"
515 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
516 (match_operand:DI 1 "const0_operand" "n,n")))]
517 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
519 test{q}\t{%0, %0|%0, %0}
520 cmp{q}\t{%1, %0|%0, %1}"
521 [(set_attr "type" "test,icmp")
522 (set_attr "length_immediate" "0,1")
523 (set_attr "mode" "DI")])
525 (define_insn "*cmpdi_minus_1_rex64"
527 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
528 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
530 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
531 "cmp{q}\t{%1, %0|%0, %1}"
532 [(set_attr "type" "icmp")
533 (set_attr "mode" "DI")])
535 (define_expand "cmpdi_1_rex64"
536 [(set (reg:CC FLAGS_REG)
537 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
538 (match_operand:DI 1 "general_operand" "")))]
542 (define_insn "cmpdi_1_insn_rex64"
544 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
545 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
546 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
547 "cmp{q}\t{%1, %0|%0, %1}"
548 [(set_attr "type" "icmp")
549 (set_attr "mode" "DI")])
552 (define_insn "*cmpsi_ccno_1"
554 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
555 (match_operand:SI 1 "const0_operand" "n,n")))]
556 "ix86_match_ccmode (insn, CCNOmode)"
558 test{l}\t{%0, %0|%0, %0}
559 cmp{l}\t{%1, %0|%0, %1}"
560 [(set_attr "type" "test,icmp")
561 (set_attr "length_immediate" "0,1")
562 (set_attr "mode" "SI")])
564 (define_insn "*cmpsi_minus_1"
566 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
567 (match_operand:SI 1 "general_operand" "ri,mr"))
569 "ix86_match_ccmode (insn, CCGOCmode)"
570 "cmp{l}\t{%1, %0|%0, %1}"
571 [(set_attr "type" "icmp")
572 (set_attr "mode" "SI")])
574 (define_expand "cmpsi_1"
575 [(set (reg:CC FLAGS_REG)
576 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577 (match_operand:SI 1 "general_operand" "ri,mr")))]
581 (define_insn "*cmpsi_1_insn"
583 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
584 (match_operand:SI 1 "general_operand" "ri,mr")))]
585 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
586 && ix86_match_ccmode (insn, CCmode)"
587 "cmp{l}\t{%1, %0|%0, %1}"
588 [(set_attr "type" "icmp")
589 (set_attr "mode" "SI")])
591 (define_insn "*cmphi_ccno_1"
593 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
594 (match_operand:HI 1 "const0_operand" "n,n")))]
595 "ix86_match_ccmode (insn, CCNOmode)"
597 test{w}\t{%0, %0|%0, %0}
598 cmp{w}\t{%1, %0|%0, %1}"
599 [(set_attr "type" "test,icmp")
600 (set_attr "length_immediate" "0,1")
601 (set_attr "mode" "HI")])
603 (define_insn "*cmphi_minus_1"
605 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
606 (match_operand:HI 1 "general_operand" "ri,mr"))
608 "ix86_match_ccmode (insn, CCGOCmode)"
609 "cmp{w}\t{%1, %0|%0, %1}"
610 [(set_attr "type" "icmp")
611 (set_attr "mode" "HI")])
613 (define_insn "*cmphi_1"
615 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616 (match_operand:HI 1 "general_operand" "ri,mr")))]
617 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
618 && ix86_match_ccmode (insn, CCmode)"
619 "cmp{w}\t{%1, %0|%0, %1}"
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "HI")])
623 (define_insn "*cmpqi_ccno_1"
625 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
626 (match_operand:QI 1 "const0_operand" "n,n")))]
627 "ix86_match_ccmode (insn, CCNOmode)"
629 test{b}\t{%0, %0|%0, %0}
630 cmp{b}\t{$0, %0|%0, 0}"
631 [(set_attr "type" "test,icmp")
632 (set_attr "length_immediate" "0,1")
633 (set_attr "mode" "QI")])
635 (define_insn "*cmpqi_1"
637 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
638 (match_operand:QI 1 "general_operand" "qi,mq")))]
639 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
640 && ix86_match_ccmode (insn, CCmode)"
641 "cmp{b}\t{%1, %0|%0, %1}"
642 [(set_attr "type" "icmp")
643 (set_attr "mode" "QI")])
645 (define_insn "*cmpqi_minus_1"
647 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648 (match_operand:QI 1 "general_operand" "qi,mq"))
650 "ix86_match_ccmode (insn, CCGOCmode)"
651 "cmp{b}\t{%1, %0|%0, %1}"
652 [(set_attr "type" "icmp")
653 (set_attr "mode" "QI")])
655 (define_insn "*cmpqi_ext_1"
658 (match_operand:QI 0 "general_operand" "Qm")
661 (match_operand 1 "ext_register_operand" "Q")
664 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665 "cmp{b}\t{%h1, %0|%0, %h1}"
666 [(set_attr "type" "icmp")
667 (set_attr "mode" "QI")])
669 (define_insn "*cmpqi_ext_1_rex64"
672 (match_operand:QI 0 "register_operand" "Q")
675 (match_operand 1 "ext_register_operand" "Q")
678 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679 "cmp{b}\t{%h1, %0|%0, %h1}"
680 [(set_attr "type" "icmp")
681 (set_attr "mode" "QI")])
683 (define_insn "*cmpqi_ext_2"
688 (match_operand 0 "ext_register_operand" "Q")
691 (match_operand:QI 1 "const0_operand" "n")))]
692 "ix86_match_ccmode (insn, CCNOmode)"
694 [(set_attr "type" "test")
695 (set_attr "length_immediate" "0")
696 (set_attr "mode" "QI")])
698 (define_expand "cmpqi_ext_3"
699 [(set (reg:CC FLAGS_REG)
703 (match_operand 0 "ext_register_operand" "")
706 (match_operand:QI 1 "general_operand" "")))]
710 (define_insn "cmpqi_ext_3_insn"
715 (match_operand 0 "ext_register_operand" "Q")
718 (match_operand:QI 1 "general_operand" "Qmn")))]
719 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
720 "cmp{b}\t{%1, %h0|%h0, %1}"
721 [(set_attr "type" "icmp")
722 (set_attr "mode" "QI")])
724 (define_insn "cmpqi_ext_3_insn_rex64"
729 (match_operand 0 "ext_register_operand" "Q")
732 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
733 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
734 "cmp{b}\t{%1, %h0|%h0, %1}"
735 [(set_attr "type" "icmp")
736 (set_attr "mode" "QI")])
738 (define_insn "*cmpqi_ext_4"
743 (match_operand 0 "ext_register_operand" "Q")
748 (match_operand 1 "ext_register_operand" "Q")
751 "ix86_match_ccmode (insn, CCmode)"
752 "cmp{b}\t{%h1, %h0|%h0, %h1}"
753 [(set_attr "type" "icmp")
754 (set_attr "mode" "QI")])
756 ;; These implement float point compares.
757 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
758 ;; which would allow mix and match FP modes on the compares. Which is what
759 ;; the old patterns did, but with many more of them.
761 (define_expand "cmpxf"
762 [(set (reg:CC FLAGS_REG)
763 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
764 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
767 ix86_compare_op0 = operands[0];
768 ix86_compare_op1 = operands[1];
772 (define_expand "cmpdf"
773 [(set (reg:CC FLAGS_REG)
774 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
775 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
776 "TARGET_80387 || TARGET_SSE2"
778 ix86_compare_op0 = operands[0];
779 ix86_compare_op1 = operands[1];
783 (define_expand "cmpsf"
784 [(set (reg:CC FLAGS_REG)
785 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
786 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
787 "TARGET_80387 || TARGET_SSE"
789 ix86_compare_op0 = operands[0];
790 ix86_compare_op1 = operands[1];
794 ;; FP compares, step 1:
795 ;; Set the FP condition codes.
797 ;; CCFPmode compare with exceptions
798 ;; CCFPUmode compare with no exceptions
800 (define_insn "*cmpfp_0_sf"
801 [(set (match_operand:HI 0 "register_operand" "=a")
804 (match_operand:SF 1 "register_operand" "f")
805 (match_operand:SF 2 "const0_operand" "X"))]
809 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
811 output_asm_insn ("ftst\;fnstsw\t%0", operands);
812 return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
815 return "ftst\;fnstsw\t%0";
817 [(set_attr "type" "multi")
818 (set_attr "mode" "SF")])
820 (define_insn "*cmpfp_0_df"
821 [(set (match_operand:HI 0 "register_operand" "=a")
824 (match_operand:DF 1 "register_operand" "f")
825 (match_operand:DF 2 "const0_operand" "X"))]
829 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
831 output_asm_insn ("ftst\;fnstsw\t%0", operands);
832 return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
835 return "ftst\;fnstsw\t%0";
837 [(set_attr "type" "multi")
838 (set_attr "mode" "DF")])
840 (define_insn "*cmpfp_0_xf"
841 [(set (match_operand:HI 0 "register_operand" "=a")
844 (match_operand:XF 1 "register_operand" "f")
845 (match_operand:XF 2 "const0_operand" "X"))]
849 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
851 output_asm_insn ("ftst\;fnstsw\t%0", operands);
852 return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
855 return "ftst\;fnstsw\t%0";
857 [(set_attr "type" "multi")
858 (set_attr "mode" "XF")])
860 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
861 ;; used to manage the reg stack popping would not be preserved.
863 (define_insn "*cmpfp_2_sf"
864 [(set (reg:CCFP FPSR_REG)
866 (match_operand:SF 0 "register_operand" "f")
867 (match_operand:SF 1 "nonimmediate_operand" "fm")))]
869 "* return output_fp_compare (insn, operands, 0, 0);"
870 [(set_attr "type" "fcmp")
871 (set_attr "mode" "SF")])
873 (define_insn "*cmpfp_2_sf_1"
874 [(set (match_operand:HI 0 "register_operand" "=a")
877 (match_operand:SF 1 "register_operand" "f")
878 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
881 "* return output_fp_compare (insn, operands, 2, 0);"
882 [(set_attr "type" "fcmp")
883 (set_attr "mode" "SF")])
885 (define_insn "*cmpfp_2_df"
886 [(set (reg:CCFP FPSR_REG)
888 (match_operand:DF 0 "register_operand" "f")
889 (match_operand:DF 1 "nonimmediate_operand" "fm")))]
891 "* return output_fp_compare (insn, operands, 0, 0);"
892 [(set_attr "type" "fcmp")
893 (set_attr "mode" "DF")])
895 (define_insn "*cmpfp_2_df_1"
896 [(set (match_operand:HI 0 "register_operand" "=a")
899 (match_operand:DF 1 "register_operand" "f")
900 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
903 "* return output_fp_compare (insn, operands, 2, 0);"
904 [(set_attr "type" "multi")
905 (set_attr "mode" "DF")])
907 (define_insn "*cmpfp_2_xf"
908 [(set (reg:CCFP FPSR_REG)
910 (match_operand:XF 0 "register_operand" "f")
911 (match_operand:XF 1 "register_operand" "f")))]
913 "* return output_fp_compare (insn, operands, 0, 0);"
914 [(set_attr "type" "fcmp")
915 (set_attr "mode" "XF")])
917 (define_insn "*cmpfp_2_xf_1"
918 [(set (match_operand:HI 0 "register_operand" "=a")
921 (match_operand:XF 1 "register_operand" "f")
922 (match_operand:XF 2 "register_operand" "f"))]
925 "* return output_fp_compare (insn, operands, 2, 0);"
926 [(set_attr "type" "multi")
927 (set_attr "mode" "XF")])
929 (define_insn "*cmpfp_2u"
930 [(set (reg:CCFPU FPSR_REG)
932 (match_operand 0 "register_operand" "f")
933 (match_operand 1 "register_operand" "f")))]
935 && FLOAT_MODE_P (GET_MODE (operands[0]))
936 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
937 "* return output_fp_compare (insn, operands, 0, 1);"
938 [(set_attr "type" "fcmp")
940 (cond [(match_operand:SF 1 "" "")
942 (match_operand:DF 1 "" "")
945 (const_string "XF")))])
947 (define_insn "*cmpfp_2u_1"
948 [(set (match_operand:HI 0 "register_operand" "=a")
951 (match_operand 1 "register_operand" "f")
952 (match_operand 2 "register_operand" "f"))]
955 && FLOAT_MODE_P (GET_MODE (operands[1]))
956 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
957 "* return output_fp_compare (insn, operands, 2, 1);"
958 [(set_attr "type" "multi")
960 (cond [(match_operand:SF 1 "" "")
962 (match_operand:DF 1 "" "")
965 (const_string "XF")))])
967 ;; Patterns to match the SImode-in-memory ficom instructions.
969 ;; %%% Play games with accepting gp registers, as otherwise we have to
970 ;; force them to memory during rtl generation, which is no good. We
971 ;; can get rid of this once we teach reload to do memory input reloads
974 (define_insn "*ficom_1"
975 [(set (reg:CCFP FPSR_REG)
977 (match_operand 0 "register_operand" "f,f")
978 (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
979 "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
980 && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
983 ;; Split the not-really-implemented gp register case into a
984 ;; push-op-pop sequence.
986 ;; %%% This is most efficient, but am I gonna get in trouble
987 ;; for separating cc0_setter and cc0_user?
990 [(set (reg:CCFP FPSR_REG)
992 (match_operand:SF 0 "register_operand" "")
993 (float (match_operand:SI 1 "register_operand" ""))))]
994 "0 && TARGET_80387 && reload_completed"
995 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 1))
996 (set (reg:CCFP FPSR_REG) (compare:CCFP (match_dup 0) (match_dup 2)))
997 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
998 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
999 "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1000 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
1002 ;; FP compares, step 2
1003 ;; Move the fpsw to ax.
1005 (define_insn "x86_fnstsw_1"
1006 [(set (match_operand:HI 0 "register_operand" "=a")
1007 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1010 [(set_attr "length" "2")
1011 (set_attr "mode" "SI")
1012 (set_attr "unit" "i387")])
1014 ;; FP compares, step 3
1015 ;; Get ax into flags, general case.
1017 (define_insn "x86_sahf_1"
1018 [(set (reg:CC FLAGS_REG)
1019 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
1022 [(set_attr "length" "1")
1023 (set_attr "athlon_decode" "vector")
1024 (set_attr "mode" "SI")])
1026 ;; Pentium Pro can do steps 1 through 3 in one go.
1028 (define_insn "*cmpfp_i"
1029 [(set (reg:CCFP FLAGS_REG)
1030 (compare:CCFP (match_operand 0 "register_operand" "f")
1031 (match_operand 1 "register_operand" "f")))]
1032 "TARGET_80387 && TARGET_CMOVE
1033 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1034 && FLOAT_MODE_P (GET_MODE (operands[0]))
1035 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1036 "* return output_fp_compare (insn, operands, 1, 0);"
1037 [(set_attr "type" "fcmp")
1039 (cond [(match_operand:SF 1 "" "")
1041 (match_operand:DF 1 "" "")
1044 (const_string "XF")))
1045 (set_attr "athlon_decode" "vector")])
1047 (define_insn "*cmpfp_i_sse"
1048 [(set (reg:CCFP FLAGS_REG)
1049 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1050 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1052 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1053 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1054 "* return output_fp_compare (insn, operands, 1, 0);"
1055 [(set_attr "type" "fcmp,ssecomi")
1057 (if_then_else (match_operand:SF 1 "" "")
1059 (const_string "DF")))
1060 (set_attr "athlon_decode" "vector")])
1062 (define_insn "*cmpfp_i_sse_only"
1063 [(set (reg:CCFP FLAGS_REG)
1064 (compare:CCFP (match_operand 0 "register_operand" "x")
1065 (match_operand 1 "nonimmediate_operand" "xm")))]
1066 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067 && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1068 "* return output_fp_compare (insn, operands, 1, 0);"
1069 [(set_attr "type" "ssecomi")
1071 (if_then_else (match_operand:SF 1 "" "")
1073 (const_string "DF")))
1074 (set_attr "athlon_decode" "vector")])
1076 (define_insn "*cmpfp_iu"
1077 [(set (reg:CCFPU FLAGS_REG)
1078 (compare:CCFPU (match_operand 0 "register_operand" "f")
1079 (match_operand 1 "register_operand" "f")))]
1080 "TARGET_80387 && TARGET_CMOVE
1081 && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1082 && FLOAT_MODE_P (GET_MODE (operands[0]))
1083 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1084 "* return output_fp_compare (insn, operands, 1, 1);"
1085 [(set_attr "type" "fcmp")
1087 (cond [(match_operand:SF 1 "" "")
1089 (match_operand:DF 1 "" "")
1092 (const_string "XF")))
1093 (set_attr "athlon_decode" "vector")])
1095 (define_insn "*cmpfp_iu_sse"
1096 [(set (reg:CCFPU FLAGS_REG)
1097 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1098 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1100 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1101 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1102 "* return output_fp_compare (insn, operands, 1, 1);"
1103 [(set_attr "type" "fcmp,ssecomi")
1105 (if_then_else (match_operand:SF 1 "" "")
1107 (const_string "DF")))
1108 (set_attr "athlon_decode" "vector")])
1110 (define_insn "*cmpfp_iu_sse_only"
1111 [(set (reg:CCFPU FLAGS_REG)
1112 (compare:CCFPU (match_operand 0 "register_operand" "x")
1113 (match_operand 1 "nonimmediate_operand" "xm")))]
1114 "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1115 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1116 "* return output_fp_compare (insn, operands, 1, 1);"
1117 [(set_attr "type" "ssecomi")
1119 (if_then_else (match_operand:SF 1 "" "")
1121 (const_string "DF")))
1122 (set_attr "athlon_decode" "vector")])
1124 ;; Move instructions.
1126 ;; General case of fullword move.
1128 (define_expand "movsi"
1129 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1130 (match_operand:SI 1 "general_operand" ""))]
1132 "ix86_expand_move (SImode, operands); DONE;")
1134 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1137 ;; %%% We don't use a post-inc memory reference because x86 is not a
1138 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1139 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1140 ;; targets without our curiosities, and it is just as easy to represent
1141 ;; this differently.
1143 (define_insn "*pushsi2"
1144 [(set (match_operand:SI 0 "push_operand" "=<")
1145 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1148 [(set_attr "type" "push")
1149 (set_attr "mode" "SI")])
1151 ;; For 64BIT abi we always round up to 8 bytes.
1152 (define_insn "*pushsi2_rex64"
1153 [(set (match_operand:SI 0 "push_operand" "=X")
1154 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1157 [(set_attr "type" "push")
1158 (set_attr "mode" "SI")])
1160 (define_insn "*pushsi2_prologue"
1161 [(set (match_operand:SI 0 "push_operand" "=<")
1162 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1163 (clobber (mem:BLK (scratch)))]
1166 [(set_attr "type" "push")
1167 (set_attr "mode" "SI")])
1169 (define_insn "*popsi1_epilogue"
1170 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1171 (mem:SI (reg:SI SP_REG)))
1172 (set (reg:SI SP_REG)
1173 (plus:SI (reg:SI SP_REG) (const_int 4)))
1174 (clobber (mem:BLK (scratch)))]
1177 [(set_attr "type" "pop")
1178 (set_attr "mode" "SI")])
1180 (define_insn "popsi1"
1181 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1182 (mem:SI (reg:SI SP_REG)))
1183 (set (reg:SI SP_REG)
1184 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1187 [(set_attr "type" "pop")
1188 (set_attr "mode" "SI")])
1190 (define_insn "*movsi_xor"
1191 [(set (match_operand:SI 0 "register_operand" "=r")
1192 (match_operand:SI 1 "const0_operand" "i"))
1193 (clobber (reg:CC FLAGS_REG))]
1194 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1195 "xor{l}\t{%0, %0|%0, %0}"
1196 [(set_attr "type" "alu1")
1197 (set_attr "mode" "SI")
1198 (set_attr "length_immediate" "0")])
1200 (define_insn "*movsi_or"
1201 [(set (match_operand:SI 0 "register_operand" "=r")
1202 (match_operand:SI 1 "immediate_operand" "i"))
1203 (clobber (reg:CC FLAGS_REG))]
1205 && operands[1] == constm1_rtx
1206 && (TARGET_PENTIUM || optimize_size)"
1208 operands[1] = constm1_rtx;
1209 return "or{l}\t{%1, %0|%0, %1}";
1211 [(set_attr "type" "alu1")
1212 (set_attr "mode" "SI")
1213 (set_attr "length_immediate" "1")])
1215 (define_insn "*movsi_1"
1216 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1217 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1218 "(TARGET_INTER_UNIT_MOVES || optimize_size)
1219 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1221 switch (get_attr_type (insn))
1224 if (get_attr_mode (insn) == MODE_TI)
1225 return "movdqa\t{%1, %0|%0, %1}";
1226 return "movd\t{%1, %0|%0, %1}";
1229 if (get_attr_mode (insn) == MODE_DI)
1230 return "movq\t{%1, %0|%0, %1}";
1231 return "movd\t{%1, %0|%0, %1}";
1234 return "lea{l}\t{%1, %0|%0, %1}";
1237 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1239 return "mov{l}\t{%1, %0|%0, %1}";
1243 (cond [(eq_attr "alternative" "2,3,4")
1244 (const_string "mmxmov")
1245 (eq_attr "alternative" "5,6,7")
1246 (const_string "ssemov")
1247 (and (ne (symbol_ref "flag_pic") (const_int 0))
1248 (match_operand:SI 1 "symbolic_operand" ""))
1249 (const_string "lea")
1251 (const_string "imov")))
1252 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1254 (define_insn "*movsi_1_nointernunit"
1255 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1256 (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1257 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1258 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1260 switch (get_attr_type (insn))
1263 if (get_attr_mode (insn) == MODE_TI)
1264 return "movdqa\t{%1, %0|%0, %1}";
1265 return "movd\t{%1, %0|%0, %1}";
1268 if (get_attr_mode (insn) == MODE_DI)
1269 return "movq\t{%1, %0|%0, %1}";
1270 return "movd\t{%1, %0|%0, %1}";
1273 return "lea{l}\t{%1, %0|%0, %1}";
1276 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1278 return "mov{l}\t{%1, %0|%0, %1}";
1282 (cond [(eq_attr "alternative" "2,3,4")
1283 (const_string "mmxmov")
1284 (eq_attr "alternative" "5,6,7")
1285 (const_string "ssemov")
1286 (and (ne (symbol_ref "flag_pic") (const_int 0))
1287 (match_operand:SI 1 "symbolic_operand" ""))
1288 (const_string "lea")
1290 (const_string "imov")))
1291 (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1293 ;; Stores and loads of ax to arbitrary constant address.
1294 ;; We fake an second form of instruction to force reload to load address
1295 ;; into register when rax is not available
1296 (define_insn "*movabssi_1_rex64"
1297 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1298 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1299 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1301 movabs{l}\t{%1, %P0|%P0, %1}
1302 mov{l}\t{%1, %a0|%a0, %1}"
1303 [(set_attr "type" "imov")
1304 (set_attr "modrm" "0,*")
1305 (set_attr "length_address" "8,0")
1306 (set_attr "length_immediate" "0,*")
1307 (set_attr "memory" "store")
1308 (set_attr "mode" "SI")])
1310 (define_insn "*movabssi_2_rex64"
1311 [(set (match_operand:SI 0 "register_operand" "=a,r")
1312 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1313 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1315 movabs{l}\t{%P1, %0|%0, %P1}
1316 mov{l}\t{%a1, %0|%0, %a1}"
1317 [(set_attr "type" "imov")
1318 (set_attr "modrm" "0,*")
1319 (set_attr "length_address" "8,0")
1320 (set_attr "length_immediate" "0")
1321 (set_attr "memory" "load")
1322 (set_attr "mode" "SI")])
1324 (define_insn "*swapsi"
1325 [(set (match_operand:SI 0 "register_operand" "+r")
1326 (match_operand:SI 1 "register_operand" "+r"))
1331 [(set_attr "type" "imov")
1332 (set_attr "pent_pair" "np")
1333 (set_attr "athlon_decode" "vector")
1334 (set_attr "mode" "SI")
1335 (set_attr "modrm" "0")])
1337 (define_expand "movhi"
1338 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1339 (match_operand:HI 1 "general_operand" ""))]
1341 "ix86_expand_move (HImode, operands); DONE;")
1343 (define_insn "*pushhi2"
1344 [(set (match_operand:HI 0 "push_operand" "=<,<")
1345 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1348 push{w}\t{|WORD PTR }%1
1350 [(set_attr "type" "push")
1351 (set_attr "mode" "HI")])
1353 ;; For 64BIT abi we always round up to 8 bytes.
1354 (define_insn "*pushhi2_rex64"
1355 [(set (match_operand:HI 0 "push_operand" "=X")
1356 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1359 [(set_attr "type" "push")
1360 (set_attr "mode" "QI")])
1362 (define_insn "*movhi_1"
1363 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1364 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1365 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1367 switch (get_attr_type (insn))
1370 /* movzwl is faster than movw on p2 due to partial word stalls,
1371 though not as fast as an aligned movl. */
1372 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1374 if (get_attr_mode (insn) == MODE_SI)
1375 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1377 return "mov{w}\t{%1, %0|%0, %1}";
1381 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1382 (const_string "imov")
1383 (and (eq_attr "alternative" "0")
1384 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1386 (eq (symbol_ref "TARGET_HIMODE_MATH")
1388 (const_string "imov")
1389 (and (eq_attr "alternative" "1,2")
1390 (match_operand:HI 1 "aligned_operand" ""))
1391 (const_string "imov")
1392 (and (ne (symbol_ref "TARGET_MOVX")
1394 (eq_attr "alternative" "0,2"))
1395 (const_string "imovx")
1397 (const_string "imov")))
1399 (cond [(eq_attr "type" "imovx")
1401 (and (eq_attr "alternative" "1,2")
1402 (match_operand:HI 1 "aligned_operand" ""))
1404 (and (eq_attr "alternative" "0")
1405 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1407 (eq (symbol_ref "TARGET_HIMODE_MATH")
1411 (const_string "HI")))])
1413 ;; Stores and loads of ax to arbitrary constant address.
1414 ;; We fake an second form of instruction to force reload to load address
1415 ;; into register when rax is not available
1416 (define_insn "*movabshi_1_rex64"
1417 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1418 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1419 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1421 movabs{w}\t{%1, %P0|%P0, %1}
1422 mov{w}\t{%1, %a0|%a0, %1}"
1423 [(set_attr "type" "imov")
1424 (set_attr "modrm" "0,*")
1425 (set_attr "length_address" "8,0")
1426 (set_attr "length_immediate" "0,*")
1427 (set_attr "memory" "store")
1428 (set_attr "mode" "HI")])
1430 (define_insn "*movabshi_2_rex64"
1431 [(set (match_operand:HI 0 "register_operand" "=a,r")
1432 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1433 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1435 movabs{w}\t{%P1, %0|%0, %P1}
1436 mov{w}\t{%a1, %0|%0, %a1}"
1437 [(set_attr "type" "imov")
1438 (set_attr "modrm" "0,*")
1439 (set_attr "length_address" "8,0")
1440 (set_attr "length_immediate" "0")
1441 (set_attr "memory" "load")
1442 (set_attr "mode" "HI")])
1444 (define_insn "*swaphi_1"
1445 [(set (match_operand:HI 0 "register_operand" "+r")
1446 (match_operand:HI 1 "register_operand" "+r"))
1449 "TARGET_PARTIAL_REG_STALL"
1451 [(set_attr "type" "imov")
1452 (set_attr "pent_pair" "np")
1453 (set_attr "mode" "HI")
1454 (set_attr "modrm" "0")])
1456 (define_insn "*swaphi_2"
1457 [(set (match_operand:HI 0 "register_operand" "+r")
1458 (match_operand:HI 1 "register_operand" "+r"))
1461 "! TARGET_PARTIAL_REG_STALL"
1463 [(set_attr "type" "imov")
1464 (set_attr "pent_pair" "np")
1465 (set_attr "mode" "SI")
1466 (set_attr "modrm" "0")])
1468 (define_expand "movstricthi"
1469 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1470 (match_operand:HI 1 "general_operand" ""))]
1471 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1473 /* Don't generate memory->memory moves, go through a register */
1474 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1475 operands[1] = force_reg (HImode, operands[1]);
1478 (define_insn "*movstricthi_1"
1479 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1480 (match_operand:HI 1 "general_operand" "rn,m"))]
1481 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1482 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1483 "mov{w}\t{%1, %0|%0, %1}"
1484 [(set_attr "type" "imov")
1485 (set_attr "mode" "HI")])
1487 (define_insn "*movstricthi_xor"
1488 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1489 (match_operand:HI 1 "const0_operand" "i"))
1490 (clobber (reg:CC FLAGS_REG))]
1492 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1493 "xor{w}\t{%0, %0|%0, %0}"
1494 [(set_attr "type" "alu1")
1495 (set_attr "mode" "HI")
1496 (set_attr "length_immediate" "0")])
1498 (define_expand "movqi"
1499 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1500 (match_operand:QI 1 "general_operand" ""))]
1502 "ix86_expand_move (QImode, operands); DONE;")
1504 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1505 ;; "push a byte". But actually we use pushw, which has the effect
1506 ;; of rounding the amount pushed up to a halfword.
1508 (define_insn "*pushqi2"
1509 [(set (match_operand:QI 0 "push_operand" "=X,X")
1510 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1513 push{w}\t{|word ptr }%1
1515 [(set_attr "type" "push")
1516 (set_attr "mode" "HI")])
1518 ;; For 64BIT abi we always round up to 8 bytes.
1519 (define_insn "*pushqi2_rex64"
1520 [(set (match_operand:QI 0 "push_operand" "=X")
1521 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1524 [(set_attr "type" "push")
1525 (set_attr "mode" "QI")])
1527 ;; Situation is quite tricky about when to choose full sized (SImode) move
1528 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1529 ;; partial register dependency machines (such as AMD Athlon), where QImode
1530 ;; moves issue extra dependency and for partial register stalls machines
1531 ;; that don't use QImode patterns (and QImode move cause stall on the next
1534 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1535 ;; register stall machines with, where we use QImode instructions, since
1536 ;; partial register stall can be caused there. Then we use movzx.
1537 (define_insn "*movqi_1"
1538 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1539 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1540 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1542 switch (get_attr_type (insn))
1545 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1547 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1549 if (get_attr_mode (insn) == MODE_SI)
1550 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1552 return "mov{b}\t{%1, %0|%0, %1}";
1556 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1557 (const_string "imov")
1558 (and (eq_attr "alternative" "3")
1559 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1561 (eq (symbol_ref "TARGET_QIMODE_MATH")
1563 (const_string "imov")
1564 (eq_attr "alternative" "3,5")
1565 (const_string "imovx")
1566 (and (ne (symbol_ref "TARGET_MOVX")
1568 (eq_attr "alternative" "2"))
1569 (const_string "imovx")
1571 (const_string "imov")))
1573 (cond [(eq_attr "alternative" "3,4,5")
1575 (eq_attr "alternative" "6")
1577 (eq_attr "type" "imovx")
1579 (and (eq_attr "type" "imov")
1580 (and (eq_attr "alternative" "0,1,2")
1581 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1584 ;; Avoid partial register stalls when not using QImode arithmetic
1585 (and (eq_attr "type" "imov")
1586 (and (eq_attr "alternative" "0,1,2")
1587 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1589 (eq (symbol_ref "TARGET_QIMODE_MATH")
1593 (const_string "QI")))])
1595 (define_expand "reload_outqi"
1596 [(parallel [(match_operand:QI 0 "" "=m")
1597 (match_operand:QI 1 "register_operand" "r")
1598 (match_operand:QI 2 "register_operand" "=&q")])]
1602 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1604 if (reg_overlap_mentioned_p (op2, op0))
1606 if (! q_regs_operand (op1, QImode))
1608 emit_insn (gen_movqi (op2, op1));
1611 emit_insn (gen_movqi (op0, op1));
1615 (define_insn "*swapqi"
1616 [(set (match_operand:QI 0 "register_operand" "+r")
1617 (match_operand:QI 1 "register_operand" "+r"))
1622 [(set_attr "type" "imov")
1623 (set_attr "pent_pair" "np")
1624 (set_attr "mode" "QI")
1625 (set_attr "modrm" "0")])
1627 (define_expand "movstrictqi"
1628 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1629 (match_operand:QI 1 "general_operand" ""))]
1630 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1632 /* Don't generate memory->memory moves, go through a register. */
1633 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1634 operands[1] = force_reg (QImode, operands[1]);
1637 (define_insn "*movstrictqi_1"
1638 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1639 (match_operand:QI 1 "general_operand" "*qn,m"))]
1640 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1641 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1642 "mov{b}\t{%1, %0|%0, %1}"
1643 [(set_attr "type" "imov")
1644 (set_attr "mode" "QI")])
1646 (define_insn "*movstrictqi_xor"
1647 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1648 (match_operand:QI 1 "const0_operand" "i"))
1649 (clobber (reg:CC FLAGS_REG))]
1650 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1651 "xor{b}\t{%0, %0|%0, %0}"
1652 [(set_attr "type" "alu1")
1653 (set_attr "mode" "QI")
1654 (set_attr "length_immediate" "0")])
1656 (define_insn "*movsi_extv_1"
1657 [(set (match_operand:SI 0 "register_operand" "=R")
1658 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1662 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1663 [(set_attr "type" "imovx")
1664 (set_attr "mode" "SI")])
1666 (define_insn "*movhi_extv_1"
1667 [(set (match_operand:HI 0 "register_operand" "=R")
1668 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1672 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1673 [(set_attr "type" "imovx")
1674 (set_attr "mode" "SI")])
1676 (define_insn "*movqi_extv_1"
1677 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1678 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1683 switch (get_attr_type (insn))
1686 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1688 return "mov{b}\t{%h1, %0|%0, %h1}";
1692 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1693 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1694 (ne (symbol_ref "TARGET_MOVX")
1696 (const_string "imovx")
1697 (const_string "imov")))
1699 (if_then_else (eq_attr "type" "imovx")
1701 (const_string "QI")))])
1703 (define_insn "*movqi_extv_1_rex64"
1704 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1705 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1710 switch (get_attr_type (insn))
1713 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1715 return "mov{b}\t{%h1, %0|%0, %h1}";
1719 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1720 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1721 (ne (symbol_ref "TARGET_MOVX")
1723 (const_string "imovx")
1724 (const_string "imov")))
1726 (if_then_else (eq_attr "type" "imovx")
1728 (const_string "QI")))])
1730 ;; Stores and loads of ax to arbitrary constant address.
1731 ;; We fake an second form of instruction to force reload to load address
1732 ;; into register when rax is not available
1733 (define_insn "*movabsqi_1_rex64"
1734 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1735 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1736 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1738 movabs{b}\t{%1, %P0|%P0, %1}
1739 mov{b}\t{%1, %a0|%a0, %1}"
1740 [(set_attr "type" "imov")
1741 (set_attr "modrm" "0,*")
1742 (set_attr "length_address" "8,0")
1743 (set_attr "length_immediate" "0,*")
1744 (set_attr "memory" "store")
1745 (set_attr "mode" "QI")])
1747 (define_insn "*movabsqi_2_rex64"
1748 [(set (match_operand:QI 0 "register_operand" "=a,r")
1749 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1750 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1752 movabs{b}\t{%P1, %0|%0, %P1}
1753 mov{b}\t{%a1, %0|%0, %a1}"
1754 [(set_attr "type" "imov")
1755 (set_attr "modrm" "0,*")
1756 (set_attr "length_address" "8,0")
1757 (set_attr "length_immediate" "0")
1758 (set_attr "memory" "load")
1759 (set_attr "mode" "QI")])
1761 (define_insn "*movsi_extzv_1"
1762 [(set (match_operand:SI 0 "register_operand" "=R")
1763 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1767 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1768 [(set_attr "type" "imovx")
1769 (set_attr "mode" "SI")])
1771 (define_insn "*movqi_extzv_2"
1772 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1773 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1778 switch (get_attr_type (insn))
1781 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1783 return "mov{b}\t{%h1, %0|%0, %h1}";
1787 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1788 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789 (ne (symbol_ref "TARGET_MOVX")
1791 (const_string "imovx")
1792 (const_string "imov")))
1794 (if_then_else (eq_attr "type" "imovx")
1796 (const_string "QI")))])
1798 (define_insn "*movqi_extzv_2_rex64"
1799 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1800 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1805 switch (get_attr_type (insn))
1808 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1810 return "mov{b}\t{%h1, %0|%0, %h1}";
1814 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1815 (ne (symbol_ref "TARGET_MOVX")
1817 (const_string "imovx")
1818 (const_string "imov")))
1820 (if_then_else (eq_attr "type" "imovx")
1822 (const_string "QI")))])
1824 (define_insn "movsi_insv_1"
1825 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1828 (match_operand:SI 1 "general_operand" "Qmn"))]
1830 "mov{b}\t{%b1, %h0|%h0, %b1}"
1831 [(set_attr "type" "imov")
1832 (set_attr "mode" "QI")])
1834 (define_insn "movdi_insv_1_rex64"
1835 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1838 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1840 "mov{b}\t{%b1, %h0|%h0, %b1}"
1841 [(set_attr "type" "imov")
1842 (set_attr "mode" "QI")])
1844 (define_insn "*movqi_insv_2"
1845 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1848 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1851 "mov{b}\t{%h1, %h0|%h0, %h1}"
1852 [(set_attr "type" "imov")
1853 (set_attr "mode" "QI")])
1855 (define_expand "movdi"
1856 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1857 (match_operand:DI 1 "general_operand" ""))]
1859 "ix86_expand_move (DImode, operands); DONE;")
1861 (define_insn "*pushdi"
1862 [(set (match_operand:DI 0 "push_operand" "=<")
1863 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1867 (define_insn "pushdi2_rex64"
1868 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1869 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1874 [(set_attr "type" "push,multi")
1875 (set_attr "mode" "DI")])
1877 ;; Convert impossible pushes of immediate to existing instructions.
1878 ;; First try to get scratch register and go through it. In case this
1879 ;; fails, push sign extended lower part first and then overwrite
1880 ;; upper part by 32bit move.
1882 [(match_scratch:DI 2 "r")
1883 (set (match_operand:DI 0 "push_operand" "")
1884 (match_operand:DI 1 "immediate_operand" ""))]
1885 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1886 && !x86_64_immediate_operand (operands[1], DImode)"
1887 [(set (match_dup 2) (match_dup 1))
1888 (set (match_dup 0) (match_dup 2))]
1891 ;; We need to define this as both peepholer and splitter for case
1892 ;; peephole2 pass is not run.
1894 [(set (match_operand:DI 0 "push_operand" "")
1895 (match_operand:DI 1 "immediate_operand" ""))]
1896 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1897 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1898 [(set (match_dup 0) (match_dup 1))
1899 (set (match_dup 2) (match_dup 3))]
1900 "split_di (operands + 1, 1, operands + 2, operands + 3);
1901 operands[1] = gen_lowpart (DImode, operands[2]);
1902 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1907 [(set (match_operand:DI 0 "push_operand" "")
1908 (match_operand:DI 1 "immediate_operand" ""))]
1909 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1910 && !symbolic_operand (operands[1], DImode)
1911 && !x86_64_immediate_operand (operands[1], DImode)"
1912 [(set (match_dup 0) (match_dup 1))
1913 (set (match_dup 2) (match_dup 3))]
1914 "split_di (operands + 1, 1, operands + 2, operands + 3);
1915 operands[1] = gen_lowpart (DImode, operands[2]);
1916 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1920 (define_insn "*pushdi2_prologue_rex64"
1921 [(set (match_operand:DI 0 "push_operand" "=<")
1922 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1923 (clobber (mem:BLK (scratch)))]
1926 [(set_attr "type" "push")
1927 (set_attr "mode" "DI")])
1929 (define_insn "*popdi1_epilogue_rex64"
1930 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1931 (mem:DI (reg:DI SP_REG)))
1932 (set (reg:DI SP_REG)
1933 (plus:DI (reg:DI SP_REG) (const_int 8)))
1934 (clobber (mem:BLK (scratch)))]
1937 [(set_attr "type" "pop")
1938 (set_attr "mode" "DI")])
1940 (define_insn "popdi1"
1941 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1942 (mem:DI (reg:DI SP_REG)))
1943 (set (reg:DI SP_REG)
1944 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1947 [(set_attr "type" "pop")
1948 (set_attr "mode" "DI")])
1950 (define_insn "*movdi_xor_rex64"
1951 [(set (match_operand:DI 0 "register_operand" "=r")
1952 (match_operand:DI 1 "const0_operand" "i"))
1953 (clobber (reg:CC FLAGS_REG))]
1954 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1955 && reload_completed"
1956 "xor{l}\t{%k0, %k0|%k0, %k0}"
1957 [(set_attr "type" "alu1")
1958 (set_attr "mode" "SI")
1959 (set_attr "length_immediate" "0")])
1961 (define_insn "*movdi_or_rex64"
1962 [(set (match_operand:DI 0 "register_operand" "=r")
1963 (match_operand:DI 1 "const_int_operand" "i"))
1964 (clobber (reg:CC FLAGS_REG))]
1965 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1967 && operands[1] == constm1_rtx"
1969 operands[1] = constm1_rtx;
1970 return "or{q}\t{%1, %0|%0, %1}";
1972 [(set_attr "type" "alu1")
1973 (set_attr "mode" "DI")
1974 (set_attr "length_immediate" "1")])
1976 (define_insn "*movdi_2"
1977 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1978 (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1980 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1984 movq\t{%1, %0|%0, %1}
1985 movq\t{%1, %0|%0, %1}
1986 movq\t{%1, %0|%0, %1}
1987 movdqa\t{%1, %0|%0, %1}
1988 movq\t{%1, %0|%0, %1}"
1989 [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1990 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1993 [(set (match_operand:DI 0 "push_operand" "")
1994 (match_operand:DI 1 "general_operand" ""))]
1995 "!TARGET_64BIT && reload_completed
1996 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1998 "ix86_split_long_move (operands); DONE;")
2000 ;; %%% This multiword shite has got to go.
2002 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2003 (match_operand:DI 1 "general_operand" ""))]
2004 "!TARGET_64BIT && reload_completed
2005 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2006 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2008 "ix86_split_long_move (operands); DONE;")
2010 (define_insn "*movdi_1_rex64"
2011 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y,!*Y,!*y")
2012 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm,*y,*Y"))]
2014 && (TARGET_INTER_UNIT_MOVES || optimize_size)
2015 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2017 switch (get_attr_type (insn))
2020 if (which_alternative == 11)
2021 return "movq2dq\t{%1, %0|%0, %1}";
2023 return "movdq2q\t{%1, %0|%0, %1}";
2025 if (get_attr_mode (insn) == MODE_TI)
2026 return "movdqa\t{%1, %0|%0, %1}";
2029 /* Moves from and into integer register is done using movd opcode with
2031 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2032 return "movd\t{%1, %0|%0, %1}";
2033 return "movq\t{%1, %0|%0, %1}";
2037 return "lea{q}\t{%a1, %0|%0, %a1}";
2039 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2041 if (get_attr_mode (insn) == MODE_SI)
2042 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2043 else if (which_alternative == 2)
2044 return "movabs{q}\t{%1, %0|%0, %1}";
2046 return "mov{q}\t{%1, %0|%0, %1}";
2050 (cond [(eq_attr "alternative" "5,6,7")
2051 (const_string "mmxmov")
2052 (eq_attr "alternative" "8,9,10")
2053 (const_string "ssemov")
2054 (eq_attr "alternative" "11,12")
2055 (const_string "ssecvt")
2056 (eq_attr "alternative" "4")
2057 (const_string "multi")
2058 (and (ne (symbol_ref "flag_pic") (const_int 0))
2059 (match_operand:DI 1 "symbolic_operand" ""))
2060 (const_string "lea")
2062 (const_string "imov")))
2063 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*")
2064 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*")
2065 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI,DI,DI")])
2067 (define_insn "*movdi_1_rex64_nointerunit"
2068 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2069 (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2071 && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2072 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2074 switch (get_attr_type (insn))
2077 if (get_attr_mode (insn) == MODE_TI)
2078 return "movdqa\t{%1, %0|%0, %1}";
2081 return "movq\t{%1, %0|%0, %1}";
2085 return "lea{q}\t{%a1, %0|%0, %a1}";
2087 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2089 if (get_attr_mode (insn) == MODE_SI)
2090 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2091 else if (which_alternative == 2)
2092 return "movabs{q}\t{%1, %0|%0, %1}";
2094 return "mov{q}\t{%1, %0|%0, %1}";
2098 (cond [(eq_attr "alternative" "5,6,7")
2099 (const_string "mmxmov")
2100 (eq_attr "alternative" "8,9,10")
2101 (const_string "ssemov")
2102 (eq_attr "alternative" "4")
2103 (const_string "multi")
2104 (and (ne (symbol_ref "flag_pic") (const_int 0))
2105 (match_operand:DI 1 "symbolic_operand" ""))
2106 (const_string "lea")
2108 (const_string "imov")))
2109 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2110 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2111 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2113 ;; Stores and loads of ax to arbitrary constant address.
2114 ;; We fake an second form of instruction to force reload to load address
2115 ;; into register when rax is not available
2116 (define_insn "*movabsdi_1_rex64"
2117 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2118 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2119 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2121 movabs{q}\t{%1, %P0|%P0, %1}
2122 mov{q}\t{%1, %a0|%a0, %1}"
2123 [(set_attr "type" "imov")
2124 (set_attr "modrm" "0,*")
2125 (set_attr "length_address" "8,0")
2126 (set_attr "length_immediate" "0,*")
2127 (set_attr "memory" "store")
2128 (set_attr "mode" "DI")])
2130 (define_insn "*movabsdi_2_rex64"
2131 [(set (match_operand:DI 0 "register_operand" "=a,r")
2132 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2133 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2135 movabs{q}\t{%P1, %0|%0, %P1}
2136 mov{q}\t{%a1, %0|%0, %a1}"
2137 [(set_attr "type" "imov")
2138 (set_attr "modrm" "0,*")
2139 (set_attr "length_address" "8,0")
2140 (set_attr "length_immediate" "0")
2141 (set_attr "memory" "load")
2142 (set_attr "mode" "DI")])
2144 ;; Convert impossible stores of immediate to existing instructions.
2145 ;; First try to get scratch register and go through it. In case this
2146 ;; fails, move by 32bit parts.
2148 [(match_scratch:DI 2 "r")
2149 (set (match_operand:DI 0 "memory_operand" "")
2150 (match_operand:DI 1 "immediate_operand" ""))]
2151 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2152 && !x86_64_immediate_operand (operands[1], DImode)"
2153 [(set (match_dup 2) (match_dup 1))
2154 (set (match_dup 0) (match_dup 2))]
2157 ;; We need to define this as both peepholer and splitter for case
2158 ;; peephole2 pass is not run.
2160 [(set (match_operand:DI 0 "memory_operand" "")
2161 (match_operand:DI 1 "immediate_operand" ""))]
2162 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2163 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2164 [(set (match_dup 2) (match_dup 3))
2165 (set (match_dup 4) (match_dup 5))]
2166 "split_di (operands, 2, operands + 2, operands + 4);")
2169 [(set (match_operand:DI 0 "memory_operand" "")
2170 (match_operand:DI 1 "immediate_operand" ""))]
2171 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2172 && !symbolic_operand (operands[1], DImode)
2173 && !x86_64_immediate_operand (operands[1], DImode)"
2174 [(set (match_dup 2) (match_dup 3))
2175 (set (match_dup 4) (match_dup 5))]
2176 "split_di (operands, 2, operands + 2, operands + 4);")
2178 (define_insn "*swapdi_rex64"
2179 [(set (match_operand:DI 0 "register_operand" "+r")
2180 (match_operand:DI 1 "register_operand" "+r"))
2185 [(set_attr "type" "imov")
2186 (set_attr "pent_pair" "np")
2187 (set_attr "athlon_decode" "vector")
2188 (set_attr "mode" "DI")
2189 (set_attr "modrm" "0")])
2192 (define_expand "movsf"
2193 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2194 (match_operand:SF 1 "general_operand" ""))]
2196 "ix86_expand_move (SFmode, operands); DONE;")
2198 (define_insn "*pushsf"
2199 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2200 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2203 switch (which_alternative)
2206 return "push{l}\t%1";
2209 /* This insn should be already split before reg-stack. */
2213 [(set_attr "type" "multi,push,multi")
2214 (set_attr "mode" "SF,SI,SF")])
2216 (define_insn "*pushsf_rex64"
2217 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2218 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2221 switch (which_alternative)
2224 return "push{q}\t%q1";
2227 /* This insn should be already split before reg-stack. */
2231 [(set_attr "type" "multi,push,multi")
2232 (set_attr "mode" "SF,DI,SF")])
2235 [(set (match_operand:SF 0 "push_operand" "")
2236 (match_operand:SF 1 "memory_operand" ""))]
2238 && GET_CODE (operands[1]) == MEM
2239 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2240 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2243 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2246 ;; %%% Kill this when call knows how to work this out.
2248 [(set (match_operand:SF 0 "push_operand" "")
2249 (match_operand:SF 1 "any_fp_register_operand" ""))]
2251 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2252 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2255 [(set (match_operand:SF 0 "push_operand" "")
2256 (match_operand:SF 1 "any_fp_register_operand" ""))]
2258 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2259 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2261 (define_insn "*movsf_1"
2262 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!rm,!*y")
2263 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2264 "(TARGET_INTER_UNIT_MOVES || optimize_size)
2265 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2266 && (reload_in_progress || reload_completed
2267 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2268 || GET_CODE (operands[1]) != CONST_DOUBLE
2269 || memory_operand (operands[0], SFmode))"
2271 switch (which_alternative)
2274 return output_387_reg_move (insn, operands);
2277 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2278 return "fstp%z0\t%y0";
2280 return "fst%z0\t%y0";
2283 return standard_80387_constant_opcode (operands[1]);
2287 return "mov{l}\t{%1, %0|%0, %1}";
2289 if (get_attr_mode (insn) == MODE_TI)
2290 return "pxor\t%0, %0";
2292 return "xorps\t%0, %0";
2294 if (get_attr_mode (insn) == MODE_V4SF)
2295 return "movaps\t{%1, %0|%0, %1}";
2297 return "movss\t{%1, %0|%0, %1}";
2300 return "movss\t{%1, %0|%0, %1}";
2304 return "movd\t{%1, %0|%0, %1}";
2307 return "movq\t{%1, %0|%0, %1}";
2313 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2315 (cond [(eq_attr "alternative" "3,4,9,10")
2317 (eq_attr "alternative" "5")
2319 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2321 (ne (symbol_ref "TARGET_SSE2")
2323 (eq (symbol_ref "optimize_size")
2326 (const_string "V4SF"))
2327 /* For architectures resolving dependencies on
2328 whole SSE registers use APS move to break dependency
2329 chains, otherwise use short move to avoid extra work.
2331 Do the same for architectures resolving dependencies on
2332 the parts. While in DF mode it is better to always handle
2333 just register parts, the SF mode is different due to lack
2334 of instructions to load just part of the register. It is
2335 better to maintain the whole registers in single format
2336 to avoid problems on using packed logical operations. */
2337 (eq_attr "alternative" "6")
2339 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2341 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2343 (const_string "V4SF")
2344 (const_string "SF"))
2345 (eq_attr "alternative" "11")
2346 (const_string "DI")]
2347 (const_string "SF")))])
2349 (define_insn "*movsf_1_nointerunit"
2350 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2351 (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2352 "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2353 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2354 && (reload_in_progress || reload_completed
2355 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2356 || GET_CODE (operands[1]) != CONST_DOUBLE
2357 || memory_operand (operands[0], SFmode))"
2359 switch (which_alternative)
2362 return output_387_reg_move (insn, operands);
2365 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2366 return "fstp%z0\t%y0";
2368 return "fst%z0\t%y0";
2371 return standard_80387_constant_opcode (operands[1]);
2375 return "mov{l}\t{%1, %0|%0, %1}";
2377 if (get_attr_mode (insn) == MODE_TI)
2378 return "pxor\t%0, %0";
2380 return "xorps\t%0, %0";
2382 if (get_attr_mode (insn) == MODE_V4SF)
2383 return "movaps\t{%1, %0|%0, %1}";
2385 return "movss\t{%1, %0|%0, %1}";
2388 return "movss\t{%1, %0|%0, %1}";
2392 return "movd\t{%1, %0|%0, %1}";
2395 return "movq\t{%1, %0|%0, %1}";
2401 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2403 (cond [(eq_attr "alternative" "3,4,9,10")
2405 (eq_attr "alternative" "5")
2407 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2409 (ne (symbol_ref "TARGET_SSE2")
2411 (eq (symbol_ref "optimize_size")
2414 (const_string "V4SF"))
2415 /* For architectures resolving dependencies on
2416 whole SSE registers use APS move to break dependency
2417 chains, otherwise use short move to avoid extra work.
2419 Do the same for architectures resolving dependencies on
2420 the parts. While in DF mode it is better to always handle
2421 just register parts, the SF mode is different due to lack
2422 of instructions to load just part of the register. It is
2423 better to maintain the whole registers in single format
2424 to avoid problems on using packed logical operations. */
2425 (eq_attr "alternative" "6")
2427 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2429 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2431 (const_string "V4SF")
2432 (const_string "SF"))
2433 (eq_attr "alternative" "11")
2434 (const_string "DI")]
2435 (const_string "SF")))])
2437 (define_insn "*swapsf"
2438 [(set (match_operand:SF 0 "register_operand" "+f")
2439 (match_operand:SF 1 "register_operand" "+f"))
2442 "reload_completed || !TARGET_SSE"
2444 if (STACK_TOP_P (operands[0]))
2449 [(set_attr "type" "fxch")
2450 (set_attr "mode" "SF")])
2452 (define_expand "movdf"
2453 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2454 (match_operand:DF 1 "general_operand" ""))]
2456 "ix86_expand_move (DFmode, operands); DONE;")
2458 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2459 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2460 ;; On the average, pushdf using integers can be still shorter. Allow this
2461 ;; pattern for optimize_size too.
2463 (define_insn "*pushdf_nointeger"
2464 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2465 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2466 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2468 /* This insn should be already split before reg-stack. */
2471 [(set_attr "type" "multi")
2472 (set_attr "mode" "DF,SI,SI,DF")])
2474 (define_insn "*pushdf_integer"
2475 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2476 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2477 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2479 /* This insn should be already split before reg-stack. */
2482 [(set_attr "type" "multi")
2483 (set_attr "mode" "DF,SI,DF")])
2485 ;; %%% Kill this when call knows how to work this out.
2487 [(set (match_operand:DF 0 "push_operand" "")
2488 (match_operand:DF 1 "any_fp_register_operand" ""))]
2489 "!TARGET_64BIT && reload_completed"
2490 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2491 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2495 [(set (match_operand:DF 0 "push_operand" "")
2496 (match_operand:DF 1 "any_fp_register_operand" ""))]
2497 "TARGET_64BIT && reload_completed"
2498 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2499 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2503 [(set (match_operand:DF 0 "push_operand" "")
2504 (match_operand:DF 1 "general_operand" ""))]
2507 "ix86_split_long_move (operands); DONE;")
2509 ;; Moving is usually shorter when only FP registers are used. This separate
2510 ;; movdf pattern avoids the use of integer registers for FP operations
2511 ;; when optimizing for size.
2513 (define_insn "*movdf_nointeger"
2514 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2515 (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2516 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2517 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2518 && (reload_in_progress || reload_completed
2519 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2520 || GET_CODE (operands[1]) != CONST_DOUBLE
2521 || memory_operand (operands[0], DFmode))"
2523 switch (which_alternative)
2526 return output_387_reg_move (insn, operands);
2529 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2530 return "fstp%z0\t%y0";
2532 return "fst%z0\t%y0";
2535 return standard_80387_constant_opcode (operands[1]);
2541 switch (get_attr_mode (insn))
2544 return "xorps\t%0, %0";
2546 return "xorpd\t%0, %0";
2548 return "pxor\t%0, %0";
2553 switch (get_attr_mode (insn))
2556 return "movaps\t{%1, %0|%0, %1}";
2558 return "movapd\t{%1, %0|%0, %1}";
2560 return "movsd\t{%1, %0|%0, %1}";
2565 if (get_attr_mode (insn) == MODE_V2DF)
2566 return "movlpd\t{%1, %0|%0, %1}";
2568 return "movsd\t{%1, %0|%0, %1}";
2570 return "movsd\t{%1, %0|%0, %1}";
2576 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2578 (cond [(eq_attr "alternative" "3,4")
2580 /* xorps is one byte shorter. */
2581 (eq_attr "alternative" "5")
2582 (cond [(ne (symbol_ref "optimize_size")
2584 (const_string "V4SF")
2585 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2587 (const_string "TI")]
2588 (const_string "V2DF"))
2589 /* For architectures resolving dependencies on
2590 whole SSE registers use APD move to break dependency
2591 chains, otherwise use short move to avoid extra work.
2593 movaps encodes one byte shorter. */
2594 (eq_attr "alternative" "6")
2596 [(ne (symbol_ref "optimize_size")
2598 (const_string "V4SF")
2599 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2601 (const_string "V2DF")]
2602 (const_string "DF"))
2603 /* For architectures resolving dependencies on register
2604 parts we may avoid extra work to zero out upper part
2606 (eq_attr "alternative" "7")
2608 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2610 (const_string "V2DF")
2611 (const_string "DF"))]
2612 (const_string "DF")))])
2614 (define_insn "*movdf_integer"
2615 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2616 (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2617 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2618 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2619 && (reload_in_progress || reload_completed
2620 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2621 || GET_CODE (operands[1]) != CONST_DOUBLE
2622 || memory_operand (operands[0], DFmode))"
2624 switch (which_alternative)
2627 return output_387_reg_move (insn, operands);
2630 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2631 return "fstp%z0\t%y0";
2633 return "fst%z0\t%y0";
2636 return standard_80387_constant_opcode (operands[1]);
2643 switch (get_attr_mode (insn))
2646 return "xorps\t%0, %0";
2648 return "xorpd\t%0, %0";
2650 return "pxor\t%0, %0";
2655 switch (get_attr_mode (insn))
2658 return "movaps\t{%1, %0|%0, %1}";
2660 return "movapd\t{%1, %0|%0, %1}";
2662 return "movsd\t{%1, %0|%0, %1}";
2667 if (get_attr_mode (insn) == MODE_V2DF)
2668 return "movlpd\t{%1, %0|%0, %1}";
2670 return "movsd\t{%1, %0|%0, %1}";
2672 return "movsd\t{%1, %0|%0, %1}";
2678 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2680 (cond [(eq_attr "alternative" "3,4")
2682 /* xorps is one byte shorter. */
2683 (eq_attr "alternative" "5")
2684 (cond [(ne (symbol_ref "optimize_size")
2686 (const_string "V4SF")
2687 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2689 (const_string "TI")]
2690 (const_string "V2DF"))
2691 /* For architectures resolving dependencies on
2692 whole SSE registers use APD move to break dependency
2693 chains, otherwise use short move to avoid extra work.
2695 movaps encodes one byte shorter. */
2696 (eq_attr "alternative" "6")
2698 [(ne (symbol_ref "optimize_size")
2700 (const_string "V4SF")
2701 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2703 (const_string "V2DF")]
2704 (const_string "DF"))
2705 /* For architectures resolving dependencies on register
2706 parts we may avoid extra work to zero out upper part
2708 (eq_attr "alternative" "7")
2710 (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2712 (const_string "V2DF")
2713 (const_string "DF"))]
2714 (const_string "DF")))])
2717 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2718 (match_operand:DF 1 "general_operand" ""))]
2720 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2721 && ! (ANY_FP_REG_P (operands[0]) ||
2722 (GET_CODE (operands[0]) == SUBREG
2723 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2724 && ! (ANY_FP_REG_P (operands[1]) ||
2725 (GET_CODE (operands[1]) == SUBREG
2726 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2728 "ix86_split_long_move (operands); DONE;")
2730 (define_insn "*swapdf"
2731 [(set (match_operand:DF 0 "register_operand" "+f")
2732 (match_operand:DF 1 "register_operand" "+f"))
2735 "reload_completed || !TARGET_SSE2"
2737 if (STACK_TOP_P (operands[0]))
2742 [(set_attr "type" "fxch")
2743 (set_attr "mode" "DF")])
2745 (define_expand "movxf"
2746 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2747 (match_operand:XF 1 "general_operand" ""))]
2749 "ix86_expand_move (XFmode, operands); DONE;")
2751 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2752 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2753 ;; Pushing using integer instructions is longer except for constants
2754 ;; and direct memory references.
2755 ;; (assuming that any given constant is pushed only once, but this ought to be
2756 ;; handled elsewhere).
2758 (define_insn "*pushxf_nointeger"
2759 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2760 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2763 /* This insn should be already split before reg-stack. */
2766 [(set_attr "type" "multi")
2767 (set_attr "mode" "XF,SI,SI")])
2769 (define_insn "*pushxf_integer"
2770 [(set (match_operand:XF 0 "push_operand" "=<,<")
2771 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2774 /* This insn should be already split before reg-stack. */
2777 [(set_attr "type" "multi")
2778 (set_attr "mode" "XF,SI")])
2781 [(set (match_operand 0 "push_operand" "")
2782 (match_operand 1 "general_operand" ""))]
2784 && (GET_MODE (operands[0]) == XFmode
2785 || GET_MODE (operands[0]) == DFmode)
2786 && !ANY_FP_REG_P (operands[1])"
2788 "ix86_split_long_move (operands); DONE;")
2791 [(set (match_operand:XF 0 "push_operand" "")
2792 (match_operand:XF 1 "any_fp_register_operand" ""))]
2794 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2795 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2796 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2799 [(set (match_operand:XF 0 "push_operand" "")
2800 (match_operand:XF 1 "any_fp_register_operand" ""))]
2802 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2803 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2804 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2806 ;; Do not use integer registers when optimizing for size
2807 (define_insn "*movxf_nointeger"
2808 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2809 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2811 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2812 && (reload_in_progress || reload_completed
2813 || GET_CODE (operands[1]) != CONST_DOUBLE
2814 || memory_operand (operands[0], XFmode))"
2816 switch (which_alternative)
2819 return output_387_reg_move (insn, operands);
2822 /* There is no non-popping store to memory for XFmode. So if
2823 we need one, follow the store with a load. */
2824 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825 return "fstp%z0\t%y0\;fld%z0\t%y0";
2827 return "fstp%z0\t%y0";
2830 return standard_80387_constant_opcode (operands[1]);
2837 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2838 (set_attr "mode" "XF,XF,XF,SI,SI")])
2840 (define_insn "*movxf_integer"
2841 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2842 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2844 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2845 && (reload_in_progress || reload_completed
2846 || GET_CODE (operands[1]) != CONST_DOUBLE
2847 || memory_operand (operands[0], XFmode))"
2849 switch (which_alternative)
2852 return output_387_reg_move (insn, operands);
2855 /* There is no non-popping store to memory for XFmode. So if
2856 we need one, follow the store with a load. */
2857 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2858 return "fstp%z0\t%y0\;fld%z0\t%y0";
2860 return "fstp%z0\t%y0";
2863 return standard_80387_constant_opcode (operands[1]);
2870 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2871 (set_attr "mode" "XF,XF,XF,SI,SI")])
2874 [(set (match_operand 0 "nonimmediate_operand" "")
2875 (match_operand 1 "general_operand" ""))]
2877 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2878 && GET_MODE (operands[0]) == XFmode
2879 && ! (ANY_FP_REG_P (operands[0]) ||
2880 (GET_CODE (operands[0]) == SUBREG
2881 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2882 && ! (ANY_FP_REG_P (operands[1]) ||
2883 (GET_CODE (operands[1]) == SUBREG
2884 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2886 "ix86_split_long_move (operands); DONE;")
2889 [(set (match_operand 0 "register_operand" "")
2890 (match_operand 1 "memory_operand" ""))]
2892 && GET_CODE (operands[1]) == MEM
2893 && (GET_MODE (operands[0]) == XFmode
2894 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2895 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2896 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2897 [(set (match_dup 0) (match_dup 1))]
2899 rtx c = get_pool_constant (XEXP (operands[1], 0));
2900 rtx r = operands[0];
2902 if (GET_CODE (r) == SUBREG)
2907 if (!standard_sse_constant_p (c))
2910 else if (FP_REG_P (r))
2912 if (!standard_80387_constant_p (c))
2915 else if (MMX_REG_P (r))
2921 (define_insn "swapxf"
2922 [(set (match_operand:XF 0 "register_operand" "+f")
2923 (match_operand:XF 1 "register_operand" "+f"))
2928 if (STACK_TOP_P (operands[0]))
2933 [(set_attr "type" "fxch")
2934 (set_attr "mode" "XF")])
2936 ;; Zero extension instructions
2938 (define_expand "zero_extendhisi2"
2939 [(set (match_operand:SI 0 "register_operand" "")
2940 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2943 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2945 operands[1] = force_reg (HImode, operands[1]);
2946 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2951 (define_insn "zero_extendhisi2_and"
2952 [(set (match_operand:SI 0 "register_operand" "=r")
2953 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2954 (clobber (reg:CC FLAGS_REG))]
2955 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2957 [(set_attr "type" "alu1")
2958 (set_attr "mode" "SI")])
2961 [(set (match_operand:SI 0 "register_operand" "")
2962 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2963 (clobber (reg:CC FLAGS_REG))]
2964 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2965 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2966 (clobber (reg:CC FLAGS_REG))])]
2969 (define_insn "*zero_extendhisi2_movzwl"
2970 [(set (match_operand:SI 0 "register_operand" "=r")
2971 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2972 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2973 "movz{wl|x}\t{%1, %0|%0, %1}"
2974 [(set_attr "type" "imovx")
2975 (set_attr "mode" "SI")])
2977 (define_expand "zero_extendqihi2"
2979 [(set (match_operand:HI 0 "register_operand" "")
2980 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2981 (clobber (reg:CC FLAGS_REG))])]
2985 (define_insn "*zero_extendqihi2_and"
2986 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
2987 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
2988 (clobber (reg:CC FLAGS_REG))]
2989 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2991 [(set_attr "type" "alu1")
2992 (set_attr "mode" "HI")])
2994 (define_insn "*zero_extendqihi2_movzbw_and"
2995 [(set (match_operand:HI 0 "register_operand" "=r,r")
2996 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
2997 (clobber (reg:CC FLAGS_REG))]
2998 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3000 [(set_attr "type" "imovx,alu1")
3001 (set_attr "mode" "HI")])
3003 (define_insn "*zero_extendqihi2_movzbw"
3004 [(set (match_operand:HI 0 "register_operand" "=r")
3005 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3006 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3007 "movz{bw|x}\t{%1, %0|%0, %1}"
3008 [(set_attr "type" "imovx")
3009 (set_attr "mode" "HI")])
3011 ;; For the movzbw case strip only the clobber
3013 [(set (match_operand:HI 0 "register_operand" "")
3014 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3015 (clobber (reg:CC FLAGS_REG))]
3017 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3018 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3019 [(set (match_operand:HI 0 "register_operand" "")
3020 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3022 ;; When source and destination does not overlap, clear destination
3023 ;; first and then do the movb
3025 [(set (match_operand:HI 0 "register_operand" "")
3026 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3027 (clobber (reg:CC FLAGS_REG))]
3029 && ANY_QI_REG_P (operands[0])
3030 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3031 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3032 [(set (match_dup 0) (const_int 0))
3033 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3034 "operands[2] = gen_lowpart (QImode, operands[0]);")
3036 ;; Rest is handled by single and.
3038 [(set (match_operand:HI 0 "register_operand" "")
3039 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3040 (clobber (reg:CC FLAGS_REG))]
3042 && true_regnum (operands[0]) == true_regnum (operands[1])"
3043 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3044 (clobber (reg:CC FLAGS_REG))])]
3047 (define_expand "zero_extendqisi2"
3049 [(set (match_operand:SI 0 "register_operand" "")
3050 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3051 (clobber (reg:CC FLAGS_REG))])]
3055 (define_insn "*zero_extendqisi2_and"
3056 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3057 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3058 (clobber (reg:CC FLAGS_REG))]
3059 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3061 [(set_attr "type" "alu1")
3062 (set_attr "mode" "SI")])
3064 (define_insn "*zero_extendqisi2_movzbw_and"
3065 [(set (match_operand:SI 0 "register_operand" "=r,r")
3066 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3067 (clobber (reg:CC FLAGS_REG))]
3068 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3070 [(set_attr "type" "imovx,alu1")
3071 (set_attr "mode" "SI")])
3073 (define_insn "*zero_extendqisi2_movzbw"
3074 [(set (match_operand:SI 0 "register_operand" "=r")
3075 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3076 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3077 "movz{bl|x}\t{%1, %0|%0, %1}"
3078 [(set_attr "type" "imovx")
3079 (set_attr "mode" "SI")])
3081 ;; For the movzbl case strip only the clobber
3083 [(set (match_operand:SI 0 "register_operand" "")
3084 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3085 (clobber (reg:CC FLAGS_REG))]
3087 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3088 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3090 (zero_extend:SI (match_dup 1)))])
3092 ;; When source and destination does not overlap, clear destination
3093 ;; first and then do the movb
3095 [(set (match_operand:SI 0 "register_operand" "")
3096 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3097 (clobber (reg:CC FLAGS_REG))]
3099 && ANY_QI_REG_P (operands[0])
3100 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3101 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3102 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3103 [(set (match_dup 0) (const_int 0))
3104 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3105 "operands[2] = gen_lowpart (QImode, operands[0]);")
3107 ;; Rest is handled by single and.
3109 [(set (match_operand:SI 0 "register_operand" "")
3110 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3111 (clobber (reg:CC FLAGS_REG))]
3113 && true_regnum (operands[0]) == true_regnum (operands[1])"
3114 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3115 (clobber (reg:CC FLAGS_REG))])]
3118 ;; %%% Kill me once multi-word ops are sane.
3119 (define_expand "zero_extendsidi2"
3120 [(set (match_operand:DI 0 "register_operand" "=r")
3121 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3125 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3130 (define_insn "zero_extendsidi2_32"
3131 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3132 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,m,m")))
3133 (clobber (reg:CC FLAGS_REG))]
3134 "!TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3139 movd\t{%1, %0|%0, %1}
3140 movd\t{%1, %0|%0, %1}"
3141 [(set_attr "mode" "SI,SI,SI,DI,TI")
3142 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3144 (define_insn "*zero_extendsidi2_32_1"
3145 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,!?y,!?Y")
3146 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3147 (clobber (reg:CC FLAGS_REG))]
3148 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3153 movd\t{%1, %0|%0, %1}
3154 movd\t{%1, %0|%0, %1}"
3155 [(set_attr "mode" "SI,SI,SI,DI,TI")
3156 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3158 (define_insn "zero_extendsidi2_rex64"
3159 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!?Y")
3160 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,m,m")))]
3161 "TARGET_64BIT && !TARGET_INTER_UNIT_MOVES"
3163 mov\t{%k1, %k0|%k0, %k1}
3165 movd\t{%1, %0|%0, %1}
3166 movd\t{%1, %0|%0, %1}"
3167 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3168 (set_attr "mode" "SI,DI,DI,TI")])
3170 (define_insn "*zero_extendsidi2_rex64_1"
3171 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!?y,!*?")
3172 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3173 "TARGET_64BIT && TARGET_INTER_UNIT_MOVES"
3175 mov\t{%k1, %k0|%k0, %k1}
3177 movd\t{%1, %0|%0, %1}
3178 movd\t{%1, %0|%0, %1}"
3179 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3180 (set_attr "mode" "SI,DI,SI,SI")])
3183 [(set (match_operand:DI 0 "memory_operand" "")
3184 (zero_extend:DI (match_dup 0)))]
3186 [(set (match_dup 4) (const_int 0))]
3187 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3190 [(set (match_operand:DI 0 "register_operand" "")
3191 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3192 (clobber (reg:CC FLAGS_REG))]
3193 "!TARGET_64BIT && reload_completed
3194 && true_regnum (operands[0]) == true_regnum (operands[1])"
3195 [(set (match_dup 4) (const_int 0))]
3196 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3199 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3200 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3201 (clobber (reg:CC FLAGS_REG))]
3202 "!TARGET_64BIT && reload_completed
3203 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3204 [(set (match_dup 3) (match_dup 1))
3205 (set (match_dup 4) (const_int 0))]
3206 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3208 (define_insn "zero_extendhidi2"
3209 [(set (match_operand:DI 0 "register_operand" "=r,r")
3210 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3213 movz{wl|x}\t{%1, %k0|%k0, %1}
3214 movz{wq|x}\t{%1, %0|%0, %1}"
3215 [(set_attr "type" "imovx")
3216 (set_attr "mode" "SI,DI")])
3218 (define_insn "zero_extendqidi2"
3219 [(set (match_operand:DI 0 "register_operand" "=r,r")
3220 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3223 movz{bl|x}\t{%1, %k0|%k0, %1}
3224 movz{bq|x}\t{%1, %0|%0, %1}"
3225 [(set_attr "type" "imovx")
3226 (set_attr "mode" "SI,DI")])
3228 ;; Sign extension instructions
3230 (define_expand "extendsidi2"
3231 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3232 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3233 (clobber (reg:CC FLAGS_REG))
3234 (clobber (match_scratch:SI 2 ""))])]
3239 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3244 (define_insn "*extendsidi2_1"
3245 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3246 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3247 (clobber (reg:CC FLAGS_REG))
3248 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3252 (define_insn "extendsidi2_rex64"
3253 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3254 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3258 movs{lq|x}\t{%1,%0|%0, %1}"
3259 [(set_attr "type" "imovx")
3260 (set_attr "mode" "DI")
3261 (set_attr "prefix_0f" "0")
3262 (set_attr "modrm" "0,1")])
3264 (define_insn "extendhidi2"
3265 [(set (match_operand:DI 0 "register_operand" "=r")
3266 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3268 "movs{wq|x}\t{%1,%0|%0, %1}"
3269 [(set_attr "type" "imovx")
3270 (set_attr "mode" "DI")])
3272 (define_insn "extendqidi2"
3273 [(set (match_operand:DI 0 "register_operand" "=r")
3274 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3276 "movs{bq|x}\t{%1,%0|%0, %1}"
3277 [(set_attr "type" "imovx")
3278 (set_attr "mode" "DI")])
3280 ;; Extend to memory case when source register does die.
3282 [(set (match_operand:DI 0 "memory_operand" "")
3283 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3284 (clobber (reg:CC FLAGS_REG))
3285 (clobber (match_operand:SI 2 "register_operand" ""))]
3287 && dead_or_set_p (insn, operands[1])
3288 && !reg_mentioned_p (operands[1], operands[0]))"
3289 [(set (match_dup 3) (match_dup 1))
3290 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3291 (clobber (reg:CC FLAGS_REG))])
3292 (set (match_dup 4) (match_dup 1))]
3293 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3295 ;; Extend to memory case when source register does not die.
3297 [(set (match_operand:DI 0 "memory_operand" "")
3298 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3299 (clobber (reg:CC FLAGS_REG))
3300 (clobber (match_operand:SI 2 "register_operand" ""))]
3304 split_di (&operands[0], 1, &operands[3], &operands[4]);
3306 emit_move_insn (operands[3], operands[1]);
3308 /* Generate a cltd if possible and doing so it profitable. */
3309 if (true_regnum (operands[1]) == 0
3310 && true_regnum (operands[2]) == 1
3311 && (optimize_size || TARGET_USE_CLTD))
3313 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3317 emit_move_insn (operands[2], operands[1]);
3318 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3320 emit_move_insn (operands[4], operands[2]);
3324 ;; Extend to register case. Optimize case where source and destination
3325 ;; registers match and cases where we can use cltd.
3327 [(set (match_operand:DI 0 "register_operand" "")
3328 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3329 (clobber (reg:CC FLAGS_REG))
3330 (clobber (match_scratch:SI 2 ""))]
3334 split_di (&operands[0], 1, &operands[3], &operands[4]);
3336 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3337 emit_move_insn (operands[3], operands[1]);
3339 /* Generate a cltd if possible and doing so it profitable. */
3340 if (true_regnum (operands[3]) == 0
3341 && (optimize_size || TARGET_USE_CLTD))
3343 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3347 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3348 emit_move_insn (operands[4], operands[1]);
3350 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3354 (define_insn "extendhisi2"
3355 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3356 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3359 switch (get_attr_prefix_0f (insn))
3362 return "{cwtl|cwde}";
3364 return "movs{wl|x}\t{%1,%0|%0, %1}";
3367 [(set_attr "type" "imovx")
3368 (set_attr "mode" "SI")
3369 (set (attr "prefix_0f")
3370 ;; movsx is short decodable while cwtl is vector decoded.
3371 (if_then_else (and (eq_attr "cpu" "!k6")
3372 (eq_attr "alternative" "0"))
3374 (const_string "1")))
3376 (if_then_else (eq_attr "prefix_0f" "0")
3378 (const_string "1")))])
3380 (define_insn "*extendhisi2_zext"
3381 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3383 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3386 switch (get_attr_prefix_0f (insn))
3389 return "{cwtl|cwde}";
3391 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3394 [(set_attr "type" "imovx")
3395 (set_attr "mode" "SI")
3396 (set (attr "prefix_0f")
3397 ;; movsx is short decodable while cwtl is vector decoded.
3398 (if_then_else (and (eq_attr "cpu" "!k6")
3399 (eq_attr "alternative" "0"))
3401 (const_string "1")))
3403 (if_then_else (eq_attr "prefix_0f" "0")
3405 (const_string "1")))])
3407 (define_insn "extendqihi2"
3408 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3409 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3412 switch (get_attr_prefix_0f (insn))
3415 return "{cbtw|cbw}";
3417 return "movs{bw|x}\t{%1,%0|%0, %1}";
3420 [(set_attr "type" "imovx")
3421 (set_attr "mode" "HI")
3422 (set (attr "prefix_0f")
3423 ;; movsx is short decodable while cwtl is vector decoded.
3424 (if_then_else (and (eq_attr "cpu" "!k6")
3425 (eq_attr "alternative" "0"))
3427 (const_string "1")))
3429 (if_then_else (eq_attr "prefix_0f" "0")
3431 (const_string "1")))])
3433 (define_insn "extendqisi2"
3434 [(set (match_operand:SI 0 "register_operand" "=r")
3435 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3437 "movs{bl|x}\t{%1,%0|%0, %1}"
3438 [(set_attr "type" "imovx")
3439 (set_attr "mode" "SI")])
3441 (define_insn "*extendqisi2_zext"
3442 [(set (match_operand:DI 0 "register_operand" "=r")
3444 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3446 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3447 [(set_attr "type" "imovx")
3448 (set_attr "mode" "SI")])
3450 ;; Conversions between float and double.
3452 ;; These are all no-ops in the model used for the 80387. So just
3455 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3456 (define_insn "*dummy_extendsfdf2"
3457 [(set (match_operand:DF 0 "push_operand" "=<")
3458 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3463 [(set (match_operand:DF 0 "push_operand" "")
3464 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3466 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3467 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3470 [(set (match_operand:DF 0 "push_operand" "")
3471 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3473 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3474 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3476 (define_insn "*dummy_extendsfxf2"
3477 [(set (match_operand:XF 0 "push_operand" "=<")
3478 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3483 [(set (match_operand:XF 0 "push_operand" "")
3484 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3486 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3487 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3488 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3491 [(set (match_operand:XF 0 "push_operand" "")
3492 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3494 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3495 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3496 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3499 [(set (match_operand:XF 0 "push_operand" "")
3500 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3502 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3503 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3504 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3507 [(set (match_operand:XF 0 "push_operand" "")
3508 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3510 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3511 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3512 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3514 (define_expand "extendsfdf2"
3515 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3516 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3517 "TARGET_80387 || TARGET_SSE2"
3519 /* ??? Needed for compress_float_constant since all fp constants
3520 are LEGITIMATE_CONSTANT_P. */
3521 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3522 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3523 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3524 operands[1] = force_reg (SFmode, operands[1]);
3527 (define_insn "*extendsfdf2_1"
3528 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3529 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3530 "(TARGET_80387 || TARGET_SSE2)
3531 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3533 switch (which_alternative)
3536 return output_387_reg_move (insn, operands);
3539 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3540 return "fstp%z0\t%y0";
3542 return "fst%z0\t%y0";
3545 return "cvtss2sd\t{%1, %0|%0, %1}";
3551 [(set_attr "type" "fmov,fmov,ssecvt")
3552 (set_attr "mode" "SF,XF,DF")])
3554 (define_insn "*extendsfdf2_1_sse_only"
3555 [(set (match_operand:DF 0 "register_operand" "=Y")
3556 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3557 "!TARGET_80387 && TARGET_SSE2
3558 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3559 "cvtss2sd\t{%1, %0|%0, %1}"
3560 [(set_attr "type" "ssecvt")
3561 (set_attr "mode" "DF")])
3563 (define_expand "extendsfxf2"
3564 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3565 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3568 /* ??? Needed for compress_float_constant since all fp constants
3569 are LEGITIMATE_CONSTANT_P. */
3570 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3571 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3572 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3573 operands[1] = force_reg (SFmode, operands[1]);
3576 (define_insn "*extendsfxf2_1"
3577 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3578 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3580 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3582 switch (which_alternative)
3585 return output_387_reg_move (insn, operands);
3588 /* There is no non-popping store to memory for XFmode. So if
3589 we need one, follow the store with a load. */
3590 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3591 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3593 return "fstp%z0\t%y0";
3599 [(set_attr "type" "fmov")
3600 (set_attr "mode" "SF,XF")])
3602 (define_expand "extenddfxf2"
3603 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3604 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3607 /* ??? Needed for compress_float_constant since all fp constants
3608 are LEGITIMATE_CONSTANT_P. */
3609 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3610 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3611 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3612 operands[1] = force_reg (DFmode, operands[1]);
3615 (define_insn "*extenddfxf2_1"
3616 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3617 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3619 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3621 switch (which_alternative)
3624 return output_387_reg_move (insn, operands);
3627 /* There is no non-popping store to memory for XFmode. So if
3628 we need one, follow the store with a load. */
3629 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3630 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3632 return "fstp%z0\t%y0";
3638 [(set_attr "type" "fmov")
3639 (set_attr "mode" "DF,XF")])
3641 ;; %%% This seems bad bad news.
3642 ;; This cannot output into an f-reg because there is no way to be sure
3643 ;; of truncating in that case. Otherwise this is just like a simple move
3644 ;; insn. So we pretend we can output to a reg in order to get better
3645 ;; register preferencing, but we really use a stack slot.
3647 (define_expand "truncdfsf2"
3648 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3650 (match_operand:DF 1 "register_operand" "")))
3651 (clobber (match_dup 2))])]
3652 "TARGET_80387 || TARGET_SSE2"
3656 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3659 else if (flag_unsafe_math_optimizations)
3661 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3662 emit_insn (gen_truncdfsf2_noop (reg, operands[1]));
3663 if (reg != operands[0])
3664 emit_move_insn (operands[0], reg);
3668 operands[2] = assign_386_stack_local (SFmode, 0);
3671 (define_insn "truncdfsf2_noop"
3672 [(set (match_operand:SF 0 "register_operand" "=f")
3673 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3674 "TARGET_80387 && flag_unsafe_math_optimizations"
3676 return output_387_reg_move (insn, operands);
3678 [(set_attr "type" "fmov")
3679 (set_attr "mode" "SF")])
3681 (define_insn "*truncdfsf2_1"
3682 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3684 (match_operand:DF 1 "register_operand" "f,f,f,f")))
3685 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3686 "TARGET_80387 && !TARGET_SSE2"
3688 switch (which_alternative)
3691 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3692 return "fstp%z0\t%y0";
3694 return "fst%z0\t%y0";
3699 [(set_attr "type" "fmov,multi,multi,multi")
3700 (set_attr "mode" "SF,SF,SF,SF")])
3702 (define_insn "*truncdfsf2_1_sse"
3703 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3705 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3706 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3707 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3709 switch (which_alternative)
3712 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3713 return "fstp%z0\t%y0";
3715 return "fst%z0\t%y0";
3722 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3723 (set_attr "mode" "SF,SF,SF,SF,DF")])
3725 (define_insn "*truncdfsf2_1_sse_nooverlap"
3726 [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3728 (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3729 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3730 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3732 switch (which_alternative)
3735 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3736 return "fstp%z0\t%y0";
3738 return "fst%z0\t%y0";
3745 [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3746 (set_attr "mode" "SF,SF,SF,SF,DF")])
3748 (define_insn "*truncdfsf2_2"
3749 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3751 (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3752 "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3753 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3755 switch (which_alternative)
3759 return "cvtsd2ss\t{%1, %0|%0, %1}";
3761 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3762 return "fstp%z0\t%y0";
3764 return "fst%z0\t%y0";
3769 [(set_attr "type" "ssecvt,ssecvt,fmov")
3770 (set_attr "athlon_decode" "vector,double,*")
3771 (set_attr "mode" "SF,SF,SF")])
3773 (define_insn "*truncdfsf2_2_nooverlap"
3774 [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
3776 (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
3777 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3778 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3780 switch (which_alternative)
3785 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786 return "fstp%z0\t%y0";
3788 return "fst%z0\t%y0";
3793 [(set_attr "type" "ssecvt,fmov")
3794 (set_attr "mode" "DF,SF")])
3796 (define_insn "*truncdfsf2_3"
3797 [(set (match_operand:SF 0 "memory_operand" "=m")
3799 (match_operand:DF 1 "register_operand" "f")))]
3802 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3803 return "fstp%z0\t%y0";
3805 return "fst%z0\t%y0";
3807 [(set_attr "type" "fmov")
3808 (set_attr "mode" "SF")])
3810 (define_insn "truncdfsf2_sse_only"
3811 [(set (match_operand:SF 0 "register_operand" "=Y,Y")
3813 (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
3814 "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3815 "cvtsd2ss\t{%1, %0|%0, %1}"
3816 [(set_attr "type" "ssecvt")
3817 (set_attr "athlon_decode" "vector,double")
3818 (set_attr "mode" "SF")])
3820 (define_insn "*truncdfsf2_sse_only_nooverlap"
3821 [(set (match_operand:SF 0 "register_operand" "=&Y")
3823 (match_operand:DF 1 "nonimmediate_operand" "mY")))]
3824 "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3826 [(set_attr "type" "ssecvt")
3827 (set_attr "mode" "DF")])
3830 [(set (match_operand:SF 0 "memory_operand" "")
3832 (match_operand:DF 1 "register_operand" "")))
3833 (clobber (match_operand:SF 2 "memory_operand" ""))]
3835 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3838 ; Avoid possible reformatting penalty on the destination by first
3841 [(set (match_operand:SF 0 "register_operand" "")
3843 (match_operand:DF 1 "nonimmediate_operand" "")))
3844 (clobber (match_operand 2 "" ""))]
3845 "TARGET_80387 && reload_completed
3846 && SSE_REG_P (operands[0])
3847 && !STACK_REG_P (operands[1])"
3851 if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
3852 emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3855 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3856 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3857 /* simplify_gen_subreg refuses to widen memory references. */
3858 if (GET_CODE (src) == SUBREG)
3859 alter_subreg (&src);
3860 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3862 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3863 emit_insn (gen_cvtsd2ss (dest, dest, src));
3869 [(set (match_operand:SF 0 "register_operand" "")
3871 (match_operand:DF 1 "nonimmediate_operand" "")))]
3872 "TARGET_80387 && reload_completed
3873 && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3877 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3878 src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3879 /* simplify_gen_subreg refuses to widen memory references. */
3880 if (GET_CODE (src) == SUBREG)
3881 alter_subreg (&src);
3882 if (reg_overlap_mentioned_p (operands[0], operands[1]))
3884 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
3885 emit_insn (gen_cvtsd2ss (dest, dest, src));
3890 [(set (match_operand:SF 0 "register_operand" "")
3892 (match_operand:DF 1 "fp_register_operand" "")))
3893 (clobber (match_operand:SF 2 "memory_operand" ""))]
3894 "TARGET_80387 && reload_completed"
3895 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3896 (set (match_dup 0) (match_dup 2))]
3899 (define_expand "truncxfsf2"
3900 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3902 (match_operand:XF 1 "register_operand" "")))
3903 (clobber (match_dup 2))])]
3906 if (flag_unsafe_math_optimizations)
3908 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3909 emit_insn (gen_truncxfsf2_noop (reg, operands[1]));
3910 if (reg != operands[0])
3911 emit_move_insn (operands[0], reg);
3915 operands[2] = assign_386_stack_local (SFmode, 0);
3918 (define_insn "truncxfsf2_noop"
3919 [(set (match_operand:SF 0 "register_operand" "=f")
3920 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3921 "TARGET_80387 && flag_unsafe_math_optimizations"
3923 return output_387_reg_move (insn, operands);
3925 [(set_attr "type" "fmov")
3926 (set_attr "mode" "SF")])
3928 (define_insn "*truncxfsf2_1"
3929 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3931 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3932 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3935 switch (which_alternative)
3938 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3939 return "fstp%z0\t%y0";
3941 return "fst%z0\t%y0";
3946 [(set_attr "type" "fmov,multi,multi,multi")
3947 (set_attr "mode" "SF")])
3949 (define_insn "*truncxfsf2_2"
3950 [(set (match_operand:SF 0 "memory_operand" "=m")
3952 (match_operand:XF 1 "register_operand" "f")))]
3955 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3956 return "fstp%z0\t%y0";
3958 return "fst%z0\t%y0";
3960 [(set_attr "type" "fmov")
3961 (set_attr "mode" "SF")])
3964 [(set (match_operand:SF 0 "memory_operand" "")
3966 (match_operand:XF 1 "register_operand" "")))
3967 (clobber (match_operand:SF 2 "memory_operand" ""))]
3969 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3973 [(set (match_operand:SF 0 "register_operand" "")
3975 (match_operand:XF 1 "register_operand" "")))
3976 (clobber (match_operand:SF 2 "memory_operand" ""))]
3977 "TARGET_80387 && reload_completed"
3978 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3979 (set (match_dup 0) (match_dup 2))]
3982 (define_expand "truncxfdf2"
3983 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3985 (match_operand:XF 1 "register_operand" "")))
3986 (clobber (match_dup 2))])]
3989 if (flag_unsafe_math_optimizations)
3991 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3992 emit_insn (gen_truncxfdf2_noop (reg, operands[1]));
3993 if (reg != operands[0])
3994 emit_move_insn (operands[0], reg);
3998 operands[2] = assign_386_stack_local (DFmode, 0);
4001 (define_insn "truncxfdf2_noop"
4002 [(set (match_operand:DF 0 "register_operand" "=f")
4003 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4004 "TARGET_80387 && flag_unsafe_math_optimizations"
4006 return output_387_reg_move (insn, operands);
4008 [(set_attr "type" "fmov")
4009 (set_attr "mode" "DF")])
4011 (define_insn "*truncxfdf2_1"
4012 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4014 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4015 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4018 switch (which_alternative)
4021 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4022 return "fstp%z0\t%y0";
4024 return "fst%z0\t%y0";
4030 [(set_attr "type" "fmov,multi,multi,multi")
4031 (set_attr "mode" "DF")])
4033 (define_insn "*truncxfdf2_2"
4034 [(set (match_operand:DF 0 "memory_operand" "=m")
4036 (match_operand:XF 1 "register_operand" "f")))]
4039 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4040 return "fstp%z0\t%y0";
4042 return "fst%z0\t%y0";
4044 [(set_attr "type" "fmov")
4045 (set_attr "mode" "DF")])
4048 [(set (match_operand:DF 0 "memory_operand" "")
4050 (match_operand:XF 1 "register_operand" "")))
4051 (clobber (match_operand:DF 2 "memory_operand" ""))]
4053 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4057 [(set (match_operand:DF 0 "register_operand" "")
4059 (match_operand:XF 1 "register_operand" "")))
4060 (clobber (match_operand:DF 2 "memory_operand" ""))]
4061 "TARGET_80387 && reload_completed"
4062 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4063 (set (match_dup 0) (match_dup 2))]
4067 ;; %%% Break up all these bad boys.
4069 ;; Signed conversion to DImode.
4071 (define_expand "fix_truncxfdi2"
4072 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4073 (fix:DI (match_operand:XF 1 "register_operand" "")))
4074 (clobber (reg:CC FLAGS_REG))])]
4078 (define_expand "fix_truncdfdi2"
4079 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4080 (fix:DI (match_operand:DF 1 "register_operand" "")))
4081 (clobber (reg:CC FLAGS_REG))])]
4082 "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4084 if (TARGET_64BIT && TARGET_SSE2)
4086 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4087 emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4088 if (out != operands[0])
4089 emit_move_insn (operands[0], out);
4094 (define_expand "fix_truncsfdi2"
4095 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4096 (fix:DI (match_operand:SF 1 "register_operand" "")))
4097 (clobber (reg:CC FLAGS_REG))])]
4098 "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4100 if (TARGET_SSE && TARGET_64BIT)
4102 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4103 emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4104 if (out != operands[0])
4105 emit_move_insn (operands[0], out);
4110 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4111 ;; of the machinery.
4112 (define_insn_and_split "*fix_truncdi_1"
4113 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4114 (fix:DI (match_operand 1 "register_operand" "f,f")))
4115 (clobber (reg:CC FLAGS_REG))]
4116 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4117 && !reload_completed && !reload_in_progress
4118 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4123 ix86_optimize_mode_switching = 1;
4124 operands[2] = assign_386_stack_local (HImode, 1);
4125 operands[3] = assign_386_stack_local (HImode, 2);
4126 if (memory_operand (operands[0], VOIDmode))
4127 emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4128 operands[2], operands[3]));
4131 operands[4] = assign_386_stack_local (DImode, 0);
4132 emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4133 operands[2], operands[3],
4138 [(set_attr "type" "fistp")
4139 (set_attr "i387_cw" "trunc")
4140 (set_attr "mode" "DI")])
4142 (define_insn "fix_truncdi_nomemory"
4143 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4144 (fix:DI (match_operand 1 "register_operand" "f,f")))
4145 (use (match_operand:HI 2 "memory_operand" "m,m"))
4146 (use (match_operand:HI 3 "memory_operand" "m,m"))
4147 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4148 (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4149 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4150 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4152 [(set_attr "type" "fistp")
4153 (set_attr "i387_cw" "trunc")
4154 (set_attr "mode" "DI")])
4156 (define_insn "fix_truncdi_memory"
4157 [(set (match_operand:DI 0 "memory_operand" "=m")
4158 (fix:DI (match_operand 1 "register_operand" "f")))
4159 (use (match_operand:HI 2 "memory_operand" "m"))
4160 (use (match_operand:HI 3 "memory_operand" "m"))
4161 (clobber (match_scratch:DF 4 "=&1f"))]
4162 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4163 && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4164 "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4165 [(set_attr "type" "fistp")
4166 (set_attr "i387_cw" "trunc")
4167 (set_attr "mode" "DI")])
4170 [(set (match_operand:DI 0 "register_operand" "")
4171 (fix:DI (match_operand 1 "register_operand" "")))
4172 (use (match_operand:HI 2 "memory_operand" ""))
4173 (use (match_operand:HI 3 "memory_operand" ""))
4174 (clobber (match_operand:DI 4 "memory_operand" ""))
4175 (clobber (match_scratch 5 ""))]
4177 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4180 (clobber (match_dup 5))])
4181 (set (match_dup 0) (match_dup 4))]
4185 [(set (match_operand:DI 0 "memory_operand" "")
4186 (fix:DI (match_operand 1 "register_operand" "")))
4187 (use (match_operand:HI 2 "memory_operand" ""))
4188 (use (match_operand:HI 3 "memory_operand" ""))
4189 (clobber (match_operand:DI 4 "memory_operand" ""))
4190 (clobber (match_scratch 5 ""))]
4192 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4195 (clobber (match_dup 5))])]
4198 ;; When SSE available, it is always faster to use it!
4199 (define_insn "fix_truncsfdi_sse"
4200 [(set (match_operand:DI 0 "register_operand" "=r,r")
4201 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4202 "TARGET_64BIT && TARGET_SSE"
4203 "cvttss2si{q}\t{%1, %0|%0, %1}"
4204 [(set_attr "type" "sseicvt")
4205 (set_attr "mode" "SF")
4206 (set_attr "athlon_decode" "double,vector")])
4208 ;; Avoid vector decoded form of the instruction.
4210 [(match_scratch:SF 2 "x")
4211 (set (match_operand:DI 0 "register_operand" "")
4212 (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4213 "TARGET_K8 && !optimize_size"
4214 [(set (match_dup 2) (match_dup 1))
4215 (set (match_dup 0) (fix:DI (match_dup 2)))]
4218 (define_insn "fix_truncdfdi_sse"
4219 [(set (match_operand:DI 0 "register_operand" "=r,r")
4220 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4221 "TARGET_64BIT && TARGET_SSE2"
4222 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4223 [(set_attr "type" "sseicvt,sseicvt")
4224 (set_attr "mode" "DF")
4225 (set_attr "athlon_decode" "double,vector")])
4227 ;; Avoid vector decoded form of the instruction.
4229 [(match_scratch:DF 2 "Y")
4230 (set (match_operand:DI 0 "register_operand" "")
4231 (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4232 "TARGET_K8 && !optimize_size"
4233 [(set (match_dup 2) (match_dup 1))
4234 (set (match_dup 0) (fix:DI (match_dup 2)))]
4237 ;; Signed conversion to SImode.
4239 (define_expand "fix_truncxfsi2"
4240 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4241 (fix:SI (match_operand:XF 1 "register_operand" "")))
4242 (clobber (reg:CC FLAGS_REG))])]
4246 (define_expand "fix_truncdfsi2"
4247 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4248 (fix:SI (match_operand:DF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4250 "TARGET_80387 || TARGET_SSE2"
4254 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4255 emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4256 if (out != operands[0])
4257 emit_move_insn (operands[0], out);
4262 (define_expand "fix_truncsfsi2"
4263 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4264 (fix:SI (match_operand:SF 1 "register_operand" "")))
4265 (clobber (reg:CC FLAGS_REG))])]
4266 "TARGET_80387 || TARGET_SSE"
4270 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4271 emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4272 if (out != operands[0])
4273 emit_move_insn (operands[0], out);
4278 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4279 ;; of the machinery.
4280 (define_insn_and_split "*fix_truncsi_1"
4281 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4282 (fix:SI (match_operand 1 "register_operand" "f,f")))
4283 (clobber (reg:CC FLAGS_REG))]
4284 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4285 && !reload_completed && !reload_in_progress
4286 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4291 ix86_optimize_mode_switching = 1;
4292 operands[2] = assign_386_stack_local (HImode, 1);
4293 operands[3] = assign_386_stack_local (HImode, 2);
4294 if (memory_operand (operands[0], VOIDmode))
4295 emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4296 operands[2], operands[3]));
4299 operands[4] = assign_386_stack_local (SImode, 0);
4300 emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4301 operands[2], operands[3],
4306 [(set_attr "type" "fistp")
4307 (set_attr "i387_cw" "trunc")
4308 (set_attr "mode" "SI")])
4310 (define_insn "fix_truncsi_nomemory"
4311 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4312 (fix:SI (match_operand 1 "register_operand" "f,f")))
4313 (use (match_operand:HI 2 "memory_operand" "m,m"))
4314 (use (match_operand:HI 3 "memory_operand" "m,m"))
4315 (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4316 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4317 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4319 [(set_attr "type" "fistp")
4320 (set_attr "i387_cw" "trunc")
4321 (set_attr "mode" "SI")])
4323 (define_insn "fix_truncsi_memory"
4324 [(set (match_operand:SI 0 "memory_operand" "=m")
4325 (fix:SI (match_operand 1 "register_operand" "f")))
4326 (use (match_operand:HI 2 "memory_operand" "m"))
4327 (use (match_operand:HI 3 "memory_operand" "m"))]
4328 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4329 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4330 "* return output_fix_trunc (insn, operands);"
4331 [(set_attr "type" "fistp")
4332 (set_attr "i387_cw" "trunc")
4333 (set_attr "mode" "SI")])
4335 ;; When SSE available, it is always faster to use it!
4336 (define_insn "fix_truncsfsi_sse"
4337 [(set (match_operand:SI 0 "register_operand" "=r,r")
4338 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4340 "cvttss2si\t{%1, %0|%0, %1}"
4341 [(set_attr "type" "sseicvt")
4342 (set_attr "mode" "DF")
4343 (set_attr "athlon_decode" "double,vector")])
4345 ;; Avoid vector decoded form of the instruction.
4347 [(match_scratch:SF 2 "x")
4348 (set (match_operand:SI 0 "register_operand" "")
4349 (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4350 "TARGET_K8 && !optimize_size"
4351 [(set (match_dup 2) (match_dup 1))
4352 (set (match_dup 0) (fix:SI (match_dup 2)))]
4355 (define_insn "fix_truncdfsi_sse"
4356 [(set (match_operand:SI 0 "register_operand" "=r,r")
4357 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4359 "cvttsd2si\t{%1, %0|%0, %1}"
4360 [(set_attr "type" "sseicvt")
4361 (set_attr "mode" "DF")
4362 (set_attr "athlon_decode" "double,vector")])
4364 ;; Avoid vector decoded form of the instruction.
4366 [(match_scratch:DF 2 "Y")
4367 (set (match_operand:SI 0 "register_operand" "")
4368 (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4369 "TARGET_K8 && !optimize_size"
4370 [(set (match_dup 2) (match_dup 1))
4371 (set (match_dup 0) (fix:SI (match_dup 2)))]
4375 [(set (match_operand:SI 0 "register_operand" "")
4376 (fix:SI (match_operand 1 "register_operand" "")))
4377 (use (match_operand:HI 2 "memory_operand" ""))
4378 (use (match_operand:HI 3 "memory_operand" ""))
4379 (clobber (match_operand:SI 4 "memory_operand" ""))]
4381 [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4383 (use (match_dup 3))])
4384 (set (match_dup 0) (match_dup 4))]
4388 [(set (match_operand:SI 0 "memory_operand" "")
4389 (fix:SI (match_operand 1 "register_operand" "")))
4390 (use (match_operand:HI 2 "memory_operand" ""))
4391 (use (match_operand:HI 3 "memory_operand" ""))
4392 (clobber (match_operand:SI 4 "memory_operand" ""))]
4394 [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4396 (use (match_dup 3))])]
4399 ;; Signed conversion to HImode.
4401 (define_expand "fix_truncxfhi2"
4402 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4403 (fix:HI (match_operand:XF 1 "register_operand" "")))
4404 (clobber (reg:CC FLAGS_REG))])]
4408 (define_expand "fix_truncdfhi2"
4409 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4410 (fix:HI (match_operand:DF 1 "register_operand" "")))
4411 (clobber (reg:CC FLAGS_REG))])]
4412 "TARGET_80387 && !TARGET_SSE2"
4415 (define_expand "fix_truncsfhi2"
4416 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4417 (fix:HI (match_operand:SF 1 "register_operand" "")))
4418 (clobber (reg:CC FLAGS_REG))])]
4419 "TARGET_80387 && !TARGET_SSE"
4422 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4423 ;; of the machinery.
4424 (define_insn_and_split "*fix_trunchi_1"
4425 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4426 (fix:HI (match_operand 1 "register_operand" "f,f")))
4427 (clobber (reg:CC FLAGS_REG))]
4428 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4429 && !reload_completed && !reload_in_progress
4430 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4435 ix86_optimize_mode_switching = 1;
4436 operands[2] = assign_386_stack_local (HImode, 1);
4437 operands[3] = assign_386_stack_local (HImode, 2);
4438 if (memory_operand (operands[0], VOIDmode))
4439 emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4440 operands[2], operands[3]));
4443 operands[4] = assign_386_stack_local (HImode, 0);
4444 emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4445 operands[2], operands[3],
4450 [(set_attr "type" "fistp")
4451 (set_attr "i387_cw" "trunc")
4452 (set_attr "mode" "HI")])
4454 (define_insn "fix_trunchi_nomemory"
4455 [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4456 (fix:HI (match_operand 1 "register_operand" "f,f")))
4457 (use (match_operand:HI 2 "memory_operand" "m,m"))
4458 (use (match_operand:HI 3 "memory_operand" "m,m"))
4459 (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4460 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4461 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4463 [(set_attr "type" "fistp")
4464 (set_attr "i387_cw" "trunc")
4465 (set_attr "mode" "HI")])
4467 (define_insn "fix_trunchi_memory"
4468 [(set (match_operand:HI 0 "memory_operand" "=m")
4469 (fix:HI (match_operand 1 "register_operand" "f")))
4470 (use (match_operand:HI 2 "memory_operand" "m"))
4471 (use (match_operand:HI 3 "memory_operand" "m"))]
4472 "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4473 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4474 "* return output_fix_trunc (insn, operands);"
4475 [(set_attr "type" "fistp")
4476 (set_attr "i387_cw" "trunc")
4477 (set_attr "mode" "HI")])
4480 [(set (match_operand:HI 0 "memory_operand" "")
4481 (fix:HI (match_operand 1 "register_operand" "")))
4482 (use (match_operand:HI 2 "memory_operand" ""))
4483 (use (match_operand:HI 3 "memory_operand" ""))
4484 (clobber (match_operand:HI 4 "memory_operand" ""))]
4486 [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4488 (use (match_dup 3))])]
4492 [(set (match_operand:HI 0 "register_operand" "")
4493 (fix:HI (match_operand 1 "register_operand" "")))
4494 (use (match_operand:HI 2 "memory_operand" ""))
4495 (use (match_operand:HI 3 "memory_operand" ""))
4496 (clobber (match_operand:HI 4 "memory_operand" ""))]
4498 [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4501 (clobber (match_dup 4))])
4502 (set (match_dup 0) (match_dup 4))]
4505 (define_insn "x86_fnstcw_1"
4506 [(set (match_operand:HI 0 "memory_operand" "=m")
4507 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4510 [(set_attr "length" "2")
4511 (set_attr "mode" "HI")
4512 (set_attr "unit" "i387")])
4514 (define_insn "x86_fldcw_1"
4515 [(set (reg:HI FPSR_REG)
4516 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4519 [(set_attr "length" "2")
4520 (set_attr "mode" "HI")
4521 (set_attr "unit" "i387")
4522 (set_attr "athlon_decode" "vector")])
4524 ;; Conversion between fixed point and floating point.
4526 ;; Even though we only accept memory inputs, the backend _really_
4527 ;; wants to be able to do this between registers.
4529 (define_expand "floathisf2"
4530 [(set (match_operand:SF 0 "register_operand" "")
4531 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4532 "TARGET_SSE || TARGET_80387"
4534 if (TARGET_SSE && TARGET_SSE_MATH)
4536 emit_insn (gen_floatsisf2 (operands[0],
4537 convert_to_mode (SImode, operands[1], 0)));
4542 (define_insn "*floathisf2_1"
4543 [(set (match_operand:SF 0 "register_operand" "=f,f")
4544 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4545 "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4549 [(set_attr "type" "fmov,multi")
4550 (set_attr "mode" "SF")
4551 (set_attr "fp_int_src" "true")])
4553 (define_expand "floatsisf2"
4554 [(set (match_operand:SF 0 "register_operand" "")
4555 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4556 "TARGET_SSE || TARGET_80387"
4559 (define_insn "*floatsisf2_i387"
4560 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4561 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4562 "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4566 cvtsi2ss\t{%1, %0|%0, %1}
4567 cvtsi2ss\t{%1, %0|%0, %1}"
4568 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4569 (set_attr "mode" "SF")
4570 (set_attr "athlon_decode" "*,*,vector,double")
4571 (set_attr "fp_int_src" "true")])
4573 (define_insn "*floatsisf2_sse"
4574 [(set (match_operand:SF 0 "register_operand" "=x,x")
4575 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4577 "cvtsi2ss\t{%1, %0|%0, %1}"
4578 [(set_attr "type" "sseicvt")
4579 (set_attr "mode" "SF")
4580 (set_attr "athlon_decode" "vector,double")
4581 (set_attr "fp_int_src" "true")])
4583 ; Avoid possible reformatting penalty on the destination by first
4586 [(set (match_operand:SF 0 "register_operand" "")
4587 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4588 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4589 && SSE_REG_P (operands[0])"
4593 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4594 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4595 emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4599 (define_expand "floatdisf2"
4600 [(set (match_operand:SF 0 "register_operand" "")
4601 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4602 "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4605 (define_insn "*floatdisf2_i387_only"
4606 [(set (match_operand:SF 0 "register_operand" "=f,?f")
4607 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4608 "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4612 [(set_attr "type" "fmov,multi")
4613 (set_attr "mode" "SF")
4614 (set_attr "fp_int_src" "true")])
4616 (define_insn "*floatdisf2_i387"
4617 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4618 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4619 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4623 cvtsi2ss{q}\t{%1, %0|%0, %1}
4624 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4625 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4626 (set_attr "mode" "SF")
4627 (set_attr "athlon_decode" "*,*,vector,double")
4628 (set_attr "fp_int_src" "true")])
4630 (define_insn "*floatdisf2_sse"
4631 [(set (match_operand:SF 0 "register_operand" "=x,x")
4632 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4633 "TARGET_64BIT && TARGET_SSE"
4634 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4635 [(set_attr "type" "sseicvt")
4636 (set_attr "mode" "SF")
4637 (set_attr "athlon_decode" "vector,double")
4638 (set_attr "fp_int_src" "true")])
4640 ; Avoid possible reformatting penalty on the destination by first
4643 [(set (match_operand:SF 0 "register_operand" "")
4644 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4645 "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4646 && SSE_REG_P (operands[0])"
4650 dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4651 emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4652 emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4656 (define_expand "floathidf2"
4657 [(set (match_operand:DF 0 "register_operand" "")
4658 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4659 "TARGET_SSE2 || TARGET_80387"
4661 if (TARGET_SSE && TARGET_SSE_MATH)
4663 emit_insn (gen_floatsidf2 (operands[0],
4664 convert_to_mode (SImode, operands[1], 0)));
4669 (define_insn "*floathidf2_1"
4670 [(set (match_operand:DF 0 "register_operand" "=f,f")
4671 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4672 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4676 [(set_attr "type" "fmov,multi")
4677 (set_attr "mode" "DF")
4678 (set_attr "fp_int_src" "true")])
4680 (define_expand "floatsidf2"
4681 [(set (match_operand:DF 0 "register_operand" "")
4682 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4683 "TARGET_80387 || TARGET_SSE2"
4686 (define_insn "*floatsidf2_i387"
4687 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4688 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4689 "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4693 cvtsi2sd\t{%1, %0|%0, %1}
4694 cvtsi2sd\t{%1, %0|%0, %1}"
4695 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4696 (set_attr "mode" "DF")
4697 (set_attr "athlon_decode" "*,*,double,direct")
4698 (set_attr "fp_int_src" "true")])
4700 (define_insn "*floatsidf2_sse"
4701 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4702 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4704 "cvtsi2sd\t{%1, %0|%0, %1}"
4705 [(set_attr "type" "sseicvt")
4706 (set_attr "mode" "DF")
4707 (set_attr "athlon_decode" "double,direct")
4708 (set_attr "fp_int_src" "true")])
4710 (define_expand "floatdidf2"
4711 [(set (match_operand:DF 0 "register_operand" "")
4712 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4713 "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
4716 (define_insn "*floatdidf2_i387_only"
4717 [(set (match_operand:DF 0 "register_operand" "=f,?f")
4718 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4719 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
4723 [(set_attr "type" "fmov,multi")
4724 (set_attr "mode" "DF")
4725 (set_attr "fp_int_src" "true")])
4727 (define_insn "*floatdidf2_i387"
4728 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4729 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4730 "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
4734 cvtsi2sd{q}\t{%1, %0|%0, %1}
4735 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4736 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4737 (set_attr "mode" "DF")
4738 (set_attr "athlon_decode" "*,*,double,direct")
4739 (set_attr "fp_int_src" "true")])
4741 (define_insn "*floatdidf2_sse"
4742 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4743 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4745 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4746 [(set_attr "type" "sseicvt")
4747 (set_attr "mode" "DF")
4748 (set_attr "athlon_decode" "double,direct")
4749 (set_attr "fp_int_src" "true")])
4751 (define_insn "floathixf2"
4752 [(set (match_operand:XF 0 "register_operand" "=f,f")
4753 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4758 [(set_attr "type" "fmov,multi")
4759 (set_attr "mode" "XF")
4760 (set_attr "fp_int_src" "true")])
4762 (define_insn "floatsixf2"
4763 [(set (match_operand:XF 0 "register_operand" "=f,f")
4764 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
4769 [(set_attr "type" "fmov,multi")
4770 (set_attr "mode" "XF")
4771 (set_attr "fp_int_src" "true")])
4773 (define_insn "floatdixf2"
4774 [(set (match_operand:XF 0 "register_operand" "=f,f")
4775 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4780 [(set_attr "type" "fmov,multi")
4781 (set_attr "mode" "XF")
4782 (set_attr "fp_int_src" "true")])
4784 ;; %%% Kill these when reload knows how to do it.
4786 [(set (match_operand 0 "fp_register_operand" "")
4787 (float (match_operand 1 "register_operand" "")))]
4788 "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
4791 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4792 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4793 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4794 ix86_free_from_memory (GET_MODE (operands[1]));
4798 (define_expand "floatunssisf2"
4799 [(use (match_operand:SF 0 "register_operand" ""))
4800 (use (match_operand:SI 1 "register_operand" ""))]
4801 "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
4802 "x86_emit_floatuns (operands); DONE;")
4804 (define_expand "floatunsdisf2"
4805 [(use (match_operand:SF 0 "register_operand" ""))
4806 (use (match_operand:DI 1 "register_operand" ""))]
4807 "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
4808 "x86_emit_floatuns (operands); DONE;")
4810 (define_expand "floatunsdidf2"
4811 [(use (match_operand:DF 0 "register_operand" ""))
4812 (use (match_operand:DI 1 "register_operand" ""))]
4813 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
4814 "x86_emit_floatuns (operands); DONE;")
4816 ;; SSE extract/set expanders
4818 (define_expand "vec_setv2df"
4819 [(match_operand:V2DF 0 "register_operand" "")
4820 (match_operand:DF 1 "register_operand" "")
4821 (match_operand 2 "const_int_operand" "")]
4824 switch (INTVAL (operands[2]))
4827 emit_insn (gen_sse2_movsd (operands[0], operands[0],
4828 simplify_gen_subreg (V2DFmode, operands[1],
4833 rtx op1 = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4835 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], op1));
4844 (define_expand "vec_extractv2df"
4845 [(match_operand:DF 0 "register_operand" "")
4846 (match_operand:V2DF 1 "register_operand" "")
4847 (match_operand 2 "const_int_operand" "")]
4850 switch (INTVAL (operands[2]))
4853 emit_move_insn (operands[0], gen_lowpart (DFmode, operands[1]));
4857 rtx dest = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4859 emit_insn (gen_sse2_unpckhpd (dest, operands[1], operands[1]));
4868 (define_expand "vec_initv2df"
4869 [(match_operand:V2DF 0 "register_operand" "")
4870 (match_operand 1 "" "")]
4873 ix86_expand_vector_init (operands[0], operands[1]);
4877 (define_expand "vec_setv4sf"
4878 [(match_operand:V4SF 0 "register_operand" "")
4879 (match_operand:SF 1 "register_operand" "")
4880 (match_operand 2 "const_int_operand" "")]
4883 switch (INTVAL (operands[2]))
4886 emit_insn (gen_sse_movss (operands[0], operands[0],
4887 simplify_gen_subreg (V4SFmode, operands[1],
4892 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4893 rtx tmp = gen_reg_rtx (V4SFmode);
4895 emit_move_insn (tmp, operands[0]);
4896 emit_insn (gen_sse_unpcklps (operands[0], operands[0], operands[0]));
4897 emit_insn (gen_sse_movss (operands[0], operands[0], op1));
4898 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4899 GEN_INT (1 + (0<<2) + (2<<4) + (3<<6))));
4904 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4905 rtx tmp = gen_reg_rtx (V4SFmode);
4907 emit_move_insn (tmp, operands[0]);
4908 emit_insn (gen_sse_movss (tmp, tmp, op1));
4909 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4910 GEN_INT (0 + (1<<2) + (0<<4) + (3<<6))));
4915 rtx op1 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4916 rtx tmp = gen_reg_rtx (V4SFmode);
4918 emit_move_insn (tmp, operands[0]);
4919 emit_insn (gen_sse_movss (tmp, tmp, op1));
4920 emit_insn (gen_sse_shufps (operands[0], operands[0], tmp,
4921 GEN_INT (0 + (1<<2) + (2<<4) + (0<<6))));
4930 (define_expand "vec_extractv4sf"
4931 [(match_operand:SF 0 "register_operand" "")
4932 (match_operand:V4SF 1 "register_operand" "")
4933 (match_operand 2 "const_int_operand" "")]
4936 switch (INTVAL (operands[2]))
4939 emit_move_insn (operands[0], gen_lowpart (SFmode, operands[1]));
4943 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4944 rtx tmp = gen_reg_rtx (V4SFmode);
4946 emit_move_insn (tmp, operands[1]);
4947 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4953 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4954 rtx tmp = gen_reg_rtx (V4SFmode);
4956 emit_move_insn (tmp, operands[1]);
4957 emit_insn (gen_sse_unpckhps (op0, tmp, tmp));
4962 rtx op0 = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4963 rtx tmp = gen_reg_rtx (V4SFmode);
4965 emit_move_insn (tmp, operands[1]);
4966 emit_insn (gen_sse_shufps (op0, tmp, tmp,
4976 (define_expand "vec_initv4sf"
4977 [(match_operand:V4SF 0 "register_operand" "")
4978 (match_operand 1 "" "")]
4981 ix86_expand_vector_init (operands[0], operands[1]);
4987 ;; %%% splits for addsidi3
4988 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4989 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4990 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4992 (define_expand "adddi3"
4993 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4994 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4995 (match_operand:DI 2 "x86_64_general_operand" "")))
4996 (clobber (reg:CC FLAGS_REG))]
4998 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5000 (define_insn "*adddi3_1"
5001 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5002 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5003 (match_operand:DI 2 "general_operand" "roiF,riF")))
5004 (clobber (reg:CC FLAGS_REG))]
5005 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5009 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5010 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5011 (match_operand:DI 2 "general_operand" "")))
5012 (clobber (reg:CC FLAGS_REG))]
5013 "!TARGET_64BIT && reload_completed"
5014 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5016 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5017 (parallel [(set (match_dup 3)
5018 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5021 (clobber (reg:CC FLAGS_REG))])]
5022 "split_di (operands+0, 1, operands+0, operands+3);
5023 split_di (operands+1, 1, operands+1, operands+4);
5024 split_di (operands+2, 1, operands+2, operands+5);")
5026 (define_insn "adddi3_carry_rex64"
5027 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5028 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5029 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5030 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5031 (clobber (reg:CC FLAGS_REG))]
5032 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5033 "adc{q}\t{%2, %0|%0, %2}"
5034 [(set_attr "type" "alu")
5035 (set_attr "pent_pair" "pu")
5036 (set_attr "mode" "DI")])
5038 (define_insn "*adddi3_cc_rex64"
5039 [(set (reg:CC FLAGS_REG)
5040 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5041 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5043 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5044 (plus:DI (match_dup 1) (match_dup 2)))]
5045 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5046 "add{q}\t{%2, %0|%0, %2}"
5047 [(set_attr "type" "alu")
5048 (set_attr "mode" "DI")])
5050 (define_insn "addqi3_carry"
5051 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5052 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5053 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5054 (match_operand:QI 2 "general_operand" "qi,qm")))
5055 (clobber (reg:CC FLAGS_REG))]
5056 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5057 "adc{b}\t{%2, %0|%0, %2}"
5058 [(set_attr "type" "alu")
5059 (set_attr "pent_pair" "pu")
5060 (set_attr "mode" "QI")])
5062 (define_insn "addhi3_carry"
5063 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5064 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5065 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5066 (match_operand:HI 2 "general_operand" "ri,rm")))
5067 (clobber (reg:CC FLAGS_REG))]
5068 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5069 "adc{w}\t{%2, %0|%0, %2}"
5070 [(set_attr "type" "alu")
5071 (set_attr "pent_pair" "pu")
5072 (set_attr "mode" "HI")])
5074 (define_insn "addsi3_carry"
5075 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5076 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5077 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5078 (match_operand:SI 2 "general_operand" "ri,rm")))
5079 (clobber (reg:CC FLAGS_REG))]
5080 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5081 "adc{l}\t{%2, %0|%0, %2}"
5082 [(set_attr "type" "alu")
5083 (set_attr "pent_pair" "pu")
5084 (set_attr "mode" "SI")])
5086 (define_insn "*addsi3_carry_zext"
5087 [(set (match_operand:DI 0 "register_operand" "=r")
5089 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5090 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5091 (match_operand:SI 2 "general_operand" "rim"))))
5092 (clobber (reg:CC FLAGS_REG))]
5093 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5094 "adc{l}\t{%2, %k0|%k0, %2}"
5095 [(set_attr "type" "alu")
5096 (set_attr "pent_pair" "pu")
5097 (set_attr "mode" "SI")])
5099 (define_insn "*addsi3_cc"
5100 [(set (reg:CC FLAGS_REG)
5101 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5102 (match_operand:SI 2 "general_operand" "ri,rm")]
5104 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5105 (plus:SI (match_dup 1) (match_dup 2)))]
5106 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5107 "add{l}\t{%2, %0|%0, %2}"
5108 [(set_attr "type" "alu")
5109 (set_attr "mode" "SI")])
5111 (define_insn "addqi3_cc"
5112 [(set (reg:CC FLAGS_REG)
5113 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5114 (match_operand:QI 2 "general_operand" "qi,qm")]
5116 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5117 (plus:QI (match_dup 1) (match_dup 2)))]
5118 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5119 "add{b}\t{%2, %0|%0, %2}"
5120 [(set_attr "type" "alu")
5121 (set_attr "mode" "QI")])
5123 (define_expand "addsi3"
5124 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5125 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5126 (match_operand:SI 2 "general_operand" "")))
5127 (clobber (reg:CC FLAGS_REG))])]
5129 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5131 (define_insn "*lea_1"
5132 [(set (match_operand:SI 0 "register_operand" "=r")
5133 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5135 "lea{l}\t{%a1, %0|%0, %a1}"
5136 [(set_attr "type" "lea")
5137 (set_attr "mode" "SI")])
5139 (define_insn "*lea_1_rex64"
5140 [(set (match_operand:SI 0 "register_operand" "=r")
5141 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5143 "lea{l}\t{%a1, %0|%0, %a1}"
5144 [(set_attr "type" "lea")
5145 (set_attr "mode" "SI")])
5147 (define_insn "*lea_1_zext"
5148 [(set (match_operand:DI 0 "register_operand" "=r")
5150 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5152 "lea{l}\t{%a1, %k0|%k0, %a1}"
5153 [(set_attr "type" "lea")
5154 (set_attr "mode" "SI")])
5156 (define_insn "*lea_2_rex64"
5157 [(set (match_operand:DI 0 "register_operand" "=r")
5158 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5160 "lea{q}\t{%a1, %0|%0, %a1}"
5161 [(set_attr "type" "lea")
5162 (set_attr "mode" "DI")])
5164 ;; The lea patterns for non-Pmodes needs to be matched by several
5165 ;; insns converted to real lea by splitters.
5167 (define_insn_and_split "*lea_general_1"
5168 [(set (match_operand 0 "register_operand" "=r")
5169 (plus (plus (match_operand 1 "index_register_operand" "r")
5170 (match_operand 2 "register_operand" "r"))
5171 (match_operand 3 "immediate_operand" "i")))]
5172 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5173 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5174 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5175 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5176 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5177 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5178 || GET_MODE (operands[3]) == VOIDmode)"
5180 "&& reload_completed"
5184 operands[0] = gen_lowpart (SImode, operands[0]);
5185 operands[1] = gen_lowpart (Pmode, operands[1]);
5186 operands[2] = gen_lowpart (Pmode, operands[2]);
5187 operands[3] = gen_lowpart (Pmode, operands[3]);
5188 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5190 if (Pmode != SImode)
5191 pat = gen_rtx_SUBREG (SImode, pat, 0);
5192 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5195 [(set_attr "type" "lea")
5196 (set_attr "mode" "SI")])
5198 (define_insn_and_split "*lea_general_1_zext"
5199 [(set (match_operand:DI 0 "register_operand" "=r")
5201 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5202 (match_operand:SI 2 "register_operand" "r"))
5203 (match_operand:SI 3 "immediate_operand" "i"))))]
5206 "&& reload_completed"
5208 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5210 (match_dup 3)) 0)))]
5212 operands[1] = gen_lowpart (Pmode, operands[1]);
5213 operands[2] = gen_lowpart (Pmode, operands[2]);
5214 operands[3] = gen_lowpart (Pmode, operands[3]);
5216 [(set_attr "type" "lea")
5217 (set_attr "mode" "SI")])
5219 (define_insn_and_split "*lea_general_2"
5220 [(set (match_operand 0 "register_operand" "=r")
5221 (plus (mult (match_operand 1 "index_register_operand" "r")
5222 (match_operand 2 "const248_operand" "i"))
5223 (match_operand 3 "nonmemory_operand" "ri")))]
5224 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5225 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5226 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5227 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5228 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5229 || GET_MODE (operands[3]) == VOIDmode)"
5231 "&& reload_completed"
5235 operands[0] = gen_lowpart (SImode, operands[0]);
5236 operands[1] = gen_lowpart (Pmode, operands[1]);
5237 operands[3] = gen_lowpart (Pmode, operands[3]);
5238 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5240 if (Pmode != SImode)
5241 pat = gen_rtx_SUBREG (SImode, pat, 0);
5242 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5245 [(set_attr "type" "lea")
5246 (set_attr "mode" "SI")])
5248 (define_insn_and_split "*lea_general_2_zext"
5249 [(set (match_operand:DI 0 "register_operand" "=r")
5251 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5252 (match_operand:SI 2 "const248_operand" "n"))
5253 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5256 "&& reload_completed"
5258 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5260 (match_dup 3)) 0)))]
5262 operands[1] = gen_lowpart (Pmode, operands[1]);
5263 operands[3] = gen_lowpart (Pmode, operands[3]);
5265 [(set_attr "type" "lea")
5266 (set_attr "mode" "SI")])
5268 (define_insn_and_split "*lea_general_3"
5269 [(set (match_operand 0 "register_operand" "=r")
5270 (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5271 (match_operand 2 "const248_operand" "i"))
5272 (match_operand 3 "register_operand" "r"))
5273 (match_operand 4 "immediate_operand" "i")))]
5274 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5275 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5276 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5277 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5278 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5280 "&& reload_completed"
5284 operands[0] = gen_lowpart (SImode, operands[0]);
5285 operands[1] = gen_lowpart (Pmode, operands[1]);
5286 operands[3] = gen_lowpart (Pmode, operands[3]);
5287 operands[4] = gen_lowpart (Pmode, operands[4]);
5288 pat = gen_rtx_PLUS (Pmode,
5289 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5293 if (Pmode != SImode)
5294 pat = gen_rtx_SUBREG (SImode, pat, 0);
5295 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5298 [(set_attr "type" "lea")
5299 (set_attr "mode" "SI")])
5301 (define_insn_and_split "*lea_general_3_zext"
5302 [(set (match_operand:DI 0 "register_operand" "=r")
5304 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5305 (match_operand:SI 2 "const248_operand" "n"))
5306 (match_operand:SI 3 "register_operand" "r"))
5307 (match_operand:SI 4 "immediate_operand" "i"))))]
5310 "&& reload_completed"
5312 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5315 (match_dup 4)) 0)))]
5317 operands[1] = gen_lowpart (Pmode, operands[1]);
5318 operands[3] = gen_lowpart (Pmode, operands[3]);
5319 operands[4] = gen_lowpart (Pmode, operands[4]);
5321 [(set_attr "type" "lea")
5322 (set_attr "mode" "SI")])
5324 (define_insn "*adddi_1_rex64"
5325 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5326 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5327 (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5328 (clobber (reg:CC FLAGS_REG))]
5329 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5331 switch (get_attr_type (insn))
5334 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5335 return "lea{q}\t{%a2, %0|%0, %a2}";
5338 if (! rtx_equal_p (operands[0], operands[1]))
5340 if (operands[2] == const1_rtx)
5341 return "inc{q}\t%0";
5342 else if (operands[2] == constm1_rtx)
5343 return "dec{q}\t%0";
5348 if (! rtx_equal_p (operands[0], operands[1]))
5351 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5352 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5353 if (GET_CODE (operands[2]) == CONST_INT
5354 /* Avoid overflows. */
5355 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5356 && (INTVAL (operands[2]) == 128
5357 || (INTVAL (operands[2]) < 0
5358 && INTVAL (operands[2]) != -128)))
5360 operands[2] = GEN_INT (-INTVAL (operands[2]));
5361 return "sub{q}\t{%2, %0|%0, %2}";
5363 return "add{q}\t{%2, %0|%0, %2}";
5367 (cond [(eq_attr "alternative" "2")
5368 (const_string "lea")
5369 ; Current assemblers are broken and do not allow @GOTOFF in
5370 ; ought but a memory context.
5371 (match_operand:DI 2 "pic_symbolic_operand" "")
5372 (const_string "lea")
5373 (match_operand:DI 2 "incdec_operand" "")
5374 (const_string "incdec")
5376 (const_string "alu")))
5377 (set_attr "mode" "DI")])
5379 ;; Convert lea to the lea pattern to avoid flags dependency.
5381 [(set (match_operand:DI 0 "register_operand" "")
5382 (plus:DI (match_operand:DI 1 "register_operand" "")
5383 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5384 (clobber (reg:CC FLAGS_REG))]
5385 "TARGET_64BIT && reload_completed
5386 && true_regnum (operands[0]) != true_regnum (operands[1])"
5388 (plus:DI (match_dup 1)
5392 (define_insn "*adddi_2_rex64"
5395 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5396 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5398 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5399 (plus:DI (match_dup 1) (match_dup 2)))]
5400 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5401 && ix86_binary_operator_ok (PLUS, DImode, operands)
5402 /* Current assemblers are broken and do not allow @GOTOFF in
5403 ought but a memory context. */
5404 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5406 switch (get_attr_type (insn))
5409 if (! rtx_equal_p (operands[0], operands[1]))
5411 if (operands[2] == const1_rtx)
5412 return "inc{q}\t%0";
5413 else if (operands[2] == constm1_rtx)
5414 return "dec{q}\t%0";
5419 if (! rtx_equal_p (operands[0], operands[1]))
5421 /* ???? We ought to handle there the 32bit case too
5422 - do we need new constraint? */
5423 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5424 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5425 if (GET_CODE (operands[2]) == CONST_INT
5426 /* Avoid overflows. */
5427 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5428 && (INTVAL (operands[2]) == 128
5429 || (INTVAL (operands[2]) < 0
5430 && INTVAL (operands[2]) != -128)))
5432 operands[2] = GEN_INT (-INTVAL (operands[2]));
5433 return "sub{q}\t{%2, %0|%0, %2}";
5435 return "add{q}\t{%2, %0|%0, %2}";
5439 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5440 (const_string "incdec")
5441 (const_string "alu")))
5442 (set_attr "mode" "DI")])
5444 (define_insn "*adddi_3_rex64"
5446 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5447 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5448 (clobber (match_scratch:DI 0 "=r"))]
5450 && ix86_match_ccmode (insn, CCZmode)
5451 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5452 /* Current assemblers are broken and do not allow @GOTOFF in
5453 ought but a memory context. */
5454 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5456 switch (get_attr_type (insn))
5459 if (! rtx_equal_p (operands[0], operands[1]))
5461 if (operands[2] == const1_rtx)
5462 return "inc{q}\t%0";
5463 else if (operands[2] == constm1_rtx)
5464 return "dec{q}\t%0";
5469 if (! rtx_equal_p (operands[0], operands[1]))
5471 /* ???? We ought to handle there the 32bit case too
5472 - do we need new constraint? */
5473 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5474 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5475 if (GET_CODE (operands[2]) == CONST_INT
5476 /* Avoid overflows. */
5477 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5478 && (INTVAL (operands[2]) == 128
5479 || (INTVAL (operands[2]) < 0
5480 && INTVAL (operands[2]) != -128)))
5482 operands[2] = GEN_INT (-INTVAL (operands[2]));
5483 return "sub{q}\t{%2, %0|%0, %2}";
5485 return "add{q}\t{%2, %0|%0, %2}";
5489 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5490 (const_string "incdec")
5491 (const_string "alu")))
5492 (set_attr "mode" "DI")])
5494 ; For comparisons against 1, -1 and 128, we may generate better code
5495 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5496 ; is matched then. We can't accept general immediate, because for
5497 ; case of overflows, the result is messed up.
5498 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5500 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5501 ; only for comparisons not depending on it.
5502 (define_insn "*adddi_4_rex64"
5504 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5505 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5506 (clobber (match_scratch:DI 0 "=rm"))]
5508 && ix86_match_ccmode (insn, CCGCmode)"
5510 switch (get_attr_type (insn))
5513 if (operands[2] == constm1_rtx)
5514 return "inc{q}\t%0";
5515 else if (operands[2] == const1_rtx)
5516 return "dec{q}\t%0";
5521 if (! rtx_equal_p (operands[0], operands[1]))
5523 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5524 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5525 if ((INTVAL (operands[2]) == -128
5526 || (INTVAL (operands[2]) > 0
5527 && INTVAL (operands[2]) != 128))
5528 /* Avoid overflows. */
5529 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5530 return "sub{q}\t{%2, %0|%0, %2}";
5531 operands[2] = GEN_INT (-INTVAL (operands[2]));
5532 return "add{q}\t{%2, %0|%0, %2}";
5536 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5537 (const_string "incdec")
5538 (const_string "alu")))
5539 (set_attr "mode" "DI")])
5541 (define_insn "*adddi_5_rex64"
5544 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5545 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5547 (clobber (match_scratch:DI 0 "=r"))]
5549 && ix86_match_ccmode (insn, CCGOCmode)
5550 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5551 /* Current assemblers are broken and do not allow @GOTOFF in
5552 ought but a memory context. */
5553 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555 switch (get_attr_type (insn))
5558 if (! rtx_equal_p (operands[0], operands[1]))
5560 if (operands[2] == const1_rtx)
5561 return "inc{q}\t%0";
5562 else if (operands[2] == constm1_rtx)
5563 return "dec{q}\t%0";
5568 if (! rtx_equal_p (operands[0], operands[1]))
5570 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5571 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5572 if (GET_CODE (operands[2]) == CONST_INT
5573 /* Avoid overflows. */
5574 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5575 && (INTVAL (operands[2]) == 128
5576 || (INTVAL (operands[2]) < 0
5577 && INTVAL (operands[2]) != -128)))
5579 operands[2] = GEN_INT (-INTVAL (operands[2]));
5580 return "sub{q}\t{%2, %0|%0, %2}";
5582 return "add{q}\t{%2, %0|%0, %2}";
5586 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5587 (const_string "incdec")
5588 (const_string "alu")))
5589 (set_attr "mode" "DI")])
5592 (define_insn "*addsi_1"
5593 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5594 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5595 (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5596 (clobber (reg:CC FLAGS_REG))]
5597 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5599 switch (get_attr_type (insn))
5602 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5603 return "lea{l}\t{%a2, %0|%0, %a2}";
5606 if (! rtx_equal_p (operands[0], operands[1]))
5608 if (operands[2] == const1_rtx)
5609 return "inc{l}\t%0";
5610 else if (operands[2] == constm1_rtx)
5611 return "dec{l}\t%0";
5616 if (! rtx_equal_p (operands[0], operands[1]))
5619 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5621 if (GET_CODE (operands[2]) == CONST_INT
5622 && (INTVAL (operands[2]) == 128
5623 || (INTVAL (operands[2]) < 0
5624 && INTVAL (operands[2]) != -128)))
5626 operands[2] = GEN_INT (-INTVAL (operands[2]));
5627 return "sub{l}\t{%2, %0|%0, %2}";
5629 return "add{l}\t{%2, %0|%0, %2}";
5633 (cond [(eq_attr "alternative" "2")
5634 (const_string "lea")
5635 ; Current assemblers are broken and do not allow @GOTOFF in
5636 ; ought but a memory context.
5637 (match_operand:SI 2 "pic_symbolic_operand" "")
5638 (const_string "lea")
5639 (match_operand:SI 2 "incdec_operand" "")
5640 (const_string "incdec")
5642 (const_string "alu")))
5643 (set_attr "mode" "SI")])
5645 ;; Convert lea to the lea pattern to avoid flags dependency.
5647 [(set (match_operand 0 "register_operand" "")
5648 (plus (match_operand 1 "register_operand" "")
5649 (match_operand 2 "nonmemory_operand" "")))
5650 (clobber (reg:CC FLAGS_REG))]
5652 && true_regnum (operands[0]) != true_regnum (operands[1])"
5656 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5657 may confuse gen_lowpart. */
5658 if (GET_MODE (operands[0]) != Pmode)
5660 operands[1] = gen_lowpart (Pmode, operands[1]);
5661 operands[2] = gen_lowpart (Pmode, operands[2]);
5663 operands[0] = gen_lowpart (SImode, operands[0]);
5664 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5665 if (Pmode != SImode)
5666 pat = gen_rtx_SUBREG (SImode, pat, 0);
5667 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5671 ;; It may seem that nonimmediate operand is proper one for operand 1.
5672 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5673 ;; we take care in ix86_binary_operator_ok to not allow two memory
5674 ;; operands so proper swapping will be done in reload. This allow
5675 ;; patterns constructed from addsi_1 to match.
5676 (define_insn "addsi_1_zext"
5677 [(set (match_operand:DI 0 "register_operand" "=r,r")
5679 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5680 (match_operand:SI 2 "general_operand" "rmni,rni"))))
5681 (clobber (reg:CC FLAGS_REG))]
5682 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5684 switch (get_attr_type (insn))
5687 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5688 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5691 if (operands[2] == const1_rtx)
5692 return "inc{l}\t%k0";
5693 else if (operands[2] == constm1_rtx)
5694 return "dec{l}\t%k0";
5699 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5700 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5701 if (GET_CODE (operands[2]) == CONST_INT
5702 && (INTVAL (operands[2]) == 128
5703 || (INTVAL (operands[2]) < 0
5704 && INTVAL (operands[2]) != -128)))
5706 operands[2] = GEN_INT (-INTVAL (operands[2]));
5707 return "sub{l}\t{%2, %k0|%k0, %2}";
5709 return "add{l}\t{%2, %k0|%k0, %2}";
5713 (cond [(eq_attr "alternative" "1")
5714 (const_string "lea")
5715 ; Current assemblers are broken and do not allow @GOTOFF in
5716 ; ought but a memory context.
5717 (match_operand:SI 2 "pic_symbolic_operand" "")
5718 (const_string "lea")
5719 (match_operand:SI 2 "incdec_operand" "")
5720 (const_string "incdec")
5722 (const_string "alu")))
5723 (set_attr "mode" "SI")])
5725 ;; Convert lea to the lea pattern to avoid flags dependency.
5727 [(set (match_operand:DI 0 "register_operand" "")
5729 (plus:SI (match_operand:SI 1 "register_operand" "")
5730 (match_operand:SI 2 "nonmemory_operand" ""))))
5731 (clobber (reg:CC FLAGS_REG))]
5732 "TARGET_64BIT && reload_completed
5733 && true_regnum (operands[0]) != true_regnum (operands[1])"
5735 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5737 operands[1] = gen_lowpart (Pmode, operands[1]);
5738 operands[2] = gen_lowpart (Pmode, operands[2]);
5741 (define_insn "*addsi_2"
5744 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5745 (match_operand:SI 2 "general_operand" "rmni,rni"))
5747 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5748 (plus:SI (match_dup 1) (match_dup 2)))]
5749 "ix86_match_ccmode (insn, CCGOCmode)
5750 && ix86_binary_operator_ok (PLUS, SImode, operands)
5751 /* Current assemblers are broken and do not allow @GOTOFF in
5752 ought but a memory context. */
5753 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5755 switch (get_attr_type (insn))
5758 if (! rtx_equal_p (operands[0], operands[1]))
5760 if (operands[2] == const1_rtx)
5761 return "inc{l}\t%0";
5762 else if (operands[2] == constm1_rtx)
5763 return "dec{l}\t%0";
5768 if (! rtx_equal_p (operands[0], operands[1]))
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 (GET_CODE (operands[2]) == CONST_INT
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, %0|%0, %2}";
5780 return "add{l}\t{%2, %0|%0, %2}";
5784 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5785 (const_string "incdec")
5786 (const_string "alu")))
5787 (set_attr "mode" "SI")])
5789 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5790 (define_insn "*addsi_2_zext"
5793 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5794 (match_operand:SI 2 "general_operand" "rmni"))
5796 (set (match_operand:DI 0 "register_operand" "=r")
5797 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5798 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5799 && ix86_binary_operator_ok (PLUS, SImode, operands)
5800 /* Current assemblers are broken and do not allow @GOTOFF in
5801 ought but a memory context. */
5802 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5804 switch (get_attr_type (insn))
5807 if (operands[2] == const1_rtx)
5808 return "inc{l}\t%k0";
5809 else if (operands[2] == constm1_rtx)
5810 return "dec{l}\t%k0";
5815 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5816 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5817 if (GET_CODE (operands[2]) == CONST_INT
5818 && (INTVAL (operands[2]) == 128
5819 || (INTVAL (operands[2]) < 0
5820 && INTVAL (operands[2]) != -128)))
5822 operands[2] = GEN_INT (-INTVAL (operands[2]));
5823 return "sub{l}\t{%2, %k0|%k0, %2}";
5825 return "add{l}\t{%2, %k0|%k0, %2}";
5829 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5830 (const_string "incdec")
5831 (const_string "alu")))
5832 (set_attr "mode" "SI")])
5834 (define_insn "*addsi_3"
5836 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5837 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5838 (clobber (match_scratch:SI 0 "=r"))]
5839 "ix86_match_ccmode (insn, CCZmode)
5840 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5841 /* Current assemblers are broken and do not allow @GOTOFF in
5842 ought but a memory context. */
5843 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5845 switch (get_attr_type (insn))
5848 if (! rtx_equal_p (operands[0], operands[1]))
5850 if (operands[2] == const1_rtx)
5851 return "inc{l}\t%0";
5852 else if (operands[2] == constm1_rtx)
5853 return "dec{l}\t%0";
5858 if (! rtx_equal_p (operands[0], operands[1]))
5860 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5861 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5862 if (GET_CODE (operands[2]) == CONST_INT
5863 && (INTVAL (operands[2]) == 128
5864 || (INTVAL (operands[2]) < 0
5865 && INTVAL (operands[2]) != -128)))
5867 operands[2] = GEN_INT (-INTVAL (operands[2]));
5868 return "sub{l}\t{%2, %0|%0, %2}";
5870 return "add{l}\t{%2, %0|%0, %2}";
5874 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5875 (const_string "incdec")
5876 (const_string "alu")))
5877 (set_attr "mode" "SI")])
5879 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5880 (define_insn "*addsi_3_zext"
5882 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5883 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5884 (set (match_operand:DI 0 "register_operand" "=r")
5885 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5886 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5887 && ix86_binary_operator_ok (PLUS, SImode, operands)
5888 /* Current assemblers are broken and do not allow @GOTOFF in
5889 ought but a memory context. */
5890 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5892 switch (get_attr_type (insn))
5895 if (operands[2] == const1_rtx)
5896 return "inc{l}\t%k0";
5897 else if (operands[2] == constm1_rtx)
5898 return "dec{l}\t%k0";
5903 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5904 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5905 if (GET_CODE (operands[2]) == CONST_INT
5906 && (INTVAL (operands[2]) == 128
5907 || (INTVAL (operands[2]) < 0
5908 && INTVAL (operands[2]) != -128)))
5910 operands[2] = GEN_INT (-INTVAL (operands[2]));
5911 return "sub{l}\t{%2, %k0|%k0, %2}";
5913 return "add{l}\t{%2, %k0|%k0, %2}";
5917 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5918 (const_string "incdec")
5919 (const_string "alu")))
5920 (set_attr "mode" "SI")])
5922 ; For comparisons against 1, -1 and 128, we may generate better code
5923 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5924 ; is matched then. We can't accept general immediate, because for
5925 ; case of overflows, the result is messed up.
5926 ; This pattern also don't hold of 0x80000000, since the value overflows
5928 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5929 ; only for comparisons not depending on it.
5930 (define_insn "*addsi_4"
5932 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5933 (match_operand:SI 2 "const_int_operand" "n")))
5934 (clobber (match_scratch:SI 0 "=rm"))]
5935 "ix86_match_ccmode (insn, CCGCmode)
5936 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5938 switch (get_attr_type (insn))
5941 if (operands[2] == constm1_rtx)
5942 return "inc{l}\t%0";
5943 else if (operands[2] == const1_rtx)
5944 return "dec{l}\t%0";
5949 if (! rtx_equal_p (operands[0], operands[1]))
5951 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5952 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5953 if ((INTVAL (operands[2]) == -128
5954 || (INTVAL (operands[2]) > 0
5955 && INTVAL (operands[2]) != 128)))
5956 return "sub{l}\t{%2, %0|%0, %2}";
5957 operands[2] = GEN_INT (-INTVAL (operands[2]));
5958 return "add{l}\t{%2, %0|%0, %2}";
5962 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5963 (const_string "incdec")
5964 (const_string "alu")))
5965 (set_attr "mode" "SI")])
5967 (define_insn "*addsi_5"
5970 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5971 (match_operand:SI 2 "general_operand" "rmni"))
5973 (clobber (match_scratch:SI 0 "=r"))]
5974 "ix86_match_ccmode (insn, CCGOCmode)
5975 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5976 /* Current assemblers are broken and do not allow @GOTOFF in
5977 ought but a memory context. */
5978 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5980 switch (get_attr_type (insn))
5983 if (! rtx_equal_p (operands[0], operands[1]))
5985 if (operands[2] == const1_rtx)
5986 return "inc{l}\t%0";
5987 else if (operands[2] == constm1_rtx)
5988 return "dec{l}\t%0";
5993 if (! rtx_equal_p (operands[0], operands[1]))
5995 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5997 if (GET_CODE (operands[2]) == CONST_INT
5998 && (INTVAL (operands[2]) == 128
5999 || (INTVAL (operands[2]) < 0
6000 && INTVAL (operands[2]) != -128)))
6002 operands[2] = GEN_INT (-INTVAL (operands[2]));
6003 return "sub{l}\t{%2, %0|%0, %2}";
6005 return "add{l}\t{%2, %0|%0, %2}";
6009 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6010 (const_string "incdec")
6011 (const_string "alu")))
6012 (set_attr "mode" "SI")])
6014 (define_expand "addhi3"
6015 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6016 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6017 (match_operand:HI 2 "general_operand" "")))
6018 (clobber (reg:CC FLAGS_REG))])]
6019 "TARGET_HIMODE_MATH"
6020 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6022 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6023 ;; type optimizations enabled by define-splits. This is not important
6024 ;; for PII, and in fact harmful because of partial register stalls.
6026 (define_insn "*addhi_1_lea"
6027 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6028 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6029 (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6030 (clobber (reg:CC FLAGS_REG))]
6031 "!TARGET_PARTIAL_REG_STALL
6032 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6034 switch (get_attr_type (insn))
6039 if (operands[2] == const1_rtx)
6040 return "inc{w}\t%0";
6041 else if (operands[2] == constm1_rtx)
6042 return "dec{w}\t%0";
6046 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6047 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6048 if (GET_CODE (operands[2]) == CONST_INT
6049 && (INTVAL (operands[2]) == 128
6050 || (INTVAL (operands[2]) < 0
6051 && INTVAL (operands[2]) != -128)))
6053 operands[2] = GEN_INT (-INTVAL (operands[2]));
6054 return "sub{w}\t{%2, %0|%0, %2}";
6056 return "add{w}\t{%2, %0|%0, %2}";
6060 (if_then_else (eq_attr "alternative" "2")
6061 (const_string "lea")
6062 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6063 (const_string "incdec")
6064 (const_string "alu"))))
6065 (set_attr "mode" "HI,HI,SI")])
6067 (define_insn "*addhi_1"
6068 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6069 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6070 (match_operand:HI 2 "general_operand" "ri,rm")))
6071 (clobber (reg:CC FLAGS_REG))]
6072 "TARGET_PARTIAL_REG_STALL
6073 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6075 switch (get_attr_type (insn))
6078 if (operands[2] == const1_rtx)
6079 return "inc{w}\t%0";
6080 else if (operands[2] == constm1_rtx)
6081 return "dec{w}\t%0";
6085 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6087 if (GET_CODE (operands[2]) == CONST_INT
6088 && (INTVAL (operands[2]) == 128
6089 || (INTVAL (operands[2]) < 0
6090 && INTVAL (operands[2]) != -128)))
6092 operands[2] = GEN_INT (-INTVAL (operands[2]));
6093 return "sub{w}\t{%2, %0|%0, %2}";
6095 return "add{w}\t{%2, %0|%0, %2}";
6099 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6100 (const_string "incdec")
6101 (const_string "alu")))
6102 (set_attr "mode" "HI")])
6104 (define_insn "*addhi_2"
6107 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6108 (match_operand:HI 2 "general_operand" "rmni,rni"))
6110 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6111 (plus:HI (match_dup 1) (match_dup 2)))]
6112 "ix86_match_ccmode (insn, CCGOCmode)
6113 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6115 switch (get_attr_type (insn))
6118 if (operands[2] == const1_rtx)
6119 return "inc{w}\t%0";
6120 else if (operands[2] == constm1_rtx)
6121 return "dec{w}\t%0";
6125 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6127 if (GET_CODE (operands[2]) == CONST_INT
6128 && (INTVAL (operands[2]) == 128
6129 || (INTVAL (operands[2]) < 0
6130 && INTVAL (operands[2]) != -128)))
6132 operands[2] = GEN_INT (-INTVAL (operands[2]));
6133 return "sub{w}\t{%2, %0|%0, %2}";
6135 return "add{w}\t{%2, %0|%0, %2}";
6139 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6140 (const_string "incdec")
6141 (const_string "alu")))
6142 (set_attr "mode" "HI")])
6144 (define_insn "*addhi_3"
6146 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6147 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6148 (clobber (match_scratch:HI 0 "=r"))]
6149 "ix86_match_ccmode (insn, CCZmode)
6150 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6152 switch (get_attr_type (insn))
6155 if (operands[2] == const1_rtx)
6156 return "inc{w}\t%0";
6157 else if (operands[2] == constm1_rtx)
6158 return "dec{w}\t%0";
6162 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6163 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6164 if (GET_CODE (operands[2]) == CONST_INT
6165 && (INTVAL (operands[2]) == 128
6166 || (INTVAL (operands[2]) < 0
6167 && INTVAL (operands[2]) != -128)))
6169 operands[2] = GEN_INT (-INTVAL (operands[2]));
6170 return "sub{w}\t{%2, %0|%0, %2}";
6172 return "add{w}\t{%2, %0|%0, %2}";
6176 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6177 (const_string "incdec")
6178 (const_string "alu")))
6179 (set_attr "mode" "HI")])
6181 ; See comments above addsi_3_imm for details.
6182 (define_insn "*addhi_4"
6184 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6185 (match_operand:HI 2 "const_int_operand" "n")))
6186 (clobber (match_scratch:HI 0 "=rm"))]
6187 "ix86_match_ccmode (insn, CCGCmode)
6188 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6190 switch (get_attr_type (insn))
6193 if (operands[2] == constm1_rtx)
6194 return "inc{w}\t%0";
6195 else if (operands[2] == const1_rtx)
6196 return "dec{w}\t%0";
6201 if (! rtx_equal_p (operands[0], operands[1]))
6203 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6204 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6205 if ((INTVAL (operands[2]) == -128
6206 || (INTVAL (operands[2]) > 0
6207 && INTVAL (operands[2]) != 128)))
6208 return "sub{w}\t{%2, %0|%0, %2}";
6209 operands[2] = GEN_INT (-INTVAL (operands[2]));
6210 return "add{w}\t{%2, %0|%0, %2}";
6214 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6215 (const_string "incdec")
6216 (const_string "alu")))
6217 (set_attr "mode" "SI")])
6220 (define_insn "*addhi_5"
6223 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6224 (match_operand:HI 2 "general_operand" "rmni"))
6226 (clobber (match_scratch:HI 0 "=r"))]
6227 "ix86_match_ccmode (insn, CCGOCmode)
6228 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6230 switch (get_attr_type (insn))
6233 if (operands[2] == const1_rtx)
6234 return "inc{w}\t%0";
6235 else if (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 (GET_CODE (operands[2]) == CONST_INT
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 (define_expand "addqi3"
6260 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6261 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6262 (match_operand:QI 2 "general_operand" "")))
6263 (clobber (reg:CC FLAGS_REG))])]
6264 "TARGET_QIMODE_MATH"
6265 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6267 ;; %%% Potential partial reg stall on alternative 2. What to do?
6268 (define_insn "*addqi_1_lea"
6269 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6270 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6271 (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6272 (clobber (reg:CC FLAGS_REG))]
6273 "!TARGET_PARTIAL_REG_STALL
6274 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6276 int widen = (which_alternative == 2);
6277 switch (get_attr_type (insn))
6282 if (operands[2] == const1_rtx)
6283 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6284 else if (operands[2] == constm1_rtx)
6285 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6289 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6290 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6291 if (GET_CODE (operands[2]) == CONST_INT
6292 && (INTVAL (operands[2]) == 128
6293 || (INTVAL (operands[2]) < 0
6294 && INTVAL (operands[2]) != -128)))
6296 operands[2] = GEN_INT (-INTVAL (operands[2]));
6298 return "sub{l}\t{%2, %k0|%k0, %2}";
6300 return "sub{b}\t{%2, %0|%0, %2}";
6303 return "add{l}\t{%k2, %k0|%k0, %k2}";
6305 return "add{b}\t{%2, %0|%0, %2}";
6309 (if_then_else (eq_attr "alternative" "3")
6310 (const_string "lea")
6311 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6312 (const_string "incdec")
6313 (const_string "alu"))))
6314 (set_attr "mode" "QI,QI,SI,SI")])
6316 (define_insn "*addqi_1"
6317 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6318 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6319 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6320 (clobber (reg:CC FLAGS_REG))]
6321 "TARGET_PARTIAL_REG_STALL
6322 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6324 int widen = (which_alternative == 2);
6325 switch (get_attr_type (insn))
6328 if (operands[2] == const1_rtx)
6329 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6330 else if (operands[2] == constm1_rtx)
6331 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6335 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6336 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6337 if (GET_CODE (operands[2]) == CONST_INT
6338 && (INTVAL (operands[2]) == 128
6339 || (INTVAL (operands[2]) < 0
6340 && INTVAL (operands[2]) != -128)))
6342 operands[2] = GEN_INT (-INTVAL (operands[2]));
6344 return "sub{l}\t{%2, %k0|%k0, %2}";
6346 return "sub{b}\t{%2, %0|%0, %2}";
6349 return "add{l}\t{%k2, %k0|%k0, %k2}";
6351 return "add{b}\t{%2, %0|%0, %2}";
6355 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6356 (const_string "incdec")
6357 (const_string "alu")))
6358 (set_attr "mode" "QI,QI,SI")])
6360 (define_insn "*addqi_1_slp"
6361 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6362 (plus:QI (match_dup 0)
6363 (match_operand:QI 1 "general_operand" "qn,qnm")))
6364 (clobber (reg:CC FLAGS_REG))]
6365 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6366 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6368 switch (get_attr_type (insn))
6371 if (operands[1] == const1_rtx)
6372 return "inc{b}\t%0";
6373 else if (operands[1] == constm1_rtx)
6374 return "dec{b}\t%0";
6378 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6379 if (GET_CODE (operands[1]) == CONST_INT
6380 && INTVAL (operands[1]) < 0)
6382 operands[1] = GEN_INT (-INTVAL (operands[1]));
6383 return "sub{b}\t{%1, %0|%0, %1}";
6385 return "add{b}\t{%1, %0|%0, %1}";
6389 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6390 (const_string "incdec")
6391 (const_string "alu1")))
6392 (set_attr "mode" "QI")])
6394 (define_insn "*addqi_2"
6397 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6398 (match_operand:QI 2 "general_operand" "qmni,qni"))
6400 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6401 (plus:QI (match_dup 1) (match_dup 2)))]
6402 "ix86_match_ccmode (insn, CCGOCmode)
6403 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6405 switch (get_attr_type (insn))
6408 if (operands[2] == const1_rtx)
6409 return "inc{b}\t%0";
6410 else if (operands[2] == constm1_rtx
6411 || (GET_CODE (operands[2]) == CONST_INT
6412 && INTVAL (operands[2]) == 255))
6413 return "dec{b}\t%0";
6417 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6418 if (GET_CODE (operands[2]) == CONST_INT
6419 && INTVAL (operands[2]) < 0)
6421 operands[2] = GEN_INT (-INTVAL (operands[2]));
6422 return "sub{b}\t{%2, %0|%0, %2}";
6424 return "add{b}\t{%2, %0|%0, %2}";
6428 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6429 (const_string "incdec")
6430 (const_string "alu")))
6431 (set_attr "mode" "QI")])
6433 (define_insn "*addqi_3"
6435 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6436 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6437 (clobber (match_scratch:QI 0 "=q"))]
6438 "ix86_match_ccmode (insn, CCZmode)
6439 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6441 switch (get_attr_type (insn))
6444 if (operands[2] == const1_rtx)
6445 return "inc{b}\t%0";
6446 else if (operands[2] == constm1_rtx
6447 || (GET_CODE (operands[2]) == CONST_INT
6448 && INTVAL (operands[2]) == 255))
6449 return "dec{b}\t%0";
6453 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6454 if (GET_CODE (operands[2]) == CONST_INT
6455 && INTVAL (operands[2]) < 0)
6457 operands[2] = GEN_INT (-INTVAL (operands[2]));
6458 return "sub{b}\t{%2, %0|%0, %2}";
6460 return "add{b}\t{%2, %0|%0, %2}";
6464 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465 (const_string "incdec")
6466 (const_string "alu")))
6467 (set_attr "mode" "QI")])
6469 ; See comments above addsi_3_imm for details.
6470 (define_insn "*addqi_4"
6472 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6473 (match_operand:QI 2 "const_int_operand" "n")))
6474 (clobber (match_scratch:QI 0 "=qm"))]
6475 "ix86_match_ccmode (insn, CCGCmode)
6476 && (INTVAL (operands[2]) & 0xff) != 0x80"
6478 switch (get_attr_type (insn))
6481 if (operands[2] == constm1_rtx
6482 || (GET_CODE (operands[2]) == CONST_INT
6483 && INTVAL (operands[2]) == 255))
6484 return "inc{b}\t%0";
6485 else if (operands[2] == const1_rtx)
6486 return "dec{b}\t%0";
6491 if (! rtx_equal_p (operands[0], operands[1]))
6493 if (INTVAL (operands[2]) < 0)
6495 operands[2] = GEN_INT (-INTVAL (operands[2]));
6496 return "add{b}\t{%2, %0|%0, %2}";
6498 return "sub{b}\t{%2, %0|%0, %2}";
6502 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6503 (const_string "incdec")
6504 (const_string "alu")))
6505 (set_attr "mode" "QI")])
6508 (define_insn "*addqi_5"
6511 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6512 (match_operand:QI 2 "general_operand" "qmni"))
6514 (clobber (match_scratch:QI 0 "=q"))]
6515 "ix86_match_ccmode (insn, CCGOCmode)
6516 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6518 switch (get_attr_type (insn))
6521 if (operands[2] == const1_rtx)
6522 return "inc{b}\t%0";
6523 else if (operands[2] == constm1_rtx
6524 || (GET_CODE (operands[2]) == CONST_INT
6525 && INTVAL (operands[2]) == 255))
6526 return "dec{b}\t%0";
6530 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6531 if (GET_CODE (operands[2]) == CONST_INT
6532 && INTVAL (operands[2]) < 0)
6534 operands[2] = GEN_INT (-INTVAL (operands[2]));
6535 return "sub{b}\t{%2, %0|%0, %2}";
6537 return "add{b}\t{%2, %0|%0, %2}";
6541 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6542 (const_string "incdec")
6543 (const_string "alu")))
6544 (set_attr "mode" "QI")])
6547 (define_insn "addqi_ext_1"
6548 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6553 (match_operand 1 "ext_register_operand" "0")
6556 (match_operand:QI 2 "general_operand" "Qmn")))
6557 (clobber (reg:CC FLAGS_REG))]
6560 switch (get_attr_type (insn))
6563 if (operands[2] == const1_rtx)
6564 return "inc{b}\t%h0";
6565 else if (operands[2] == constm1_rtx
6566 || (GET_CODE (operands[2]) == CONST_INT
6567 && INTVAL (operands[2]) == 255))
6568 return "dec{b}\t%h0";
6572 return "add{b}\t{%2, %h0|%h0, %2}";
6576 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6577 (const_string "incdec")
6578 (const_string "alu")))
6579 (set_attr "mode" "QI")])
6581 (define_insn "*addqi_ext_1_rex64"
6582 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6587 (match_operand 1 "ext_register_operand" "0")
6590 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6591 (clobber (reg:CC FLAGS_REG))]
6594 switch (get_attr_type (insn))
6597 if (operands[2] == const1_rtx)
6598 return "inc{b}\t%h0";
6599 else if (operands[2] == constm1_rtx
6600 || (GET_CODE (operands[2]) == CONST_INT
6601 && INTVAL (operands[2]) == 255))
6602 return "dec{b}\t%h0";
6606 return "add{b}\t{%2, %h0|%h0, %2}";
6610 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6611 (const_string "incdec")
6612 (const_string "alu")))
6613 (set_attr "mode" "QI")])
6615 (define_insn "*addqi_ext_2"
6616 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6621 (match_operand 1 "ext_register_operand" "%0")
6625 (match_operand 2 "ext_register_operand" "Q")
6628 (clobber (reg:CC FLAGS_REG))]
6630 "add{b}\t{%h2, %h0|%h0, %h2}"
6631 [(set_attr "type" "alu")
6632 (set_attr "mode" "QI")])
6634 ;; The patterns that match these are at the end of this file.
6636 (define_expand "addxf3"
6637 [(set (match_operand:XF 0 "register_operand" "")
6638 (plus:XF (match_operand:XF 1 "register_operand" "")
6639 (match_operand:XF 2 "register_operand" "")))]
6643 (define_expand "adddf3"
6644 [(set (match_operand:DF 0 "register_operand" "")
6645 (plus:DF (match_operand:DF 1 "register_operand" "")
6646 (match_operand:DF 2 "nonimmediate_operand" "")))]
6647 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6650 (define_expand "addsf3"
6651 [(set (match_operand:SF 0 "register_operand" "")
6652 (plus:SF (match_operand:SF 1 "register_operand" "")
6653 (match_operand:SF 2 "nonimmediate_operand" "")))]
6654 "TARGET_80387 || TARGET_SSE_MATH"
6657 ;; Subtract instructions
6659 ;; %%% splits for subsidi3
6661 (define_expand "subdi3"
6662 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6663 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6664 (match_operand:DI 2 "x86_64_general_operand" "")))
6665 (clobber (reg:CC FLAGS_REG))])]
6667 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6669 (define_insn "*subdi3_1"
6670 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6671 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6672 (match_operand:DI 2 "general_operand" "roiF,riF")))
6673 (clobber (reg:CC FLAGS_REG))]
6674 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6678 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6679 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6680 (match_operand:DI 2 "general_operand" "")))
6681 (clobber (reg:CC FLAGS_REG))]
6682 "!TARGET_64BIT && reload_completed"
6683 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6684 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6685 (parallel [(set (match_dup 3)
6686 (minus:SI (match_dup 4)
6687 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6689 (clobber (reg:CC FLAGS_REG))])]
6690 "split_di (operands+0, 1, operands+0, operands+3);
6691 split_di (operands+1, 1, operands+1, operands+4);
6692 split_di (operands+2, 1, operands+2, operands+5);")
6694 (define_insn "subdi3_carry_rex64"
6695 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6696 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6697 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6698 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6699 (clobber (reg:CC FLAGS_REG))]
6700 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6701 "sbb{q}\t{%2, %0|%0, %2}"
6702 [(set_attr "type" "alu")
6703 (set_attr "pent_pair" "pu")
6704 (set_attr "mode" "DI")])
6706 (define_insn "*subdi_1_rex64"
6707 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6708 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6709 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6710 (clobber (reg:CC FLAGS_REG))]
6711 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6712 "sub{q}\t{%2, %0|%0, %2}"
6713 [(set_attr "type" "alu")
6714 (set_attr "mode" "DI")])
6716 (define_insn "*subdi_2_rex64"
6719 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6720 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6722 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6723 (minus:DI (match_dup 1) (match_dup 2)))]
6724 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6725 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6726 "sub{q}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "alu")
6728 (set_attr "mode" "DI")])
6730 (define_insn "*subdi_3_rex63"
6732 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6733 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6734 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6735 (minus:DI (match_dup 1) (match_dup 2)))]
6736 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6737 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6738 "sub{q}\t{%2, %0|%0, %2}"
6739 [(set_attr "type" "alu")
6740 (set_attr "mode" "DI")])
6742 (define_insn "subqi3_carry"
6743 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6744 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6745 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6746 (match_operand:QI 2 "general_operand" "qi,qm"))))
6747 (clobber (reg:CC FLAGS_REG))]
6748 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6749 "sbb{b}\t{%2, %0|%0, %2}"
6750 [(set_attr "type" "alu")
6751 (set_attr "pent_pair" "pu")
6752 (set_attr "mode" "QI")])
6754 (define_insn "subhi3_carry"
6755 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6756 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6757 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6758 (match_operand:HI 2 "general_operand" "ri,rm"))))
6759 (clobber (reg:CC FLAGS_REG))]
6760 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6761 "sbb{w}\t{%2, %0|%0, %2}"
6762 [(set_attr "type" "alu")
6763 (set_attr "pent_pair" "pu")
6764 (set_attr "mode" "HI")])
6766 (define_insn "subsi3_carry"
6767 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6768 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6769 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6770 (match_operand:SI 2 "general_operand" "ri,rm"))))
6771 (clobber (reg:CC FLAGS_REG))]
6772 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6773 "sbb{l}\t{%2, %0|%0, %2}"
6774 [(set_attr "type" "alu")
6775 (set_attr "pent_pair" "pu")
6776 (set_attr "mode" "SI")])
6778 (define_insn "subsi3_carry_zext"
6779 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6781 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6782 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6783 (match_operand:SI 2 "general_operand" "ri,rm")))))
6784 (clobber (reg:CC FLAGS_REG))]
6785 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6786 "sbb{l}\t{%2, %k0|%k0, %2}"
6787 [(set_attr "type" "alu")
6788 (set_attr "pent_pair" "pu")
6789 (set_attr "mode" "SI")])
6791 (define_expand "subsi3"
6792 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6793 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6794 (match_operand:SI 2 "general_operand" "")))
6795 (clobber (reg:CC FLAGS_REG))])]
6797 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6799 (define_insn "*subsi_1"
6800 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6801 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6802 (match_operand:SI 2 "general_operand" "ri,rm")))
6803 (clobber (reg:CC FLAGS_REG))]
6804 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6805 "sub{l}\t{%2, %0|%0, %2}"
6806 [(set_attr "type" "alu")
6807 (set_attr "mode" "SI")])
6809 (define_insn "*subsi_1_zext"
6810 [(set (match_operand:DI 0 "register_operand" "=r")
6812 (minus:SI (match_operand:SI 1 "register_operand" "0")
6813 (match_operand:SI 2 "general_operand" "rim"))))
6814 (clobber (reg:CC FLAGS_REG))]
6815 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6816 "sub{l}\t{%2, %k0|%k0, %2}"
6817 [(set_attr "type" "alu")
6818 (set_attr "mode" "SI")])
6820 (define_insn "*subsi_2"
6823 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6824 (match_operand:SI 2 "general_operand" "ri,rm"))
6826 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6827 (minus:SI (match_dup 1) (match_dup 2)))]
6828 "ix86_match_ccmode (insn, CCGOCmode)
6829 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6830 "sub{l}\t{%2, %0|%0, %2}"
6831 [(set_attr "type" "alu")
6832 (set_attr "mode" "SI")])
6834 (define_insn "*subsi_2_zext"
6837 (minus:SI (match_operand:SI 1 "register_operand" "0")
6838 (match_operand:SI 2 "general_operand" "rim"))
6840 (set (match_operand:DI 0 "register_operand" "=r")
6842 (minus:SI (match_dup 1)
6844 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6845 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6846 "sub{l}\t{%2, %k0|%k0, %2}"
6847 [(set_attr "type" "alu")
6848 (set_attr "mode" "SI")])
6850 (define_insn "*subsi_3"
6852 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6853 (match_operand:SI 2 "general_operand" "ri,rm")))
6854 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6855 (minus:SI (match_dup 1) (match_dup 2)))]
6856 "ix86_match_ccmode (insn, CCmode)
6857 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6858 "sub{l}\t{%2, %0|%0, %2}"
6859 [(set_attr "type" "alu")
6860 (set_attr "mode" "SI")])
6862 (define_insn "*subsi_3_zext"
6864 (compare (match_operand:SI 1 "register_operand" "0")
6865 (match_operand:SI 2 "general_operand" "rim")))
6866 (set (match_operand:DI 0 "register_operand" "=r")
6868 (minus:SI (match_dup 1)
6870 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6871 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6872 "sub{q}\t{%2, %0|%0, %2}"
6873 [(set_attr "type" "alu")
6874 (set_attr "mode" "DI")])
6876 (define_expand "subhi3"
6877 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6878 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6879 (match_operand:HI 2 "general_operand" "")))
6880 (clobber (reg:CC FLAGS_REG))])]
6881 "TARGET_HIMODE_MATH"
6882 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6884 (define_insn "*subhi_1"
6885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6886 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6887 (match_operand:HI 2 "general_operand" "ri,rm")))
6888 (clobber (reg:CC FLAGS_REG))]
6889 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6890 "sub{w}\t{%2, %0|%0, %2}"
6891 [(set_attr "type" "alu")
6892 (set_attr "mode" "HI")])
6894 (define_insn "*subhi_2"
6897 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6898 (match_operand:HI 2 "general_operand" "ri,rm"))
6900 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6901 (minus:HI (match_dup 1) (match_dup 2)))]
6902 "ix86_match_ccmode (insn, CCGOCmode)
6903 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6904 "sub{w}\t{%2, %0|%0, %2}"
6905 [(set_attr "type" "alu")
6906 (set_attr "mode" "HI")])
6908 (define_insn "*subhi_3"
6910 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6911 (match_operand:HI 2 "general_operand" "ri,rm")))
6912 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6913 (minus:HI (match_dup 1) (match_dup 2)))]
6914 "ix86_match_ccmode (insn, CCmode)
6915 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6916 "sub{w}\t{%2, %0|%0, %2}"
6917 [(set_attr "type" "alu")
6918 (set_attr "mode" "HI")])
6920 (define_expand "subqi3"
6921 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6922 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6923 (match_operand:QI 2 "general_operand" "")))
6924 (clobber (reg:CC FLAGS_REG))])]
6925 "TARGET_QIMODE_MATH"
6926 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6928 (define_insn "*subqi_1"
6929 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6930 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6931 (match_operand:QI 2 "general_operand" "qn,qmn")))
6932 (clobber (reg:CC FLAGS_REG))]
6933 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6934 "sub{b}\t{%2, %0|%0, %2}"
6935 [(set_attr "type" "alu")
6936 (set_attr "mode" "QI")])
6938 (define_insn "*subqi_1_slp"
6939 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6940 (minus:QI (match_dup 0)
6941 (match_operand:QI 1 "general_operand" "qn,qmn")))
6942 (clobber (reg:CC FLAGS_REG))]
6943 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6944 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6945 "sub{b}\t{%1, %0|%0, %1}"
6946 [(set_attr "type" "alu1")
6947 (set_attr "mode" "QI")])
6949 (define_insn "*subqi_2"
6952 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6953 (match_operand:QI 2 "general_operand" "qi,qm"))
6955 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6956 (minus:HI (match_dup 1) (match_dup 2)))]
6957 "ix86_match_ccmode (insn, CCGOCmode)
6958 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6959 "sub{b}\t{%2, %0|%0, %2}"
6960 [(set_attr "type" "alu")
6961 (set_attr "mode" "QI")])
6963 (define_insn "*subqi_3"
6965 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6966 (match_operand:QI 2 "general_operand" "qi,qm")))
6967 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6968 (minus:HI (match_dup 1) (match_dup 2)))]
6969 "ix86_match_ccmode (insn, CCmode)
6970 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6971 "sub{b}\t{%2, %0|%0, %2}"
6972 [(set_attr "type" "alu")
6973 (set_attr "mode" "QI")])
6975 ;; The patterns that match these are at the end of this file.
6977 (define_expand "subxf3"
6978 [(set (match_operand:XF 0 "register_operand" "")
6979 (minus:XF (match_operand:XF 1 "register_operand" "")
6980 (match_operand:XF 2 "register_operand" "")))]
6984 (define_expand "subdf3"
6985 [(set (match_operand:DF 0 "register_operand" "")
6986 (minus:DF (match_operand:DF 1 "register_operand" "")
6987 (match_operand:DF 2 "nonimmediate_operand" "")))]
6988 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6991 (define_expand "subsf3"
6992 [(set (match_operand:SF 0 "register_operand" "")
6993 (minus:SF (match_operand:SF 1 "register_operand" "")
6994 (match_operand:SF 2 "nonimmediate_operand" "")))]
6995 "TARGET_80387 || TARGET_SSE_MATH"
6998 ;; Multiply instructions
7000 (define_expand "muldi3"
7001 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7002 (mult:DI (match_operand:DI 1 "register_operand" "")
7003 (match_operand:DI 2 "x86_64_general_operand" "")))
7004 (clobber (reg:CC FLAGS_REG))])]
7008 (define_insn "*muldi3_1_rex64"
7009 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7010 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7011 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7012 (clobber (reg:CC FLAGS_REG))]
7014 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7016 imul{q}\t{%2, %1, %0|%0, %1, %2}
7017 imul{q}\t{%2, %1, %0|%0, %1, %2}
7018 imul{q}\t{%2, %0|%0, %2}"
7019 [(set_attr "type" "imul")
7020 (set_attr "prefix_0f" "0,0,1")
7021 (set (attr "athlon_decode")
7022 (cond [(eq_attr "cpu" "athlon")
7023 (const_string "vector")
7024 (eq_attr "alternative" "1")
7025 (const_string "vector")
7026 (and (eq_attr "alternative" "2")
7027 (match_operand 1 "memory_operand" ""))
7028 (const_string "vector")]
7029 (const_string "direct")))
7030 (set_attr "mode" "DI")])
7032 (define_expand "mulsi3"
7033 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7034 (mult:SI (match_operand:SI 1 "register_operand" "")
7035 (match_operand:SI 2 "general_operand" "")))
7036 (clobber (reg:CC FLAGS_REG))])]
7040 (define_insn "*mulsi3_1"
7041 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7042 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7043 (match_operand:SI 2 "general_operand" "K,i,mr")))
7044 (clobber (reg:CC FLAGS_REG))]
7045 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7047 imul{l}\t{%2, %1, %0|%0, %1, %2}
7048 imul{l}\t{%2, %1, %0|%0, %1, %2}
7049 imul{l}\t{%2, %0|%0, %2}"
7050 [(set_attr "type" "imul")
7051 (set_attr "prefix_0f" "0,0,1")
7052 (set (attr "athlon_decode")
7053 (cond [(eq_attr "cpu" "athlon")
7054 (const_string "vector")
7055 (eq_attr "alternative" "1")
7056 (const_string "vector")
7057 (and (eq_attr "alternative" "2")
7058 (match_operand 1 "memory_operand" ""))
7059 (const_string "vector")]
7060 (const_string "direct")))
7061 (set_attr "mode" "SI")])
7063 (define_insn "*mulsi3_1_zext"
7064 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7066 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7067 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7068 (clobber (reg:CC FLAGS_REG))]
7070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7072 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7073 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7074 imul{l}\t{%2, %k0|%k0, %2}"
7075 [(set_attr "type" "imul")
7076 (set_attr "prefix_0f" "0,0,1")
7077 (set (attr "athlon_decode")
7078 (cond [(eq_attr "cpu" "athlon")
7079 (const_string "vector")
7080 (eq_attr "alternative" "1")
7081 (const_string "vector")
7082 (and (eq_attr "alternative" "2")
7083 (match_operand 1 "memory_operand" ""))
7084 (const_string "vector")]
7085 (const_string "direct")))
7086 (set_attr "mode" "SI")])
7088 (define_expand "mulhi3"
7089 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7090 (mult:HI (match_operand:HI 1 "register_operand" "")
7091 (match_operand:HI 2 "general_operand" "")))
7092 (clobber (reg:CC FLAGS_REG))])]
7093 "TARGET_HIMODE_MATH"
7096 (define_insn "*mulhi3_1"
7097 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7098 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7099 (match_operand:HI 2 "general_operand" "K,i,mr")))
7100 (clobber (reg:CC FLAGS_REG))]
7101 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7103 imul{w}\t{%2, %1, %0|%0, %1, %2}
7104 imul{w}\t{%2, %1, %0|%0, %1, %2}
7105 imul{w}\t{%2, %0|%0, %2}"
7106 [(set_attr "type" "imul")
7107 (set_attr "prefix_0f" "0,0,1")
7108 (set (attr "athlon_decode")
7109 (cond [(eq_attr "cpu" "athlon")
7110 (const_string "vector")
7111 (eq_attr "alternative" "1,2")
7112 (const_string "vector")]
7113 (const_string "direct")))
7114 (set_attr "mode" "HI")])
7116 (define_expand "mulqi3"
7117 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7118 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7119 (match_operand:QI 2 "register_operand" "")))
7120 (clobber (reg:CC FLAGS_REG))])]
7121 "TARGET_QIMODE_MATH"
7124 (define_insn "*mulqi3_1"
7125 [(set (match_operand:QI 0 "register_operand" "=a")
7126 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7127 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7128 (clobber (reg:CC FLAGS_REG))]
7130 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7132 [(set_attr "type" "imul")
7133 (set_attr "length_immediate" "0")
7134 (set (attr "athlon_decode")
7135 (if_then_else (eq_attr "cpu" "athlon")
7136 (const_string "vector")
7137 (const_string "direct")))
7138 (set_attr "mode" "QI")])
7140 (define_expand "umulqihi3"
7141 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7142 (mult:HI (zero_extend:HI
7143 (match_operand:QI 1 "nonimmediate_operand" ""))
7145 (match_operand:QI 2 "register_operand" ""))))
7146 (clobber (reg:CC FLAGS_REG))])]
7147 "TARGET_QIMODE_MATH"
7150 (define_insn "*umulqihi3_1"
7151 [(set (match_operand:HI 0 "register_operand" "=a")
7152 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7153 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7154 (clobber (reg:CC FLAGS_REG))]
7156 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7158 [(set_attr "type" "imul")
7159 (set_attr "length_immediate" "0")
7160 (set (attr "athlon_decode")
7161 (if_then_else (eq_attr "cpu" "athlon")
7162 (const_string "vector")
7163 (const_string "direct")))
7164 (set_attr "mode" "QI")])
7166 (define_expand "mulqihi3"
7167 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7168 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7169 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7170 (clobber (reg:CC FLAGS_REG))])]
7171 "TARGET_QIMODE_MATH"
7174 (define_insn "*mulqihi3_insn"
7175 [(set (match_operand:HI 0 "register_operand" "=a")
7176 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7177 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7178 (clobber (reg:CC FLAGS_REG))]
7180 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7182 [(set_attr "type" "imul")
7183 (set_attr "length_immediate" "0")
7184 (set (attr "athlon_decode")
7185 (if_then_else (eq_attr "cpu" "athlon")
7186 (const_string "vector")
7187 (const_string "direct")))
7188 (set_attr "mode" "QI")])
7190 (define_expand "umulditi3"
7191 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7192 (mult:TI (zero_extend:TI
7193 (match_operand:DI 1 "nonimmediate_operand" ""))
7195 (match_operand:DI 2 "register_operand" ""))))
7196 (clobber (reg:CC FLAGS_REG))])]
7200 (define_insn "*umulditi3_insn"
7201 [(set (match_operand:TI 0 "register_operand" "=A")
7202 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7203 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7204 (clobber (reg:CC FLAGS_REG))]
7206 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7208 [(set_attr "type" "imul")
7209 (set_attr "length_immediate" "0")
7210 (set (attr "athlon_decode")
7211 (if_then_else (eq_attr "cpu" "athlon")
7212 (const_string "vector")
7213 (const_string "double")))
7214 (set_attr "mode" "DI")])
7216 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7217 (define_expand "umulsidi3"
7218 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7219 (mult:DI (zero_extend:DI
7220 (match_operand:SI 1 "nonimmediate_operand" ""))
7222 (match_operand:SI 2 "register_operand" ""))))
7223 (clobber (reg:CC FLAGS_REG))])]
7227 (define_insn "*umulsidi3_insn"
7228 [(set (match_operand:DI 0 "register_operand" "=A")
7229 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7230 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7231 (clobber (reg:CC FLAGS_REG))]
7233 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7235 [(set_attr "type" "imul")
7236 (set_attr "length_immediate" "0")
7237 (set (attr "athlon_decode")
7238 (if_then_else (eq_attr "cpu" "athlon")
7239 (const_string "vector")
7240 (const_string "double")))
7241 (set_attr "mode" "SI")])
7243 (define_expand "mulditi3"
7244 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7245 (mult:TI (sign_extend:TI
7246 (match_operand:DI 1 "nonimmediate_operand" ""))
7248 (match_operand:DI 2 "register_operand" ""))))
7249 (clobber (reg:CC FLAGS_REG))])]
7253 (define_insn "*mulditi3_insn"
7254 [(set (match_operand:TI 0 "register_operand" "=A")
7255 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7256 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7257 (clobber (reg:CC FLAGS_REG))]
7259 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7261 [(set_attr "type" "imul")
7262 (set_attr "length_immediate" "0")
7263 (set (attr "athlon_decode")
7264 (if_then_else (eq_attr "cpu" "athlon")
7265 (const_string "vector")
7266 (const_string "double")))
7267 (set_attr "mode" "DI")])
7269 (define_expand "mulsidi3"
7270 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7271 (mult:DI (sign_extend:DI
7272 (match_operand:SI 1 "nonimmediate_operand" ""))
7274 (match_operand:SI 2 "register_operand" ""))))
7275 (clobber (reg:CC FLAGS_REG))])]
7279 (define_insn "*mulsidi3_insn"
7280 [(set (match_operand:DI 0 "register_operand" "=A")
7281 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7282 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7283 (clobber (reg:CC FLAGS_REG))]
7285 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7287 [(set_attr "type" "imul")
7288 (set_attr "length_immediate" "0")
7289 (set (attr "athlon_decode")
7290 (if_then_else (eq_attr "cpu" "athlon")
7291 (const_string "vector")
7292 (const_string "double")))
7293 (set_attr "mode" "SI")])
7295 (define_expand "umuldi3_highpart"
7296 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7299 (mult:TI (zero_extend:TI
7300 (match_operand:DI 1 "nonimmediate_operand" ""))
7302 (match_operand:DI 2 "register_operand" "")))
7304 (clobber (match_scratch:DI 3 ""))
7305 (clobber (reg:CC FLAGS_REG))])]
7309 (define_insn "*umuldi3_highpart_rex64"
7310 [(set (match_operand:DI 0 "register_operand" "=d")
7313 (mult:TI (zero_extend:TI
7314 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7316 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7318 (clobber (match_scratch:DI 3 "=1"))
7319 (clobber (reg:CC FLAGS_REG))]
7321 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7323 [(set_attr "type" "imul")
7324 (set_attr "length_immediate" "0")
7325 (set (attr "athlon_decode")
7326 (if_then_else (eq_attr "cpu" "athlon")
7327 (const_string "vector")
7328 (const_string "double")))
7329 (set_attr "mode" "DI")])
7331 (define_expand "umulsi3_highpart"
7332 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7335 (mult:DI (zero_extend:DI
7336 (match_operand:SI 1 "nonimmediate_operand" ""))
7338 (match_operand:SI 2 "register_operand" "")))
7340 (clobber (match_scratch:SI 3 ""))
7341 (clobber (reg:CC FLAGS_REG))])]
7345 (define_insn "*umulsi3_highpart_insn"
7346 [(set (match_operand:SI 0 "register_operand" "=d")
7349 (mult:DI (zero_extend:DI
7350 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7352 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7354 (clobber (match_scratch:SI 3 "=1"))
7355 (clobber (reg:CC FLAGS_REG))]
7356 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7358 [(set_attr "type" "imul")
7359 (set_attr "length_immediate" "0")
7360 (set (attr "athlon_decode")
7361 (if_then_else (eq_attr "cpu" "athlon")
7362 (const_string "vector")
7363 (const_string "double")))
7364 (set_attr "mode" "SI")])
7366 (define_insn "*umulsi3_highpart_zext"
7367 [(set (match_operand:DI 0 "register_operand" "=d")
7368 (zero_extend:DI (truncate:SI
7370 (mult:DI (zero_extend:DI
7371 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7373 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7375 (clobber (match_scratch:SI 3 "=1"))
7376 (clobber (reg:CC FLAGS_REG))]
7378 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7380 [(set_attr "type" "imul")
7381 (set_attr "length_immediate" "0")
7382 (set (attr "athlon_decode")
7383 (if_then_else (eq_attr "cpu" "athlon")
7384 (const_string "vector")
7385 (const_string "double")))
7386 (set_attr "mode" "SI")])
7388 (define_expand "smuldi3_highpart"
7389 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7392 (mult:TI (sign_extend:TI
7393 (match_operand:DI 1 "nonimmediate_operand" ""))
7395 (match_operand:DI 2 "register_operand" "")))
7397 (clobber (match_scratch:DI 3 ""))
7398 (clobber (reg:CC FLAGS_REG))])]
7402 (define_insn "*smuldi3_highpart_rex64"
7403 [(set (match_operand:DI 0 "register_operand" "=d")
7406 (mult:TI (sign_extend:TI
7407 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7409 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7411 (clobber (match_scratch:DI 3 "=1"))
7412 (clobber (reg:CC FLAGS_REG))]
7414 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7416 [(set_attr "type" "imul")
7417 (set (attr "athlon_decode")
7418 (if_then_else (eq_attr "cpu" "athlon")
7419 (const_string "vector")
7420 (const_string "double")))
7421 (set_attr "mode" "DI")])
7423 (define_expand "smulsi3_highpart"
7424 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7427 (mult:DI (sign_extend:DI
7428 (match_operand:SI 1 "nonimmediate_operand" ""))
7430 (match_operand:SI 2 "register_operand" "")))
7432 (clobber (match_scratch:SI 3 ""))
7433 (clobber (reg:CC FLAGS_REG))])]
7437 (define_insn "*smulsi3_highpart_insn"
7438 [(set (match_operand:SI 0 "register_operand" "=d")
7441 (mult:DI (sign_extend:DI
7442 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7444 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7446 (clobber (match_scratch:SI 3 "=1"))
7447 (clobber (reg:CC FLAGS_REG))]
7448 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7450 [(set_attr "type" "imul")
7451 (set (attr "athlon_decode")
7452 (if_then_else (eq_attr "cpu" "athlon")
7453 (const_string "vector")
7454 (const_string "double")))
7455 (set_attr "mode" "SI")])
7457 (define_insn "*smulsi3_highpart_zext"
7458 [(set (match_operand:DI 0 "register_operand" "=d")
7459 (zero_extend:DI (truncate:SI
7461 (mult:DI (sign_extend:DI
7462 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7464 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7466 (clobber (match_scratch:SI 3 "=1"))
7467 (clobber (reg:CC FLAGS_REG))]
7469 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7471 [(set_attr "type" "imul")
7472 (set (attr "athlon_decode")
7473 (if_then_else (eq_attr "cpu" "athlon")
7474 (const_string "vector")
7475 (const_string "double")))
7476 (set_attr "mode" "SI")])
7478 ;; The patterns that match these are at the end of this file.
7480 (define_expand "mulxf3"
7481 [(set (match_operand:XF 0 "register_operand" "")
7482 (mult:XF (match_operand:XF 1 "register_operand" "")
7483 (match_operand:XF 2 "register_operand" "")))]
7487 (define_expand "muldf3"
7488 [(set (match_operand:DF 0 "register_operand" "")
7489 (mult:DF (match_operand:DF 1 "register_operand" "")
7490 (match_operand:DF 2 "nonimmediate_operand" "")))]
7491 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7494 (define_expand "mulsf3"
7495 [(set (match_operand:SF 0 "register_operand" "")
7496 (mult:SF (match_operand:SF 1 "register_operand" "")
7497 (match_operand:SF 2 "nonimmediate_operand" "")))]
7498 "TARGET_80387 || TARGET_SSE_MATH"
7501 ;; Divide instructions
7503 (define_insn "divqi3"
7504 [(set (match_operand:QI 0 "register_operand" "=a")
7505 (div:QI (match_operand:HI 1 "register_operand" "0")
7506 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7507 (clobber (reg:CC FLAGS_REG))]
7508 "TARGET_QIMODE_MATH"
7510 [(set_attr "type" "idiv")
7511 (set_attr "mode" "QI")])
7513 (define_insn "udivqi3"
7514 [(set (match_operand:QI 0 "register_operand" "=a")
7515 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7516 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7517 (clobber (reg:CC FLAGS_REG))]
7518 "TARGET_QIMODE_MATH"
7520 [(set_attr "type" "idiv")
7521 (set_attr "mode" "QI")])
7523 ;; The patterns that match these are at the end of this file.
7525 (define_expand "divxf3"
7526 [(set (match_operand:XF 0 "register_operand" "")
7527 (div:XF (match_operand:XF 1 "register_operand" "")
7528 (match_operand:XF 2 "register_operand" "")))]
7532 (define_expand "divdf3"
7533 [(set (match_operand:DF 0 "register_operand" "")
7534 (div:DF (match_operand:DF 1 "register_operand" "")
7535 (match_operand:DF 2 "nonimmediate_operand" "")))]
7536 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7539 (define_expand "divsf3"
7540 [(set (match_operand:SF 0 "register_operand" "")
7541 (div:SF (match_operand:SF 1 "register_operand" "")
7542 (match_operand:SF 2 "nonimmediate_operand" "")))]
7543 "TARGET_80387 || TARGET_SSE_MATH"
7546 ;; Remainder instructions.
7548 (define_expand "divmoddi4"
7549 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7550 (div:DI (match_operand:DI 1 "register_operand" "")
7551 (match_operand:DI 2 "nonimmediate_operand" "")))
7552 (set (match_operand:DI 3 "register_operand" "")
7553 (mod:DI (match_dup 1) (match_dup 2)))
7554 (clobber (reg:CC FLAGS_REG))])]
7558 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7559 ;; Penalize eax case slightly because it results in worse scheduling
7561 (define_insn "*divmoddi4_nocltd_rex64"
7562 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7563 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7564 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7565 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7566 (mod:DI (match_dup 2) (match_dup 3)))
7567 (clobber (reg:CC FLAGS_REG))]
7568 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7570 [(set_attr "type" "multi")])
7572 (define_insn "*divmoddi4_cltd_rex64"
7573 [(set (match_operand:DI 0 "register_operand" "=a")
7574 (div:DI (match_operand:DI 2 "register_operand" "a")
7575 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7576 (set (match_operand:DI 1 "register_operand" "=&d")
7577 (mod:DI (match_dup 2) (match_dup 3)))
7578 (clobber (reg:CC FLAGS_REG))]
7579 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7581 [(set_attr "type" "multi")])
7583 (define_insn "*divmoddi_noext_rex64"
7584 [(set (match_operand:DI 0 "register_operand" "=a")
7585 (div:DI (match_operand:DI 1 "register_operand" "0")
7586 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7587 (set (match_operand:DI 3 "register_operand" "=d")
7588 (mod:DI (match_dup 1) (match_dup 2)))
7589 (use (match_operand:DI 4 "register_operand" "3"))
7590 (clobber (reg:CC FLAGS_REG))]
7593 [(set_attr "type" "idiv")
7594 (set_attr "mode" "DI")])
7597 [(set (match_operand:DI 0 "register_operand" "")
7598 (div:DI (match_operand:DI 1 "register_operand" "")
7599 (match_operand:DI 2 "nonimmediate_operand" "")))
7600 (set (match_operand:DI 3 "register_operand" "")
7601 (mod:DI (match_dup 1) (match_dup 2)))
7602 (clobber (reg:CC FLAGS_REG))]
7603 "TARGET_64BIT && reload_completed"
7604 [(parallel [(set (match_dup 3)
7605 (ashiftrt:DI (match_dup 4) (const_int 63)))
7606 (clobber (reg:CC FLAGS_REG))])
7607 (parallel [(set (match_dup 0)
7608 (div:DI (reg:DI 0) (match_dup 2)))
7610 (mod:DI (reg:DI 0) (match_dup 2)))
7612 (clobber (reg:CC FLAGS_REG))])]
7614 /* Avoid use of cltd in favor of a mov+shift. */
7615 if (!TARGET_USE_CLTD && !optimize_size)
7617 if (true_regnum (operands[1]))
7618 emit_move_insn (operands[0], operands[1]);
7620 emit_move_insn (operands[3], operands[1]);
7621 operands[4] = operands[3];
7625 if (true_regnum (operands[1]))
7627 operands[4] = operands[1];
7632 (define_expand "divmodsi4"
7633 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7634 (div:SI (match_operand:SI 1 "register_operand" "")
7635 (match_operand:SI 2 "nonimmediate_operand" "")))
7636 (set (match_operand:SI 3 "register_operand" "")
7637 (mod:SI (match_dup 1) (match_dup 2)))
7638 (clobber (reg:CC FLAGS_REG))])]
7642 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7643 ;; Penalize eax case slightly because it results in worse scheduling
7645 (define_insn "*divmodsi4_nocltd"
7646 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7647 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7648 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7649 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7650 (mod:SI (match_dup 2) (match_dup 3)))
7651 (clobber (reg:CC FLAGS_REG))]
7652 "!optimize_size && !TARGET_USE_CLTD"
7654 [(set_attr "type" "multi")])
7656 (define_insn "*divmodsi4_cltd"
7657 [(set (match_operand:SI 0 "register_operand" "=a")
7658 (div:SI (match_operand:SI 2 "register_operand" "a")
7659 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7660 (set (match_operand:SI 1 "register_operand" "=&d")
7661 (mod:SI (match_dup 2) (match_dup 3)))
7662 (clobber (reg:CC FLAGS_REG))]
7663 "optimize_size || TARGET_USE_CLTD"
7665 [(set_attr "type" "multi")])
7667 (define_insn "*divmodsi_noext"
7668 [(set (match_operand:SI 0 "register_operand" "=a")
7669 (div:SI (match_operand:SI 1 "register_operand" "0")
7670 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7671 (set (match_operand:SI 3 "register_operand" "=d")
7672 (mod:SI (match_dup 1) (match_dup 2)))
7673 (use (match_operand:SI 4 "register_operand" "3"))
7674 (clobber (reg:CC FLAGS_REG))]
7677 [(set_attr "type" "idiv")
7678 (set_attr "mode" "SI")])
7681 [(set (match_operand:SI 0 "register_operand" "")
7682 (div:SI (match_operand:SI 1 "register_operand" "")
7683 (match_operand:SI 2 "nonimmediate_operand" "")))
7684 (set (match_operand:SI 3 "register_operand" "")
7685 (mod:SI (match_dup 1) (match_dup 2)))
7686 (clobber (reg:CC FLAGS_REG))]
7688 [(parallel [(set (match_dup 3)
7689 (ashiftrt:SI (match_dup 4) (const_int 31)))
7690 (clobber (reg:CC FLAGS_REG))])
7691 (parallel [(set (match_dup 0)
7692 (div:SI (reg:SI 0) (match_dup 2)))
7694 (mod:SI (reg:SI 0) (match_dup 2)))
7696 (clobber (reg:CC FLAGS_REG))])]
7698 /* Avoid use of cltd in favor of a mov+shift. */
7699 if (!TARGET_USE_CLTD && !optimize_size)
7701 if (true_regnum (operands[1]))
7702 emit_move_insn (operands[0], operands[1]);
7704 emit_move_insn (operands[3], operands[1]);
7705 operands[4] = operands[3];
7709 if (true_regnum (operands[1]))
7711 operands[4] = operands[1];
7715 (define_insn "divmodhi4"
7716 [(set (match_operand:HI 0 "register_operand" "=a")
7717 (div:HI (match_operand:HI 1 "register_operand" "0")
7718 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7719 (set (match_operand:HI 3 "register_operand" "=&d")
7720 (mod:HI (match_dup 1) (match_dup 2)))
7721 (clobber (reg:CC FLAGS_REG))]
7722 "TARGET_HIMODE_MATH"
7724 [(set_attr "type" "multi")
7725 (set_attr "length_immediate" "0")
7726 (set_attr "mode" "SI")])
7728 (define_insn "udivmoddi4"
7729 [(set (match_operand:DI 0 "register_operand" "=a")
7730 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7731 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7732 (set (match_operand:DI 3 "register_operand" "=&d")
7733 (umod:DI (match_dup 1) (match_dup 2)))
7734 (clobber (reg:CC FLAGS_REG))]
7736 "xor{q}\t%3, %3\;div{q}\t%2"
7737 [(set_attr "type" "multi")
7738 (set_attr "length_immediate" "0")
7739 (set_attr "mode" "DI")])
7741 (define_insn "*udivmoddi4_noext"
7742 [(set (match_operand:DI 0 "register_operand" "=a")
7743 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7744 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7745 (set (match_operand:DI 3 "register_operand" "=d")
7746 (umod:DI (match_dup 1) (match_dup 2)))
7748 (clobber (reg:CC FLAGS_REG))]
7751 [(set_attr "type" "idiv")
7752 (set_attr "mode" "DI")])
7755 [(set (match_operand:DI 0 "register_operand" "")
7756 (udiv:DI (match_operand:DI 1 "register_operand" "")
7757 (match_operand:DI 2 "nonimmediate_operand" "")))
7758 (set (match_operand:DI 3 "register_operand" "")
7759 (umod:DI (match_dup 1) (match_dup 2)))
7760 (clobber (reg:CC FLAGS_REG))]
7761 "TARGET_64BIT && reload_completed"
7762 [(set (match_dup 3) (const_int 0))
7763 (parallel [(set (match_dup 0)
7764 (udiv:DI (match_dup 1) (match_dup 2)))
7766 (umod:DI (match_dup 1) (match_dup 2)))
7768 (clobber (reg:CC FLAGS_REG))])]
7771 (define_insn "udivmodsi4"
7772 [(set (match_operand:SI 0 "register_operand" "=a")
7773 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7774 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7775 (set (match_operand:SI 3 "register_operand" "=&d")
7776 (umod:SI (match_dup 1) (match_dup 2)))
7777 (clobber (reg:CC FLAGS_REG))]
7779 "xor{l}\t%3, %3\;div{l}\t%2"
7780 [(set_attr "type" "multi")
7781 (set_attr "length_immediate" "0")
7782 (set_attr "mode" "SI")])
7784 (define_insn "*udivmodsi4_noext"
7785 [(set (match_operand:SI 0 "register_operand" "=a")
7786 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7787 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7788 (set (match_operand:SI 3 "register_operand" "=d")
7789 (umod:SI (match_dup 1) (match_dup 2)))
7791 (clobber (reg:CC FLAGS_REG))]
7794 [(set_attr "type" "idiv")
7795 (set_attr "mode" "SI")])
7798 [(set (match_operand:SI 0 "register_operand" "")
7799 (udiv:SI (match_operand:SI 1 "register_operand" "")
7800 (match_operand:SI 2 "nonimmediate_operand" "")))
7801 (set (match_operand:SI 3 "register_operand" "")
7802 (umod:SI (match_dup 1) (match_dup 2)))
7803 (clobber (reg:CC FLAGS_REG))]
7805 [(set (match_dup 3) (const_int 0))
7806 (parallel [(set (match_dup 0)
7807 (udiv:SI (match_dup 1) (match_dup 2)))
7809 (umod:SI (match_dup 1) (match_dup 2)))
7811 (clobber (reg:CC FLAGS_REG))])]
7814 (define_expand "udivmodhi4"
7815 [(set (match_dup 4) (const_int 0))
7816 (parallel [(set (match_operand:HI 0 "register_operand" "")
7817 (udiv:HI (match_operand:HI 1 "register_operand" "")
7818 (match_operand:HI 2 "nonimmediate_operand" "")))
7819 (set (match_operand:HI 3 "register_operand" "")
7820 (umod:HI (match_dup 1) (match_dup 2)))
7822 (clobber (reg:CC FLAGS_REG))])]
7823 "TARGET_HIMODE_MATH"
7824 "operands[4] = gen_reg_rtx (HImode);")
7826 (define_insn "*udivmodhi_noext"
7827 [(set (match_operand:HI 0 "register_operand" "=a")
7828 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7829 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7830 (set (match_operand:HI 3 "register_operand" "=d")
7831 (umod:HI (match_dup 1) (match_dup 2)))
7832 (use (match_operand:HI 4 "register_operand" "3"))
7833 (clobber (reg:CC FLAGS_REG))]
7836 [(set_attr "type" "idiv")
7837 (set_attr "mode" "HI")])
7839 ;; We cannot use div/idiv for double division, because it causes
7840 ;; "division by zero" on the overflow and that's not what we expect
7841 ;; from truncate. Because true (non truncating) double division is
7842 ;; never generated, we can't create this insn anyway.
7845 ; [(set (match_operand:SI 0 "register_operand" "=a")
7847 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7849 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7850 ; (set (match_operand:SI 3 "register_operand" "=d")
7852 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7853 ; (clobber (reg:CC FLAGS_REG))]
7855 ; "div{l}\t{%2, %0|%0, %2}"
7856 ; [(set_attr "type" "idiv")])
7858 ;;- Logical AND instructions
7860 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7861 ;; Note that this excludes ah.
7863 (define_insn "*testdi_1_rex64"
7866 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7867 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7869 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7870 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7872 test{l}\t{%k1, %k0|%k0, %k1}
7873 test{l}\t{%k1, %k0|%k0, %k1}
7874 test{q}\t{%1, %0|%0, %1}
7875 test{q}\t{%1, %0|%0, %1}
7876 test{q}\t{%1, %0|%0, %1}"
7877 [(set_attr "type" "test")
7878 (set_attr "modrm" "0,1,0,1,1")
7879 (set_attr "mode" "SI,SI,DI,DI,DI")
7880 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7882 (define_insn "testsi_1"
7885 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7886 (match_operand:SI 1 "general_operand" "in,in,rin"))
7888 "ix86_match_ccmode (insn, CCNOmode)
7889 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7890 "test{l}\t{%1, %0|%0, %1}"
7891 [(set_attr "type" "test")
7892 (set_attr "modrm" "0,1,1")
7893 (set_attr "mode" "SI")
7894 (set_attr "pent_pair" "uv,np,uv")])
7896 (define_expand "testsi_ccno_1"
7897 [(set (reg:CCNO FLAGS_REG)
7899 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7900 (match_operand:SI 1 "nonmemory_operand" ""))
7905 (define_insn "*testhi_1"
7907 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7908 (match_operand:HI 1 "general_operand" "n,n,rn"))
7910 "ix86_match_ccmode (insn, CCNOmode)
7911 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7912 "test{w}\t{%1, %0|%0, %1}"
7913 [(set_attr "type" "test")
7914 (set_attr "modrm" "0,1,1")
7915 (set_attr "mode" "HI")
7916 (set_attr "pent_pair" "uv,np,uv")])
7918 (define_expand "testqi_ccz_1"
7919 [(set (reg:CCZ FLAGS_REG)
7920 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7921 (match_operand:QI 1 "nonmemory_operand" ""))
7926 (define_insn "*testqi_1"
7927 [(set (reg FLAGS_REG)
7928 (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7929 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7931 "ix86_match_ccmode (insn, CCNOmode)
7932 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7934 if (which_alternative == 3)
7936 if (GET_CODE (operands[1]) == CONST_INT
7937 && (INTVAL (operands[1]) & 0xffffff00))
7938 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7939 return "test{l}\t{%1, %k0|%k0, %1}";
7941 return "test{b}\t{%1, %0|%0, %1}";
7943 [(set_attr "type" "test")
7944 (set_attr "modrm" "0,1,1,1")
7945 (set_attr "mode" "QI,QI,QI,SI")
7946 (set_attr "pent_pair" "uv,np,uv,np")])
7948 (define_expand "testqi_ext_ccno_0"
7949 [(set (reg:CCNO FLAGS_REG)
7953 (match_operand 0 "ext_register_operand" "")
7956 (match_operand 1 "const_int_operand" ""))
7961 (define_insn "*testqi_ext_0"
7966 (match_operand 0 "ext_register_operand" "Q")
7969 (match_operand 1 "const_int_operand" "n"))
7971 "ix86_match_ccmode (insn, CCNOmode)"
7972 "test{b}\t{%1, %h0|%h0, %1}"
7973 [(set_attr "type" "test")
7974 (set_attr "mode" "QI")
7975 (set_attr "length_immediate" "1")
7976 (set_attr "pent_pair" "np")])
7978 (define_insn "*testqi_ext_1"
7983 (match_operand 0 "ext_register_operand" "Q")
7987 (match_operand:QI 1 "general_operand" "Qm")))
7989 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7990 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7991 "test{b}\t{%1, %h0|%h0, %1}"
7992 [(set_attr "type" "test")
7993 (set_attr "mode" "QI")])
7995 (define_insn "*testqi_ext_1_rex64"
8000 (match_operand 0 "ext_register_operand" "Q")
8004 (match_operand:QI 1 "register_operand" "Q")))
8006 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8007 "test{b}\t{%1, %h0|%h0, %1}"
8008 [(set_attr "type" "test")
8009 (set_attr "mode" "QI")])
8011 (define_insn "*testqi_ext_2"
8016 (match_operand 0 "ext_register_operand" "Q")
8020 (match_operand 1 "ext_register_operand" "Q")
8024 "ix86_match_ccmode (insn, CCNOmode)"
8025 "test{b}\t{%h1, %h0|%h0, %h1}"
8026 [(set_attr "type" "test")
8027 (set_attr "mode" "QI")])
8029 ;; Combine likes to form bit extractions for some tests. Humor it.
8030 (define_insn "*testqi_ext_3"
8032 (compare (zero_extract:SI
8033 (match_operand 0 "nonimmediate_operand" "rm")
8034 (match_operand:SI 1 "const_int_operand" "")
8035 (match_operand:SI 2 "const_int_operand" ""))
8037 "ix86_match_ccmode (insn, CCNOmode)
8038 && (GET_MODE (operands[0]) == SImode
8039 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8040 || GET_MODE (operands[0]) == HImode
8041 || GET_MODE (operands[0]) == QImode)"
8044 (define_insn "*testqi_ext_3_rex64"
8046 (compare (zero_extract:DI
8047 (match_operand 0 "nonimmediate_operand" "rm")
8048 (match_operand:DI 1 "const_int_operand" "")
8049 (match_operand:DI 2 "const_int_operand" ""))
8052 && ix86_match_ccmode (insn, CCNOmode)
8053 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
8054 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8055 /* Ensure that resulting mask is zero or sign extended operand. */
8056 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8057 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8058 && INTVAL (operands[1]) > 32))
8059 && (GET_MODE (operands[0]) == SImode
8060 || GET_MODE (operands[0]) == DImode
8061 || GET_MODE (operands[0]) == HImode
8062 || GET_MODE (operands[0]) == QImode)"
8067 (compare (zero_extract
8068 (match_operand 0 "nonimmediate_operand" "")
8069 (match_operand 1 "const_int_operand" "")
8070 (match_operand 2 "const_int_operand" ""))
8072 "ix86_match_ccmode (insn, CCNOmode)"
8073 [(set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
8075 HOST_WIDE_INT len = INTVAL (operands[1]);
8076 HOST_WIDE_INT pos = INTVAL (operands[2]);
8078 enum machine_mode mode, submode;
8080 mode = GET_MODE (operands[0]);
8081 if (GET_CODE (operands[0]) == MEM)
8083 /* ??? Combine likes to put non-volatile mem extractions in QImode
8084 no matter the size of the test. So find a mode that works. */
8085 if (! MEM_VOLATILE_P (operands[0]))
8087 mode = smallest_mode_for_size (pos + len, MODE_INT);
8088 operands[0] = adjust_address (operands[0], mode, 0);
8091 else if (GET_CODE (operands[0]) == SUBREG
8092 && (submode = GET_MODE (SUBREG_REG (operands[0])),
8093 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8094 && pos + len <= GET_MODE_BITSIZE (submode))
8096 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8098 operands[0] = SUBREG_REG (operands[0]);
8100 else if (mode == HImode && pos + len <= 8)
8102 /* Small HImode tests can be converted to QImode. */
8104 operands[0] = gen_lowpart (QImode, operands[0]);
8107 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8108 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8110 operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8113 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8114 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8115 ;; this is relatively important trick.
8116 ;; Do the conversion only post-reload to avoid limiting of the register class
8121 (and (match_operand 0 "register_operand" "")
8122 (match_operand 1 "const_int_operand" ""))
8125 && QI_REG_P (operands[0])
8126 && ((ix86_match_ccmode (insn, CCZmode)
8127 && !(INTVAL (operands[1]) & ~(255 << 8)))
8128 || (ix86_match_ccmode (insn, CCNOmode)
8129 && !(INTVAL (operands[1]) & ~(127 << 8))))
8130 && GET_MODE (operands[0]) != QImode"
8131 [(set (reg:CCNO FLAGS_REG)
8133 (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8136 "operands[0] = gen_lowpart (SImode, operands[0]);
8137 operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8142 (and (match_operand 0 "nonimmediate_operand" "")
8143 (match_operand 1 "const_int_operand" ""))
8146 && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8147 && ((ix86_match_ccmode (insn, CCZmode)
8148 && !(INTVAL (operands[1]) & ~255))
8149 || (ix86_match_ccmode (insn, CCNOmode)
8150 && !(INTVAL (operands[1]) & ~127)))
8151 && GET_MODE (operands[0]) != QImode"
8152 [(set (reg:CCNO FLAGS_REG)
8154 (and:QI (match_dup 0)
8157 "operands[0] = gen_lowpart (QImode, operands[0]);
8158 operands[1] = gen_lowpart (QImode, operands[1]);")
8161 ;; %%% This used to optimize known byte-wide and operations to memory,
8162 ;; and sometimes to QImode registers. If this is considered useful,
8163 ;; it should be done with splitters.
8165 (define_expand "anddi3"
8166 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8167 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8168 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8169 (clobber (reg:CC FLAGS_REG))]
8171 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8173 (define_insn "*anddi_1_rex64"
8174 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8175 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8176 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8177 (clobber (reg:CC FLAGS_REG))]
8178 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8180 switch (get_attr_type (insn))
8184 enum machine_mode mode;
8186 if (GET_CODE (operands[2]) != CONST_INT)
8188 if (INTVAL (operands[2]) == 0xff)
8190 else if (INTVAL (operands[2]) == 0xffff)
8195 operands[1] = gen_lowpart (mode, operands[1]);
8197 return "movz{bq|x}\t{%1,%0|%0, %1}";
8199 return "movz{wq|x}\t{%1,%0|%0, %1}";
8203 if (! rtx_equal_p (operands[0], operands[1]))
8205 if (get_attr_mode (insn) == MODE_SI)
8206 return "and{l}\t{%k2, %k0|%k0, %k2}";
8208 return "and{q}\t{%2, %0|%0, %2}";
8211 [(set_attr "type" "alu,alu,alu,imovx")
8212 (set_attr "length_immediate" "*,*,*,0")
8213 (set_attr "mode" "SI,DI,DI,DI")])
8215 (define_insn "*anddi_2"
8217 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8218 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8220 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8221 (and:DI (match_dup 1) (match_dup 2)))]
8222 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8223 && ix86_binary_operator_ok (AND, DImode, operands)"
8225 and{l}\t{%k2, %k0|%k0, %k2}
8226 and{q}\t{%2, %0|%0, %2}
8227 and{q}\t{%2, %0|%0, %2}"
8228 [(set_attr "type" "alu")
8229 (set_attr "mode" "SI,DI,DI")])
8231 (define_expand "andsi3"
8232 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8233 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8234 (match_operand:SI 2 "general_operand" "")))
8235 (clobber (reg:CC FLAGS_REG))]
8237 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8239 (define_insn "*andsi_1"
8240 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8241 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8242 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8243 (clobber (reg:CC FLAGS_REG))]
8244 "ix86_binary_operator_ok (AND, SImode, operands)"
8246 switch (get_attr_type (insn))
8250 enum machine_mode mode;
8252 if (GET_CODE (operands[2]) != CONST_INT)
8254 if (INTVAL (operands[2]) == 0xff)
8256 else if (INTVAL (operands[2]) == 0xffff)
8261 operands[1] = gen_lowpart (mode, operands[1]);
8263 return "movz{bl|x}\t{%1,%0|%0, %1}";
8265 return "movz{wl|x}\t{%1,%0|%0, %1}";
8269 if (! rtx_equal_p (operands[0], operands[1]))
8271 return "and{l}\t{%2, %0|%0, %2}";
8274 [(set_attr "type" "alu,alu,imovx")
8275 (set_attr "length_immediate" "*,*,0")
8276 (set_attr "mode" "SI")])
8279 [(set (match_operand 0 "register_operand" "")
8281 (const_int -65536)))
8282 (clobber (reg:CC FLAGS_REG))]
8283 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8284 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8285 "operands[1] = gen_lowpart (HImode, operands[0]);")
8288 [(set (match_operand 0 "ext_register_operand" "")
8291 (clobber (reg:CC FLAGS_REG))]
8292 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8293 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8294 "operands[1] = gen_lowpart (QImode, operands[0]);")
8297 [(set (match_operand 0 "ext_register_operand" "")
8299 (const_int -65281)))
8300 (clobber (reg:CC FLAGS_REG))]
8301 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8302 [(parallel [(set (zero_extract:SI (match_dup 0)
8306 (zero_extract:SI (match_dup 0)
8309 (zero_extract:SI (match_dup 0)
8312 (clobber (reg:CC FLAGS_REG))])]
8313 "operands[0] = gen_lowpart (SImode, operands[0]);")
8315 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8316 (define_insn "*andsi_1_zext"
8317 [(set (match_operand:DI 0 "register_operand" "=r")
8319 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8320 (match_operand:SI 2 "general_operand" "rim"))))
8321 (clobber (reg:CC FLAGS_REG))]
8322 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8323 "and{l}\t{%2, %k0|%k0, %2}"
8324 [(set_attr "type" "alu")
8325 (set_attr "mode" "SI")])
8327 (define_insn "*andsi_2"
8329 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8330 (match_operand:SI 2 "general_operand" "rim,ri"))
8332 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8333 (and:SI (match_dup 1) (match_dup 2)))]
8334 "ix86_match_ccmode (insn, CCNOmode)
8335 && ix86_binary_operator_ok (AND, SImode, operands)"
8336 "and{l}\t{%2, %0|%0, %2}"
8337 [(set_attr "type" "alu")
8338 (set_attr "mode" "SI")])
8340 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8341 (define_insn "*andsi_2_zext"
8343 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8344 (match_operand:SI 2 "general_operand" "rim"))
8346 (set (match_operand:DI 0 "register_operand" "=r")
8347 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8348 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8349 && ix86_binary_operator_ok (AND, SImode, operands)"
8350 "and{l}\t{%2, %k0|%k0, %2}"
8351 [(set_attr "type" "alu")
8352 (set_attr "mode" "SI")])
8354 (define_expand "andhi3"
8355 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8356 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8357 (match_operand:HI 2 "general_operand" "")))
8358 (clobber (reg:CC FLAGS_REG))]
8359 "TARGET_HIMODE_MATH"
8360 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8362 (define_insn "*andhi_1"
8363 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8364 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8365 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8366 (clobber (reg:CC FLAGS_REG))]
8367 "ix86_binary_operator_ok (AND, HImode, operands)"
8369 switch (get_attr_type (insn))
8372 if (GET_CODE (operands[2]) != CONST_INT)
8374 if (INTVAL (operands[2]) == 0xff)
8375 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8379 if (! rtx_equal_p (operands[0], operands[1]))
8382 return "and{w}\t{%2, %0|%0, %2}";
8385 [(set_attr "type" "alu,alu,imovx")
8386 (set_attr "length_immediate" "*,*,0")
8387 (set_attr "mode" "HI,HI,SI")])
8389 (define_insn "*andhi_2"
8391 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8392 (match_operand:HI 2 "general_operand" "rim,ri"))
8394 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8395 (and:HI (match_dup 1) (match_dup 2)))]
8396 "ix86_match_ccmode (insn, CCNOmode)
8397 && ix86_binary_operator_ok (AND, HImode, operands)"
8398 "and{w}\t{%2, %0|%0, %2}"
8399 [(set_attr "type" "alu")
8400 (set_attr "mode" "HI")])
8402 (define_expand "andqi3"
8403 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8404 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8405 (match_operand:QI 2 "general_operand" "")))
8406 (clobber (reg:CC FLAGS_REG))]
8407 "TARGET_QIMODE_MATH"
8408 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8410 ;; %%% Potential partial reg stall on alternative 2. What to do?
8411 (define_insn "*andqi_1"
8412 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8413 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8414 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8415 (clobber (reg:CC FLAGS_REG))]
8416 "ix86_binary_operator_ok (AND, QImode, operands)"
8418 and{b}\t{%2, %0|%0, %2}
8419 and{b}\t{%2, %0|%0, %2}
8420 and{l}\t{%k2, %k0|%k0, %k2}"
8421 [(set_attr "type" "alu")
8422 (set_attr "mode" "QI,QI,SI")])
8424 (define_insn "*andqi_1_slp"
8425 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8426 (and:QI (match_dup 0)
8427 (match_operand:QI 1 "general_operand" "qi,qmi")))
8428 (clobber (reg:CC FLAGS_REG))]
8429 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8430 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8431 "and{b}\t{%1, %0|%0, %1}"
8432 [(set_attr "type" "alu1")
8433 (set_attr "mode" "QI")])
8435 (define_insn "*andqi_2"
8438 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8439 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8441 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8442 (and:QI (match_dup 1) (match_dup 2)))]
8443 "ix86_match_ccmode (insn, CCNOmode)
8444 && ix86_binary_operator_ok (AND, QImode, operands)"
8446 if (which_alternative == 2)
8448 if (GET_CODE (operands[2]) == CONST_INT
8449 && (INTVAL (operands[2]) & 0xffffff00))
8450 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8451 return "and{l}\t{%2, %k0|%k0, %2}";
8453 return "and{b}\t{%2, %0|%0, %2}";
8455 [(set_attr "type" "alu")
8456 (set_attr "mode" "QI,QI,SI")])
8458 (define_insn "*andqi_2_slp"
8461 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8462 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8464 (set (strict_low_part (match_dup 0))
8465 (and:QI (match_dup 0) (match_dup 1)))]
8466 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8467 && ix86_match_ccmode (insn, CCNOmode)
8468 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8469 "and{b}\t{%1, %0|%0, %1}"
8470 [(set_attr "type" "alu1")
8471 (set_attr "mode" "QI")])
8473 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8474 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8475 ;; for a QImode operand, which of course failed.
8477 (define_insn "andqi_ext_0"
8478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8483 (match_operand 1 "ext_register_operand" "0")
8486 (match_operand 2 "const_int_operand" "n")))
8487 (clobber (reg:CC FLAGS_REG))]
8489 "and{b}\t{%2, %h0|%h0, %2}"
8490 [(set_attr "type" "alu")
8491 (set_attr "length_immediate" "1")
8492 (set_attr "mode" "QI")])
8494 ;; Generated by peephole translating test to and. This shows up
8495 ;; often in fp comparisons.
8497 (define_insn "*andqi_ext_0_cc"
8502 (match_operand 1 "ext_register_operand" "0")
8505 (match_operand 2 "const_int_operand" "n"))
8507 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8516 "ix86_match_ccmode (insn, CCNOmode)"
8517 "and{b}\t{%2, %h0|%h0, %2}"
8518 [(set_attr "type" "alu")
8519 (set_attr "length_immediate" "1")
8520 (set_attr "mode" "QI")])
8522 (define_insn "*andqi_ext_1"
8523 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8528 (match_operand 1 "ext_register_operand" "0")
8532 (match_operand:QI 2 "general_operand" "Qm"))))
8533 (clobber (reg:CC FLAGS_REG))]
8535 "and{b}\t{%2, %h0|%h0, %2}"
8536 [(set_attr "type" "alu")
8537 (set_attr "length_immediate" "0")
8538 (set_attr "mode" "QI")])
8540 (define_insn "*andqi_ext_1_rex64"
8541 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8546 (match_operand 1 "ext_register_operand" "0")
8550 (match_operand 2 "ext_register_operand" "Q"))))
8551 (clobber (reg:CC FLAGS_REG))]
8553 "and{b}\t{%2, %h0|%h0, %2}"
8554 [(set_attr "type" "alu")
8555 (set_attr "length_immediate" "0")
8556 (set_attr "mode" "QI")])
8558 (define_insn "*andqi_ext_2"
8559 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8564 (match_operand 1 "ext_register_operand" "%0")
8568 (match_operand 2 "ext_register_operand" "Q")
8571 (clobber (reg:CC FLAGS_REG))]
8573 "and{b}\t{%h2, %h0|%h0, %h2}"
8574 [(set_attr "type" "alu")
8575 (set_attr "length_immediate" "0")
8576 (set_attr "mode" "QI")])
8578 ;; Convert wide AND instructions with immediate operand to shorter QImode
8579 ;; equivalents when possible.
8580 ;; Don't do the splitting with memory operands, since it introduces risk
8581 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8582 ;; for size, but that can (should?) be handled by generic code instead.
8584 [(set (match_operand 0 "register_operand" "")
8585 (and (match_operand 1 "register_operand" "")
8586 (match_operand 2 "const_int_operand" "")))
8587 (clobber (reg:CC FLAGS_REG))]
8589 && QI_REG_P (operands[0])
8590 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8591 && !(~INTVAL (operands[2]) & ~(255 << 8))
8592 && GET_MODE (operands[0]) != QImode"
8593 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8594 (and:SI (zero_extract:SI (match_dup 1)
8595 (const_int 8) (const_int 8))
8597 (clobber (reg:CC FLAGS_REG))])]
8598 "operands[0] = gen_lowpart (SImode, operands[0]);
8599 operands[1] = gen_lowpart (SImode, operands[1]);
8600 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8602 ;; Since AND can be encoded with sign extended immediate, this is only
8603 ;; profitable when 7th bit is not set.
8605 [(set (match_operand 0 "register_operand" "")
8606 (and (match_operand 1 "general_operand" "")
8607 (match_operand 2 "const_int_operand" "")))
8608 (clobber (reg:CC FLAGS_REG))]
8610 && ANY_QI_REG_P (operands[0])
8611 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8612 && !(~INTVAL (operands[2]) & ~255)
8613 && !(INTVAL (operands[2]) & 128)
8614 && GET_MODE (operands[0]) != QImode"
8615 [(parallel [(set (strict_low_part (match_dup 0))
8616 (and:QI (match_dup 1)
8618 (clobber (reg:CC FLAGS_REG))])]
8619 "operands[0] = gen_lowpart (QImode, operands[0]);
8620 operands[1] = gen_lowpart (QImode, operands[1]);
8621 operands[2] = gen_lowpart (QImode, operands[2]);")
8623 ;; Logical inclusive OR instructions
8625 ;; %%% This used to optimize known byte-wide and operations to memory.
8626 ;; If this is considered useful, it should be done with splitters.
8628 (define_expand "iordi3"
8629 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8630 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8631 (match_operand:DI 2 "x86_64_general_operand" "")))
8632 (clobber (reg:CC FLAGS_REG))]
8634 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8636 (define_insn "*iordi_1_rex64"
8637 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8638 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8639 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8640 (clobber (reg:CC FLAGS_REG))]
8642 && ix86_binary_operator_ok (IOR, DImode, operands)"
8643 "or{q}\t{%2, %0|%0, %2}"
8644 [(set_attr "type" "alu")
8645 (set_attr "mode" "DI")])
8647 (define_insn "*iordi_2_rex64"
8649 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8650 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8652 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8653 (ior:DI (match_dup 1) (match_dup 2)))]
8655 && ix86_match_ccmode (insn, CCNOmode)
8656 && ix86_binary_operator_ok (IOR, DImode, operands)"
8657 "or{q}\t{%2, %0|%0, %2}"
8658 [(set_attr "type" "alu")
8659 (set_attr "mode" "DI")])
8661 (define_insn "*iordi_3_rex64"
8663 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8664 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8666 (clobber (match_scratch:DI 0 "=r"))]
8668 && ix86_match_ccmode (insn, CCNOmode)
8669 && ix86_binary_operator_ok (IOR, DImode, operands)"
8670 "or{q}\t{%2, %0|%0, %2}"
8671 [(set_attr "type" "alu")
8672 (set_attr "mode" "DI")])
8675 (define_expand "iorsi3"
8676 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8677 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8678 (match_operand:SI 2 "general_operand" "")))
8679 (clobber (reg:CC FLAGS_REG))]
8681 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8683 (define_insn "*iorsi_1"
8684 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8685 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8686 (match_operand:SI 2 "general_operand" "ri,rmi")))
8687 (clobber (reg:CC FLAGS_REG))]
8688 "ix86_binary_operator_ok (IOR, SImode, operands)"
8689 "or{l}\t{%2, %0|%0, %2}"
8690 [(set_attr "type" "alu")
8691 (set_attr "mode" "SI")])
8693 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8694 (define_insn "*iorsi_1_zext"
8695 [(set (match_operand:DI 0 "register_operand" "=rm")
8697 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8698 (match_operand:SI 2 "general_operand" "rim"))))
8699 (clobber (reg:CC FLAGS_REG))]
8700 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8701 "or{l}\t{%2, %k0|%k0, %2}"
8702 [(set_attr "type" "alu")
8703 (set_attr "mode" "SI")])
8705 (define_insn "*iorsi_1_zext_imm"
8706 [(set (match_operand:DI 0 "register_operand" "=rm")
8707 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8708 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8709 (clobber (reg:CC FLAGS_REG))]
8711 "or{l}\t{%2, %k0|%k0, %2}"
8712 [(set_attr "type" "alu")
8713 (set_attr "mode" "SI")])
8715 (define_insn "*iorsi_2"
8717 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8718 (match_operand:SI 2 "general_operand" "rim,ri"))
8720 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8721 (ior:SI (match_dup 1) (match_dup 2)))]
8722 "ix86_match_ccmode (insn, CCNOmode)
8723 && ix86_binary_operator_ok (IOR, SImode, operands)"
8724 "or{l}\t{%2, %0|%0, %2}"
8725 [(set_attr "type" "alu")
8726 (set_attr "mode" "SI")])
8728 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8729 ;; ??? Special case for immediate operand is missing - it is tricky.
8730 (define_insn "*iorsi_2_zext"
8732 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8733 (match_operand:SI 2 "general_operand" "rim"))
8735 (set (match_operand:DI 0 "register_operand" "=r")
8736 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8737 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8738 && ix86_binary_operator_ok (IOR, SImode, operands)"
8739 "or{l}\t{%2, %k0|%k0, %2}"
8740 [(set_attr "type" "alu")
8741 (set_attr "mode" "SI")])
8743 (define_insn "*iorsi_2_zext_imm"
8745 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8746 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8748 (set (match_operand:DI 0 "register_operand" "=r")
8749 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8750 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8751 && ix86_binary_operator_ok (IOR, SImode, operands)"
8752 "or{l}\t{%2, %k0|%k0, %2}"
8753 [(set_attr "type" "alu")
8754 (set_attr "mode" "SI")])
8756 (define_insn "*iorsi_3"
8758 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8759 (match_operand:SI 2 "general_operand" "rim"))
8761 (clobber (match_scratch:SI 0 "=r"))]
8762 "ix86_match_ccmode (insn, CCNOmode)
8763 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8764 "or{l}\t{%2, %0|%0, %2}"
8765 [(set_attr "type" "alu")
8766 (set_attr "mode" "SI")])
8768 (define_expand "iorhi3"
8769 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8770 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8771 (match_operand:HI 2 "general_operand" "")))
8772 (clobber (reg:CC FLAGS_REG))]
8773 "TARGET_HIMODE_MATH"
8774 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8776 (define_insn "*iorhi_1"
8777 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8778 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8779 (match_operand:HI 2 "general_operand" "rmi,ri")))
8780 (clobber (reg:CC FLAGS_REG))]
8781 "ix86_binary_operator_ok (IOR, HImode, operands)"
8782 "or{w}\t{%2, %0|%0, %2}"
8783 [(set_attr "type" "alu")
8784 (set_attr "mode" "HI")])
8786 (define_insn "*iorhi_2"
8788 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8789 (match_operand:HI 2 "general_operand" "rim,ri"))
8791 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8792 (ior:HI (match_dup 1) (match_dup 2)))]
8793 "ix86_match_ccmode (insn, CCNOmode)
8794 && ix86_binary_operator_ok (IOR, HImode, operands)"
8795 "or{w}\t{%2, %0|%0, %2}"
8796 [(set_attr "type" "alu")
8797 (set_attr "mode" "HI")])
8799 (define_insn "*iorhi_3"
8801 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8802 (match_operand:HI 2 "general_operand" "rim"))
8804 (clobber (match_scratch:HI 0 "=r"))]
8805 "ix86_match_ccmode (insn, CCNOmode)
8806 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8807 "or{w}\t{%2, %0|%0, %2}"
8808 [(set_attr "type" "alu")
8809 (set_attr "mode" "HI")])
8811 (define_expand "iorqi3"
8812 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8813 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8814 (match_operand:QI 2 "general_operand" "")))
8815 (clobber (reg:CC FLAGS_REG))]
8816 "TARGET_QIMODE_MATH"
8817 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8819 ;; %%% Potential partial reg stall on alternative 2. What to do?
8820 (define_insn "*iorqi_1"
8821 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8822 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8823 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8824 (clobber (reg:CC FLAGS_REG))]
8825 "ix86_binary_operator_ok (IOR, QImode, operands)"
8827 or{b}\t{%2, %0|%0, %2}
8828 or{b}\t{%2, %0|%0, %2}
8829 or{l}\t{%k2, %k0|%k0, %k2}"
8830 [(set_attr "type" "alu")
8831 (set_attr "mode" "QI,QI,SI")])
8833 (define_insn "*iorqi_1_slp"
8834 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8835 (ior:QI (match_dup 0)
8836 (match_operand:QI 1 "general_operand" "qmi,qi")))
8837 (clobber (reg:CC FLAGS_REG))]
8838 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8839 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8840 "or{b}\t{%1, %0|%0, %1}"
8841 [(set_attr "type" "alu1")
8842 (set_attr "mode" "QI")])
8844 (define_insn "*iorqi_2"
8846 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8847 (match_operand:QI 2 "general_operand" "qim,qi"))
8849 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8850 (ior:QI (match_dup 1) (match_dup 2)))]
8851 "ix86_match_ccmode (insn, CCNOmode)
8852 && ix86_binary_operator_ok (IOR, QImode, operands)"
8853 "or{b}\t{%2, %0|%0, %2}"
8854 [(set_attr "type" "alu")
8855 (set_attr "mode" "QI")])
8857 (define_insn "*iorqi_2_slp"
8859 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8860 (match_operand:QI 1 "general_operand" "qim,qi"))
8862 (set (strict_low_part (match_dup 0))
8863 (ior:QI (match_dup 0) (match_dup 1)))]
8864 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8865 && ix86_match_ccmode (insn, CCNOmode)
8866 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8867 "or{b}\t{%1, %0|%0, %1}"
8868 [(set_attr "type" "alu1")
8869 (set_attr "mode" "QI")])
8871 (define_insn "*iorqi_3"
8873 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8874 (match_operand:QI 2 "general_operand" "qim"))
8876 (clobber (match_scratch:QI 0 "=q"))]
8877 "ix86_match_ccmode (insn, CCNOmode)
8878 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8879 "or{b}\t{%2, %0|%0, %2}"
8880 [(set_attr "type" "alu")
8881 (set_attr "mode" "QI")])
8883 (define_insn "iorqi_ext_0"
8884 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8889 (match_operand 1 "ext_register_operand" "0")
8892 (match_operand 2 "const_int_operand" "n")))
8893 (clobber (reg:CC FLAGS_REG))]
8894 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8895 "or{b}\t{%2, %h0|%h0, %2}"
8896 [(set_attr "type" "alu")
8897 (set_attr "length_immediate" "1")
8898 (set_attr "mode" "QI")])
8900 (define_insn "*iorqi_ext_1"
8901 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8906 (match_operand 1 "ext_register_operand" "0")
8910 (match_operand:QI 2 "general_operand" "Qm"))))
8911 (clobber (reg:CC FLAGS_REG))]
8913 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8914 "or{b}\t{%2, %h0|%h0, %2}"
8915 [(set_attr "type" "alu")
8916 (set_attr "length_immediate" "0")
8917 (set_attr "mode" "QI")])
8919 (define_insn "*iorqi_ext_1_rex64"
8920 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8925 (match_operand 1 "ext_register_operand" "0")
8929 (match_operand 2 "ext_register_operand" "Q"))))
8930 (clobber (reg:CC FLAGS_REG))]
8932 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8933 "or{b}\t{%2, %h0|%h0, %2}"
8934 [(set_attr "type" "alu")
8935 (set_attr "length_immediate" "0")
8936 (set_attr "mode" "QI")])
8938 (define_insn "*iorqi_ext_2"
8939 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8943 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8946 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8949 (clobber (reg:CC FLAGS_REG))]
8950 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8951 "ior{b}\t{%h2, %h0|%h0, %h2}"
8952 [(set_attr "type" "alu")
8953 (set_attr "length_immediate" "0")
8954 (set_attr "mode" "QI")])
8957 [(set (match_operand 0 "register_operand" "")
8958 (ior (match_operand 1 "register_operand" "")
8959 (match_operand 2 "const_int_operand" "")))
8960 (clobber (reg:CC FLAGS_REG))]
8962 && QI_REG_P (operands[0])
8963 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8964 && !(INTVAL (operands[2]) & ~(255 << 8))
8965 && GET_MODE (operands[0]) != QImode"
8966 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8967 (ior:SI (zero_extract:SI (match_dup 1)
8968 (const_int 8) (const_int 8))
8970 (clobber (reg:CC FLAGS_REG))])]
8971 "operands[0] = gen_lowpart (SImode, operands[0]);
8972 operands[1] = gen_lowpart (SImode, operands[1]);
8973 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8975 ;; Since OR can be encoded with sign extended immediate, this is only
8976 ;; profitable when 7th bit is set.
8978 [(set (match_operand 0 "register_operand" "")
8979 (ior (match_operand 1 "general_operand" "")
8980 (match_operand 2 "const_int_operand" "")))
8981 (clobber (reg:CC FLAGS_REG))]
8983 && ANY_QI_REG_P (operands[0])
8984 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8985 && !(INTVAL (operands[2]) & ~255)
8986 && (INTVAL (operands[2]) & 128)
8987 && GET_MODE (operands[0]) != QImode"
8988 [(parallel [(set (strict_low_part (match_dup 0))
8989 (ior:QI (match_dup 1)
8991 (clobber (reg:CC FLAGS_REG))])]
8992 "operands[0] = gen_lowpart (QImode, operands[0]);
8993 operands[1] = gen_lowpart (QImode, operands[1]);
8994 operands[2] = gen_lowpart (QImode, operands[2]);")
8996 ;; Logical XOR instructions
8998 ;; %%% This used to optimize known byte-wide and operations to memory.
8999 ;; If this is considered useful, it should be done with splitters.
9001 (define_expand "xordi3"
9002 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9003 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9004 (match_operand:DI 2 "x86_64_general_operand" "")))
9005 (clobber (reg:CC FLAGS_REG))]
9007 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9009 (define_insn "*xordi_1_rex64"
9010 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9011 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9012 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9013 (clobber (reg:CC FLAGS_REG))]
9015 && ix86_binary_operator_ok (XOR, DImode, operands)"
9017 xor{q}\t{%2, %0|%0, %2}
9018 xor{q}\t{%2, %0|%0, %2}"
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "DI,DI")])
9022 (define_insn "*xordi_2_rex64"
9024 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9025 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9027 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9028 (xor:DI (match_dup 1) (match_dup 2)))]
9030 && ix86_match_ccmode (insn, CCNOmode)
9031 && ix86_binary_operator_ok (XOR, DImode, operands)"
9033 xor{q}\t{%2, %0|%0, %2}
9034 xor{q}\t{%2, %0|%0, %2}"
9035 [(set_attr "type" "alu")
9036 (set_attr "mode" "DI,DI")])
9038 (define_insn "*xordi_3_rex64"
9040 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9041 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9043 (clobber (match_scratch:DI 0 "=r"))]
9045 && ix86_match_ccmode (insn, CCNOmode)
9046 && ix86_binary_operator_ok (XOR, DImode, operands)"
9047 "xor{q}\t{%2, %0|%0, %2}"
9048 [(set_attr "type" "alu")
9049 (set_attr "mode" "DI")])
9051 (define_expand "xorsi3"
9052 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9053 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9054 (match_operand:SI 2 "general_operand" "")))
9055 (clobber (reg:CC FLAGS_REG))]
9057 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9059 (define_insn "*xorsi_1"
9060 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9061 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9062 (match_operand:SI 2 "general_operand" "ri,rm")))
9063 (clobber (reg:CC FLAGS_REG))]
9064 "ix86_binary_operator_ok (XOR, SImode, operands)"
9065 "xor{l}\t{%2, %0|%0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "SI")])
9069 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9070 ;; Add speccase for immediates
9071 (define_insn "*xorsi_1_zext"
9072 [(set (match_operand:DI 0 "register_operand" "=r")
9074 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9075 (match_operand:SI 2 "general_operand" "rim"))))
9076 (clobber (reg:CC FLAGS_REG))]
9077 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9078 "xor{l}\t{%2, %k0|%k0, %2}"
9079 [(set_attr "type" "alu")
9080 (set_attr "mode" "SI")])
9082 (define_insn "*xorsi_1_zext_imm"
9083 [(set (match_operand:DI 0 "register_operand" "=r")
9084 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9085 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9086 (clobber (reg:CC FLAGS_REG))]
9087 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9088 "xor{l}\t{%2, %k0|%k0, %2}"
9089 [(set_attr "type" "alu")
9090 (set_attr "mode" "SI")])
9092 (define_insn "*xorsi_2"
9094 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9095 (match_operand:SI 2 "general_operand" "rim,ri"))
9097 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9098 (xor:SI (match_dup 1) (match_dup 2)))]
9099 "ix86_match_ccmode (insn, CCNOmode)
9100 && ix86_binary_operator_ok (XOR, SImode, operands)"
9101 "xor{l}\t{%2, %0|%0, %2}"
9102 [(set_attr "type" "alu")
9103 (set_attr "mode" "SI")])
9105 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9106 ;; ??? Special case for immediate operand is missing - it is tricky.
9107 (define_insn "*xorsi_2_zext"
9109 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9110 (match_operand:SI 2 "general_operand" "rim"))
9112 (set (match_operand:DI 0 "register_operand" "=r")
9113 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9114 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9115 && ix86_binary_operator_ok (XOR, SImode, operands)"
9116 "xor{l}\t{%2, %k0|%k0, %2}"
9117 [(set_attr "type" "alu")
9118 (set_attr "mode" "SI")])
9120 (define_insn "*xorsi_2_zext_imm"
9122 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9123 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9125 (set (match_operand:DI 0 "register_operand" "=r")
9126 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9127 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9128 && ix86_binary_operator_ok (XOR, SImode, operands)"
9129 "xor{l}\t{%2, %k0|%k0, %2}"
9130 [(set_attr "type" "alu")
9131 (set_attr "mode" "SI")])
9133 (define_insn "*xorsi_3"
9135 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9136 (match_operand:SI 2 "general_operand" "rim"))
9138 (clobber (match_scratch:SI 0 "=r"))]
9139 "ix86_match_ccmode (insn, CCNOmode)
9140 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9141 "xor{l}\t{%2, %0|%0, %2}"
9142 [(set_attr "type" "alu")
9143 (set_attr "mode" "SI")])
9145 (define_expand "xorhi3"
9146 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9147 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9148 (match_operand:HI 2 "general_operand" "")))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "TARGET_HIMODE_MATH"
9151 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9153 (define_insn "*xorhi_1"
9154 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9155 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9156 (match_operand:HI 2 "general_operand" "rmi,ri")))
9157 (clobber (reg:CC FLAGS_REG))]
9158 "ix86_binary_operator_ok (XOR, HImode, operands)"
9159 "xor{w}\t{%2, %0|%0, %2}"
9160 [(set_attr "type" "alu")
9161 (set_attr "mode" "HI")])
9163 (define_insn "*xorhi_2"
9165 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9166 (match_operand:HI 2 "general_operand" "rim,ri"))
9168 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9169 (xor:HI (match_dup 1) (match_dup 2)))]
9170 "ix86_match_ccmode (insn, CCNOmode)
9171 && ix86_binary_operator_ok (XOR, HImode, operands)"
9172 "xor{w}\t{%2, %0|%0, %2}"
9173 [(set_attr "type" "alu")
9174 (set_attr "mode" "HI")])
9176 (define_insn "*xorhi_3"
9178 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9179 (match_operand:HI 2 "general_operand" "rim"))
9181 (clobber (match_scratch:HI 0 "=r"))]
9182 "ix86_match_ccmode (insn, CCNOmode)
9183 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9184 "xor{w}\t{%2, %0|%0, %2}"
9185 [(set_attr "type" "alu")
9186 (set_attr "mode" "HI")])
9188 (define_expand "xorqi3"
9189 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9190 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9191 (match_operand:QI 2 "general_operand" "")))
9192 (clobber (reg:CC FLAGS_REG))]
9193 "TARGET_QIMODE_MATH"
9194 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9196 ;; %%% Potential partial reg stall on alternative 2. What to do?
9197 (define_insn "*xorqi_1"
9198 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9199 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9200 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9201 (clobber (reg:CC FLAGS_REG))]
9202 "ix86_binary_operator_ok (XOR, QImode, operands)"
9204 xor{b}\t{%2, %0|%0, %2}
9205 xor{b}\t{%2, %0|%0, %2}
9206 xor{l}\t{%k2, %k0|%k0, %k2}"
9207 [(set_attr "type" "alu")
9208 (set_attr "mode" "QI,QI,SI")])
9210 (define_insn "*xorqi_1_slp"
9211 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9212 (xor:QI (match_dup 0)
9213 (match_operand:QI 1 "general_operand" "qi,qmi")))
9214 (clobber (reg:CC FLAGS_REG))]
9215 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9216 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9217 "xor{b}\t{%1, %0|%0, %1}"
9218 [(set_attr "type" "alu1")
9219 (set_attr "mode" "QI")])
9221 (define_insn "xorqi_ext_0"
9222 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9227 (match_operand 1 "ext_register_operand" "0")
9230 (match_operand 2 "const_int_operand" "n")))
9231 (clobber (reg:CC FLAGS_REG))]
9232 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9233 "xor{b}\t{%2, %h0|%h0, %2}"
9234 [(set_attr "type" "alu")
9235 (set_attr "length_immediate" "1")
9236 (set_attr "mode" "QI")])
9238 (define_insn "*xorqi_ext_1"
9239 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9244 (match_operand 1 "ext_register_operand" "0")
9248 (match_operand:QI 2 "general_operand" "Qm"))))
9249 (clobber (reg:CC FLAGS_REG))]
9251 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9252 "xor{b}\t{%2, %h0|%h0, %2}"
9253 [(set_attr "type" "alu")
9254 (set_attr "length_immediate" "0")
9255 (set_attr "mode" "QI")])
9257 (define_insn "*xorqi_ext_1_rex64"
9258 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9263 (match_operand 1 "ext_register_operand" "0")
9267 (match_operand 2 "ext_register_operand" "Q"))))
9268 (clobber (reg:CC FLAGS_REG))]
9270 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9271 "xor{b}\t{%2, %h0|%h0, %2}"
9272 [(set_attr "type" "alu")
9273 (set_attr "length_immediate" "0")
9274 (set_attr "mode" "QI")])
9276 (define_insn "*xorqi_ext_2"
9277 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9281 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9284 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9287 (clobber (reg:CC FLAGS_REG))]
9288 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9289 "xor{b}\t{%h2, %h0|%h0, %h2}"
9290 [(set_attr "type" "alu")
9291 (set_attr "length_immediate" "0")
9292 (set_attr "mode" "QI")])
9294 (define_insn "*xorqi_cc_1"
9297 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9298 (match_operand:QI 2 "general_operand" "qim,qi"))
9300 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9301 (xor:QI (match_dup 1) (match_dup 2)))]
9302 "ix86_match_ccmode (insn, CCNOmode)
9303 && ix86_binary_operator_ok (XOR, QImode, operands)"
9304 "xor{b}\t{%2, %0|%0, %2}"
9305 [(set_attr "type" "alu")
9306 (set_attr "mode" "QI")])
9308 (define_insn "*xorqi_2_slp"
9310 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9311 (match_operand:QI 1 "general_operand" "qim,qi"))
9313 (set (strict_low_part (match_dup 0))
9314 (xor:QI (match_dup 0) (match_dup 1)))]
9315 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9316 && ix86_match_ccmode (insn, CCNOmode)
9317 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9318 "xor{b}\t{%1, %0|%0, %1}"
9319 [(set_attr "type" "alu1")
9320 (set_attr "mode" "QI")])
9322 (define_insn "*xorqi_cc_2"
9325 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9326 (match_operand:QI 2 "general_operand" "qim"))
9328 (clobber (match_scratch:QI 0 "=q"))]
9329 "ix86_match_ccmode (insn, CCNOmode)
9330 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9331 "xor{b}\t{%2, %0|%0, %2}"
9332 [(set_attr "type" "alu")
9333 (set_attr "mode" "QI")])
9335 (define_insn "*xorqi_cc_ext_1"
9340 (match_operand 1 "ext_register_operand" "0")
9343 (match_operand:QI 2 "general_operand" "qmn"))
9345 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9349 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9351 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9352 "xor{b}\t{%2, %h0|%h0, %2}"
9353 [(set_attr "type" "alu")
9354 (set_attr "mode" "QI")])
9356 (define_insn "*xorqi_cc_ext_1_rex64"
9361 (match_operand 1 "ext_register_operand" "0")
9364 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9366 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9370 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9372 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9373 "xor{b}\t{%2, %h0|%h0, %2}"
9374 [(set_attr "type" "alu")
9375 (set_attr "mode" "QI")])
9377 (define_expand "xorqi_cc_ext_1"
9379 (set (reg:CCNO FLAGS_REG)
9383 (match_operand 1 "ext_register_operand" "")
9386 (match_operand:QI 2 "general_operand" ""))
9388 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9392 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9398 [(set (match_operand 0 "register_operand" "")
9399 (xor (match_operand 1 "register_operand" "")
9400 (match_operand 2 "const_int_operand" "")))
9401 (clobber (reg:CC FLAGS_REG))]
9403 && QI_REG_P (operands[0])
9404 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9405 && !(INTVAL (operands[2]) & ~(255 << 8))
9406 && GET_MODE (operands[0]) != QImode"
9407 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9408 (xor:SI (zero_extract:SI (match_dup 1)
9409 (const_int 8) (const_int 8))
9411 (clobber (reg:CC FLAGS_REG))])]
9412 "operands[0] = gen_lowpart (SImode, operands[0]);
9413 operands[1] = gen_lowpart (SImode, operands[1]);
9414 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9416 ;; Since XOR can be encoded with sign extended immediate, this is only
9417 ;; profitable when 7th bit is set.
9419 [(set (match_operand 0 "register_operand" "")
9420 (xor (match_operand 1 "general_operand" "")
9421 (match_operand 2 "const_int_operand" "")))
9422 (clobber (reg:CC FLAGS_REG))]
9424 && ANY_QI_REG_P (operands[0])
9425 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9426 && !(INTVAL (operands[2]) & ~255)
9427 && (INTVAL (operands[2]) & 128)
9428 && GET_MODE (operands[0]) != QImode"
9429 [(parallel [(set (strict_low_part (match_dup 0))
9430 (xor:QI (match_dup 1)
9432 (clobber (reg:CC FLAGS_REG))])]
9433 "operands[0] = gen_lowpart (QImode, operands[0]);
9434 operands[1] = gen_lowpart (QImode, operands[1]);
9435 operands[2] = gen_lowpart (QImode, operands[2]);")
9437 ;; Negation instructions
9439 (define_expand "negdi2"
9440 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9441 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9442 (clobber (reg:CC FLAGS_REG))])]
9444 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9446 (define_insn "*negdi2_1"
9447 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9448 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9449 (clobber (reg:CC FLAGS_REG))]
9451 && ix86_unary_operator_ok (NEG, DImode, operands)"
9455 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9456 (neg:DI (match_operand:DI 1 "general_operand" "")))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "!TARGET_64BIT && reload_completed"
9460 [(set (reg:CCZ FLAGS_REG)
9461 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9462 (set (match_dup 0) (neg:SI (match_dup 2)))])
9465 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9468 (clobber (reg:CC FLAGS_REG))])
9471 (neg:SI (match_dup 1)))
9472 (clobber (reg:CC FLAGS_REG))])]
9473 "split_di (operands+1, 1, operands+2, operands+3);
9474 split_di (operands+0, 1, operands+0, operands+1);")
9476 (define_insn "*negdi2_1_rex64"
9477 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9478 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9479 (clobber (reg:CC FLAGS_REG))]
9480 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9482 [(set_attr "type" "negnot")
9483 (set_attr "mode" "DI")])
9485 ;; The problem with neg is that it does not perform (compare x 0),
9486 ;; it really performs (compare 0 x), which leaves us with the zero
9487 ;; flag being the only useful item.
9489 (define_insn "*negdi2_cmpz_rex64"
9490 [(set (reg:CCZ FLAGS_REG)
9491 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9493 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9494 (neg:DI (match_dup 1)))]
9495 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9497 [(set_attr "type" "negnot")
9498 (set_attr "mode" "DI")])
9501 (define_expand "negsi2"
9502 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9503 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9504 (clobber (reg:CC FLAGS_REG))])]
9506 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9508 (define_insn "*negsi2_1"
9509 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9510 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9511 (clobber (reg:CC FLAGS_REG))]
9512 "ix86_unary_operator_ok (NEG, SImode, operands)"
9514 [(set_attr "type" "negnot")
9515 (set_attr "mode" "SI")])
9517 ;; Combine is quite creative about this pattern.
9518 (define_insn "*negsi2_1_zext"
9519 [(set (match_operand:DI 0 "register_operand" "=r")
9520 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9523 (clobber (reg:CC FLAGS_REG))]
9524 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9526 [(set_attr "type" "negnot")
9527 (set_attr "mode" "SI")])
9529 ;; The problem with neg is that it does not perform (compare x 0),
9530 ;; it really performs (compare 0 x), which leaves us with the zero
9531 ;; flag being the only useful item.
9533 (define_insn "*negsi2_cmpz"
9534 [(set (reg:CCZ FLAGS_REG)
9535 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9537 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9538 (neg:SI (match_dup 1)))]
9539 "ix86_unary_operator_ok (NEG, SImode, operands)"
9541 [(set_attr "type" "negnot")
9542 (set_attr "mode" "SI")])
9544 (define_insn "*negsi2_cmpz_zext"
9545 [(set (reg:CCZ FLAGS_REG)
9546 (compare:CCZ (lshiftrt:DI
9548 (match_operand:DI 1 "register_operand" "0")
9552 (set (match_operand:DI 0 "register_operand" "=r")
9553 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9556 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9558 [(set_attr "type" "negnot")
9559 (set_attr "mode" "SI")])
9561 (define_expand "neghi2"
9562 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9563 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9564 (clobber (reg:CC FLAGS_REG))])]
9565 "TARGET_HIMODE_MATH"
9566 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9568 (define_insn "*neghi2_1"
9569 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9570 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9571 (clobber (reg:CC FLAGS_REG))]
9572 "ix86_unary_operator_ok (NEG, HImode, operands)"
9574 [(set_attr "type" "negnot")
9575 (set_attr "mode" "HI")])
9577 (define_insn "*neghi2_cmpz"
9578 [(set (reg:CCZ FLAGS_REG)
9579 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9581 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9582 (neg:HI (match_dup 1)))]
9583 "ix86_unary_operator_ok (NEG, HImode, operands)"
9585 [(set_attr "type" "negnot")
9586 (set_attr "mode" "HI")])
9588 (define_expand "negqi2"
9589 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9590 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9591 (clobber (reg:CC FLAGS_REG))])]
9592 "TARGET_QIMODE_MATH"
9593 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9595 (define_insn "*negqi2_1"
9596 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9597 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9598 (clobber (reg:CC FLAGS_REG))]
9599 "ix86_unary_operator_ok (NEG, QImode, operands)"
9601 [(set_attr "type" "negnot")
9602 (set_attr "mode" "QI")])
9604 (define_insn "*negqi2_cmpz"
9605 [(set (reg:CCZ FLAGS_REG)
9606 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9608 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9609 (neg:QI (match_dup 1)))]
9610 "ix86_unary_operator_ok (NEG, QImode, operands)"
9612 [(set_attr "type" "negnot")
9613 (set_attr "mode" "QI")])
9615 ;; Changing of sign for FP values is doable using integer unit too.
9617 (define_expand "negsf2"
9618 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9619 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9620 (clobber (reg:CC FLAGS_REG))])]
9624 /* In case operand is in memory, we will not use SSE. */
9625 if (memory_operand (operands[0], VOIDmode)
9626 && rtx_equal_p (operands[0], operands[1]))
9627 emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9630 /* Using SSE is tricky, since we need bitwise negation of -0
9632 rtx reg = gen_reg_rtx (SFmode);
9633 rtx dest = operands[0];
9634 rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9636 operands[1] = force_reg (SFmode, operands[1]);
9637 operands[0] = force_reg (SFmode, operands[0]);
9638 reg = force_reg (V4SFmode,
9639 gen_rtx_CONST_VECTOR (V4SFmode,
9640 gen_rtvec (4, imm, CONST0_RTX (SFmode),
9641 CONST0_RTX (SFmode),
9642 CONST0_RTX (SFmode))));
9643 emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9644 if (dest != operands[0])
9645 emit_move_insn (dest, operands[0]);
9649 ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9651 (define_insn "negsf2_memory"
9652 [(set (match_operand:SF 0 "memory_operand" "=m")
9653 (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9654 (clobber (reg:CC FLAGS_REG))]
9655 "ix86_unary_operator_ok (NEG, SFmode, operands)"
9658 (define_insn "negsf2_ifs"
9659 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9660 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9661 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9662 (clobber (reg:CC FLAGS_REG))]
9664 && (reload_in_progress || reload_completed
9665 || (register_operand (operands[0], VOIDmode)
9666 && register_operand (operands[1], VOIDmode)))"
9670 [(set (match_operand:SF 0 "memory_operand" "")
9671 (neg:SF (match_operand:SF 1 "memory_operand" "")))
9672 (use (match_operand:SF 2 "" ""))
9673 (clobber (reg:CC FLAGS_REG))]
9675 [(parallel [(set (match_dup 0)
9676 (neg:SF (match_dup 1)))
9677 (clobber (reg:CC FLAGS_REG))])])
9680 [(set (match_operand:SF 0 "register_operand" "")
9681 (neg:SF (match_operand:SF 1 "register_operand" "")))
9682 (use (match_operand:V4SF 2 "" ""))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "reload_completed && !SSE_REG_P (operands[0])"
9685 [(parallel [(set (match_dup 0)
9686 (neg:SF (match_dup 1)))
9687 (clobber (reg:CC FLAGS_REG))])])
9690 [(set (match_operand:SF 0 "register_operand" "")
9691 (neg:SF (match_operand:SF 1 "register_operand" "")))
9692 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9693 (clobber (reg:CC FLAGS_REG))]
9694 "reload_completed && SSE_REG_P (operands[0])"
9696 (xor:V4SF (match_dup 1)
9699 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
9700 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
9701 if (operands_match_p (operands[0], operands[2]))
9705 operands[1] = operands[2];
9711 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9712 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9714 (define_insn "*negsf2_if"
9715 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9716 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9717 (clobber (reg:CC FLAGS_REG))]
9718 "TARGET_80387 && !TARGET_SSE
9719 && ix86_unary_operator_ok (NEG, SFmode, operands)"
9723 [(set (match_operand:SF 0 "fp_register_operand" "")
9724 (neg:SF (match_operand:SF 1 "register_operand" "")))
9725 (clobber (reg:CC FLAGS_REG))]
9726 "TARGET_80387 && reload_completed"
9728 (neg:SF (match_dup 1)))]
9732 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9733 (neg:SF (match_operand:SF 1 "register_operand" "")))
9734 (clobber (reg:CC FLAGS_REG))]
9735 "TARGET_80387 && reload_completed"
9736 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9737 (clobber (reg:CC FLAGS_REG))])]
9738 "operands[1] = gen_int_mode (0x80000000, SImode);
9739 operands[0] = gen_lowpart (SImode, operands[0]);")
9742 [(set (match_operand 0 "memory_operand" "")
9743 (neg (match_operand 1 "memory_operand" "")))
9744 (clobber (reg:CC FLAGS_REG))]
9745 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9746 [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9747 (clobber (reg:CC FLAGS_REG))])]
9749 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9751 if (GET_MODE (operands[1]) == XFmode)
9753 operands[0] = adjust_address (operands[0], QImode, size - 1);
9754 operands[1] = gen_int_mode (0x80, QImode);
9757 (define_expand "negdf2"
9758 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9759 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9760 (clobber (reg:CC FLAGS_REG))])]
9764 /* In case operand is in memory, we will not use SSE. */
9765 if (memory_operand (operands[0], VOIDmode)
9766 && rtx_equal_p (operands[0], operands[1]))
9767 emit_insn (gen_negdf2_memory (operands[0], operands[1]));
9770 /* Using SSE is tricky, since we need bitwise negation of -0
9773 #if HOST_BITS_PER_WIDE_INT >= 64
9774 rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
9776 rtx imm = immed_double_const (0, 0x80000000, DImode);
9778 rtx dest = operands[0];
9780 operands[1] = force_reg (DFmode, operands[1]);
9781 operands[0] = force_reg (DFmode, operands[0]);
9782 imm = gen_lowpart (DFmode, imm);
9783 reg = force_reg (V2DFmode,
9784 gen_rtx_CONST_VECTOR (V2DFmode,
9785 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
9786 emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
9787 if (dest != operands[0])
9788 emit_move_insn (dest, operands[0]);
9792 ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
9794 (define_insn "negdf2_memory"
9795 [(set (match_operand:DF 0 "memory_operand" "=m")
9796 (neg:DF (match_operand:DF 1 "memory_operand" "0")))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "ix86_unary_operator_ok (NEG, DFmode, operands)"
9801 (define_insn "negdf2_ifs"
9802 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
9803 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
9804 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
9805 (clobber (reg:CC FLAGS_REG))]
9806 "!TARGET_64BIT && TARGET_SSE2
9807 && (reload_in_progress || reload_completed
9808 || (register_operand (operands[0], VOIDmode)
9809 && register_operand (operands[1], VOIDmode)))"
9812 (define_insn "*negdf2_ifs_rex64"
9813 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
9814 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
9815 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
9816 (clobber (reg:CC FLAGS_REG))]
9817 "TARGET_64BIT && TARGET_SSE2
9818 && (reload_in_progress || reload_completed
9819 || (register_operand (operands[0], VOIDmode)
9820 && register_operand (operands[1], VOIDmode)))"
9824 [(set (match_operand:DF 0 "memory_operand" "")
9825 (neg:DF (match_operand:DF 1 "memory_operand" "")))
9826 (use (match_operand:V2DF 2 "" ""))
9827 (clobber (reg:CC FLAGS_REG))]
9829 [(parallel [(set (match_dup 0)
9830 (neg:DF (match_dup 1)))
9831 (clobber (reg:CC FLAGS_REG))])])
9834 [(set (match_operand:DF 0 "register_operand" "")
9835 (neg:DF (match_operand:DF 1 "register_operand" "")))
9836 (use (match_operand:V2DF 2 "" ""))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "reload_completed && !SSE_REG_P (operands[0])
9839 && (!TARGET_64BIT || FP_REG_P (operands[0]))"
9840 [(parallel [(set (match_dup 0)
9841 (neg:DF (match_dup 1)))
9842 (clobber (reg:CC FLAGS_REG))])])
9845 [(set (match_operand:DF 0 "register_operand" "")
9846 (neg:DF (match_operand:DF 1 "register_operand" "")))
9847 (use (match_operand:V2DF 2 "" ""))
9848 (clobber (reg:CC FLAGS_REG))]
9849 "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
9850 [(parallel [(set (match_dup 0)
9851 (xor:DI (match_dup 1) (match_dup 2)))
9852 (clobber (reg:CC FLAGS_REG))])]
9853 "operands[0] = gen_lowpart (DImode, operands[0]);
9854 operands[1] = gen_lowpart (DImode, operands[1]);
9855 operands[2] = gen_lowpart (DImode, operands[2]);")
9858 [(set (match_operand:DF 0 "register_operand" "")
9859 (neg:DF (match_operand:DF 1 "register_operand" "")))
9860 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "reload_completed && SSE_REG_P (operands[0])"
9864 (xor:V2DF (match_dup 1)
9867 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
9868 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
9869 /* Avoid possible reformatting on the operands. */
9870 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
9871 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
9872 if (operands_match_p (operands[0], operands[2]))
9876 operands[1] = operands[2];
9881 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9882 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9884 (define_insn "*negdf2_if"
9885 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
9886 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9887 (clobber (reg:CC FLAGS_REG))]
9888 "!TARGET_64BIT && TARGET_80387
9889 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9892 ;; FIXME: We should to allow integer registers here. Problem is that
9893 ;; we need another scratch register to get constant from.
9894 ;; Forcing constant to mem if no register available in peep2 should be
9895 ;; safe even for PIC mode, because of RIP relative addressing.
9896 (define_insn "*negdf2_if_rex64"
9897 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
9898 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
9899 (clobber (reg:CC FLAGS_REG))]
9900 "TARGET_64BIT && TARGET_80387
9901 && ix86_unary_operator_ok (NEG, DFmode, operands)"
9905 [(set (match_operand:DF 0 "fp_register_operand" "")
9906 (neg:DF (match_operand:DF 1 "register_operand" "")))
9907 (clobber (reg:CC FLAGS_REG))]
9908 "TARGET_80387 && reload_completed"
9910 (neg:DF (match_dup 1)))]
9914 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
9915 (neg:DF (match_operand:DF 1 "register_operand" "")))
9916 (clobber (reg:CC FLAGS_REG))]
9917 "!TARGET_64BIT && TARGET_80387 && reload_completed"
9918 [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
9919 (clobber (reg:CC FLAGS_REG))])]
9920 "operands[4] = gen_int_mode (0x80000000, SImode);
9921 split_di (operands+0, 1, operands+2, operands+3);")
9923 (define_expand "negxf2"
9924 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
9925 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
9926 (clobber (reg:CC FLAGS_REG))])]
9928 "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
9930 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9931 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9933 (define_insn "*negxf2_if"
9934 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
9935 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
9936 (clobber (reg:CC FLAGS_REG))]
9938 && ix86_unary_operator_ok (NEG, XFmode, operands)"
9942 [(set (match_operand:XF 0 "fp_register_operand" "")
9943 (neg:XF (match_operand:XF 1 "register_operand" "")))
9944 (clobber (reg:CC FLAGS_REG))]
9945 "TARGET_80387 && reload_completed"
9947 (neg:XF (match_dup 1)))]
9951 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
9952 (neg:XF (match_operand:XF 1 "register_operand" "")))
9953 (clobber (reg:CC FLAGS_REG))]
9954 "TARGET_80387 && reload_completed"
9955 [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9956 (clobber (reg:CC FLAGS_REG))])]
9957 "operands[1] = GEN_INT (0x8000);
9958 operands[0] = gen_rtx_REG (SImode,
9959 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
9961 ;; Conditionalize these after reload. If they matches before reload, we
9962 ;; lose the clobber and ability to use integer instructions.
9964 (define_insn "*negsf2_1"
9965 [(set (match_operand:SF 0 "register_operand" "=f")
9966 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9967 "TARGET_80387 && reload_completed"
9969 [(set_attr "type" "fsgn")
9970 (set_attr "mode" "SF")])
9972 (define_insn "*negdf2_1"
9973 [(set (match_operand:DF 0 "register_operand" "=f")
9974 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9975 "TARGET_80387 && reload_completed"
9977 [(set_attr "type" "fsgn")
9978 (set_attr "mode" "DF")])
9980 (define_insn "*negextendsfdf2"
9981 [(set (match_operand:DF 0 "register_operand" "=f")
9982 (neg:DF (float_extend:DF
9983 (match_operand:SF 1 "register_operand" "0"))))]
9986 [(set_attr "type" "fsgn")
9987 (set_attr "mode" "DF")])
9989 (define_insn "*negxf2_1"
9990 [(set (match_operand:XF 0 "register_operand" "=f")
9991 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9992 "TARGET_80387 && reload_completed"
9994 [(set_attr "type" "fsgn")
9995 (set_attr "mode" "XF")])
9997 (define_insn "*negextenddfxf2"
9998 [(set (match_operand:XF 0 "register_operand" "=f")
9999 (neg:XF (float_extend:XF
10000 (match_operand:DF 1 "register_operand" "0"))))]
10003 [(set_attr "type" "fsgn")
10004 (set_attr "mode" "XF")])
10006 (define_insn "*negextendsfxf2"
10007 [(set (match_operand:XF 0 "register_operand" "=f")
10008 (neg:XF (float_extend:XF
10009 (match_operand:SF 1 "register_operand" "0"))))]
10012 [(set_attr "type" "fsgn")
10013 (set_attr "mode" "XF")])
10015 ;; Absolute value instructions
10017 (define_expand "abssf2"
10018 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10019 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10020 (clobber (reg:CC FLAGS_REG))])]
10024 /* In case operand is in memory, we will not use SSE. */
10025 if (memory_operand (operands[0], VOIDmode)
10026 && rtx_equal_p (operands[0], operands[1]))
10027 emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10030 /* Using SSE is tricky, since we need bitwise negation of -0
10032 rtx reg = gen_reg_rtx (V4SFmode);
10033 rtx dest = operands[0];
10036 operands[1] = force_reg (SFmode, operands[1]);
10037 operands[0] = force_reg (SFmode, operands[0]);
10038 imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10039 reg = force_reg (V4SFmode,
10040 gen_rtx_CONST_VECTOR (V4SFmode,
10041 gen_rtvec (4, imm, CONST0_RTX (SFmode),
10042 CONST0_RTX (SFmode),
10043 CONST0_RTX (SFmode))));
10044 emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10045 if (dest != operands[0])
10046 emit_move_insn (dest, operands[0]);
10050 ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10052 (define_insn "abssf2_memory"
10053 [(set (match_operand:SF 0 "memory_operand" "=m")
10054 (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10055 (clobber (reg:CC FLAGS_REG))]
10056 "ix86_unary_operator_ok (ABS, SFmode, operands)"
10059 (define_insn "abssf2_ifs"
10060 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10061 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10062 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10063 (clobber (reg:CC FLAGS_REG))]
10065 && (reload_in_progress || reload_completed
10066 || (register_operand (operands[0], VOIDmode)
10067 && register_operand (operands[1], VOIDmode)))"
10071 [(set (match_operand:SF 0 "memory_operand" "")
10072 (abs:SF (match_operand:SF 1 "memory_operand" "")))
10073 (use (match_operand:V4SF 2 "" ""))
10074 (clobber (reg:CC FLAGS_REG))]
10076 [(parallel [(set (match_dup 0)
10077 (abs:SF (match_dup 1)))
10078 (clobber (reg:CC FLAGS_REG))])])
10081 [(set (match_operand:SF 0 "register_operand" "")
10082 (abs:SF (match_operand:SF 1 "register_operand" "")))
10083 (use (match_operand:V4SF 2 "" ""))
10084 (clobber (reg:CC FLAGS_REG))]
10085 "reload_completed && !SSE_REG_P (operands[0])"
10086 [(parallel [(set (match_dup 0)
10087 (abs:SF (match_dup 1)))
10088 (clobber (reg:CC FLAGS_REG))])])
10091 [(set (match_operand:SF 0 "register_operand" "")
10092 (abs:SF (match_operand:SF 1 "register_operand" "")))
10093 (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10094 (clobber (reg:CC FLAGS_REG))]
10095 "reload_completed && SSE_REG_P (operands[0])"
10096 [(set (match_dup 0)
10097 (and:V4SF (match_dup 1)
10100 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
10101 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
10102 if (operands_match_p (operands[0], operands[2]))
10106 operands[1] = operands[2];
10111 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10112 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10114 (define_insn "*abssf2_if"
10115 [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10116 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10117 (clobber (reg:CC FLAGS_REG))]
10118 "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10122 [(set (match_operand:SF 0 "fp_register_operand" "")
10123 (abs:SF (match_operand:SF 1 "register_operand" "")))
10124 (clobber (reg:CC FLAGS_REG))]
10125 "TARGET_80387 && reload_completed"
10126 [(set (match_dup 0)
10127 (abs:SF (match_dup 1)))]
10131 [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10132 (abs:SF (match_operand:SF 1 "register_operand" "")))
10133 (clobber (reg:CC FLAGS_REG))]
10134 "TARGET_80387 && reload_completed"
10135 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10136 (clobber (reg:CC FLAGS_REG))])]
10137 "operands[1] = gen_int_mode (~0x80000000, SImode);
10138 operands[0] = gen_lowpart (SImode, operands[0]);")
10141 [(set (match_operand 0 "memory_operand" "")
10142 (abs (match_operand 1 "memory_operand" "")))
10143 (clobber (reg:CC FLAGS_REG))]
10144 "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10145 [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10146 (clobber (reg:CC FLAGS_REG))])]
10148 int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10150 if (GET_MODE (operands[1]) == XFmode)
10152 operands[0] = adjust_address (operands[0], QImode, size - 1);
10153 operands[1] = gen_int_mode (~0x80, QImode);
10156 (define_expand "absdf2"
10157 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10158 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10159 (clobber (reg:CC FLAGS_REG))])]
10163 /* In case operand is in memory, we will not use SSE. */
10164 if (memory_operand (operands[0], VOIDmode)
10165 && rtx_equal_p (operands[0], operands[1]))
10166 emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10169 /* Using SSE is tricky, since we need bitwise negation of -0
10171 rtx reg = gen_reg_rtx (V2DFmode);
10172 #if HOST_BITS_PER_WIDE_INT >= 64
10173 rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10175 rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10177 rtx dest = operands[0];
10179 operands[1] = force_reg (DFmode, operands[1]);
10180 operands[0] = force_reg (DFmode, operands[0]);
10182 /* Produce LONG_DOUBLE with the proper immediate argument. */
10183 imm = gen_lowpart (DFmode, imm);
10184 reg = force_reg (V2DFmode,
10185 gen_rtx_CONST_VECTOR (V2DFmode,
10186 gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10187 emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10188 if (dest != operands[0])
10189 emit_move_insn (dest, operands[0]);
10193 ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10195 (define_insn "absdf2_memory"
10196 [(set (match_operand:DF 0 "memory_operand" "=m")
10197 (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10198 (clobber (reg:CC FLAGS_REG))]
10199 "ix86_unary_operator_ok (ABS, DFmode, operands)"
10202 (define_insn "absdf2_ifs"
10203 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10204 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10205 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10206 (clobber (reg:CC FLAGS_REG))]
10207 "!TARGET_64BIT && TARGET_SSE2
10208 && (reload_in_progress || reload_completed
10209 || (register_operand (operands[0], VOIDmode)
10210 && register_operand (operands[1], VOIDmode)))"
10213 (define_insn "*absdf2_ifs_rex64"
10214 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10215 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10216 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10217 (clobber (reg:CC FLAGS_REG))]
10218 "TARGET_64BIT && TARGET_SSE2
10219 && (reload_in_progress || reload_completed
10220 || (register_operand (operands[0], VOIDmode)
10221 && register_operand (operands[1], VOIDmode)))"
10225 [(set (match_operand:DF 0 "memory_operand" "")
10226 (abs:DF (match_operand:DF 1 "memory_operand" "")))
10227 (use (match_operand:V2DF 2 "" ""))
10228 (clobber (reg:CC FLAGS_REG))]
10230 [(parallel [(set (match_dup 0)
10231 (abs:DF (match_dup 1)))
10232 (clobber (reg:CC FLAGS_REG))])])
10235 [(set (match_operand:DF 0 "register_operand" "")
10236 (abs:DF (match_operand:DF 1 "register_operand" "")))
10237 (use (match_operand:V2DF 2 "" ""))
10238 (clobber (reg:CC FLAGS_REG))]
10239 "reload_completed && !SSE_REG_P (operands[0])"
10240 [(parallel [(set (match_dup 0)
10241 (abs:DF (match_dup 1)))
10242 (clobber (reg:CC FLAGS_REG))])])
10245 [(set (match_operand:DF 0 "register_operand" "")
10246 (abs:DF (match_operand:DF 1 "register_operand" "")))
10247 (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10248 (clobber (reg:CC FLAGS_REG))]
10249 "reload_completed && SSE_REG_P (operands[0])"
10250 [(set (match_dup 0)
10251 (and:V2DF (match_dup 1)
10254 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10255 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
10256 /* Avoid possible reformatting on the operands. */
10257 if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10258 emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10259 if (operands_match_p (operands[0], operands[2]))
10263 operands[1] = operands[2];
10269 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10270 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10272 (define_insn "*absdf2_if"
10273 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10274 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10275 (clobber (reg:CC FLAGS_REG))]
10276 "!TARGET_64BIT && TARGET_80387
10277 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10280 ;; FIXME: We should to allow integer registers here. Problem is that
10281 ;; we need another scratch register to get constant from.
10282 ;; Forcing constant to mem if no register available in peep2 should be
10283 ;; safe even for PIC mode, because of RIP relative addressing.
10284 (define_insn "*absdf2_if_rex64"
10285 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10286 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10287 (clobber (reg:CC FLAGS_REG))]
10288 "TARGET_64BIT && TARGET_80387
10289 && ix86_unary_operator_ok (ABS, DFmode, operands)"
10293 [(set (match_operand:DF 0 "fp_register_operand" "")
10294 (abs:DF (match_operand:DF 1 "register_operand" "")))
10295 (clobber (reg:CC FLAGS_REG))]
10296 "TARGET_80387 && reload_completed"
10297 [(set (match_dup 0)
10298 (abs:DF (match_dup 1)))]
10302 [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10303 (abs:DF (match_operand:DF 1 "register_operand" "")))
10304 (clobber (reg:CC FLAGS_REG))]
10305 "!TARGET_64BIT && TARGET_80387 && reload_completed"
10306 [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10307 (clobber (reg:CC FLAGS_REG))])]
10308 "operands[4] = gen_int_mode (~0x80000000, SImode);
10309 split_di (operands+0, 1, operands+2, operands+3);")
10311 (define_expand "absxf2"
10312 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10313 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10314 (clobber (reg:CC FLAGS_REG))])]
10316 "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10318 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10319 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10321 (define_insn "*absxf2_if"
10322 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10323 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10324 (clobber (reg:CC FLAGS_REG))]
10326 && ix86_unary_operator_ok (ABS, XFmode, operands)"
10330 [(set (match_operand:XF 0 "fp_register_operand" "")
10331 (abs:XF (match_operand:XF 1 "register_operand" "")))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "TARGET_80387 && reload_completed"
10334 [(set (match_dup 0)
10335 (abs:XF (match_dup 1)))]
10339 [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10340 (abs:XF (match_operand:XF 1 "register_operand" "")))
10341 (clobber (reg:CC FLAGS_REG))]
10342 "TARGET_80387 && reload_completed"
10343 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10344 (clobber (reg:CC FLAGS_REG))])]
10345 "operands[1] = GEN_INT (~0x8000);
10346 operands[0] = gen_rtx_REG (SImode,
10347 true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10349 (define_insn "*abssf2_1"
10350 [(set (match_operand:SF 0 "register_operand" "=f")
10351 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10352 "TARGET_80387 && reload_completed"
10354 [(set_attr "type" "fsgn")
10355 (set_attr "mode" "SF")])
10357 (define_insn "*absdf2_1"
10358 [(set (match_operand:DF 0 "register_operand" "=f")
10359 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10360 "TARGET_80387 && reload_completed"
10362 [(set_attr "type" "fsgn")
10363 (set_attr "mode" "DF")])
10365 (define_insn "*absextendsfdf2"
10366 [(set (match_operand:DF 0 "register_operand" "=f")
10367 (abs:DF (float_extend:DF
10368 (match_operand:SF 1 "register_operand" "0"))))]
10371 [(set_attr "type" "fsgn")
10372 (set_attr "mode" "DF")])
10374 (define_insn "*absxf2_1"
10375 [(set (match_operand:XF 0 "register_operand" "=f")
10376 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10377 "TARGET_80387 && reload_completed"
10379 [(set_attr "type" "fsgn")
10380 (set_attr "mode" "DF")])
10382 (define_insn "*absextenddfxf2"
10383 [(set (match_operand:XF 0 "register_operand" "=f")
10384 (abs:XF (float_extend:XF
10385 (match_operand:DF 1 "register_operand" "0"))))]
10388 [(set_attr "type" "fsgn")
10389 (set_attr "mode" "XF")])
10391 (define_insn "*absextendsfxf2"
10392 [(set (match_operand:XF 0 "register_operand" "=f")
10393 (abs:XF (float_extend:XF
10394 (match_operand:SF 1 "register_operand" "0"))))]
10397 [(set_attr "type" "fsgn")
10398 (set_attr "mode" "XF")])
10400 ;; One complement instructions
10402 (define_expand "one_cmpldi2"
10403 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10404 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10406 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10408 (define_insn "*one_cmpldi2_1_rex64"
10409 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10410 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10411 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10413 [(set_attr "type" "negnot")
10414 (set_attr "mode" "DI")])
10416 (define_insn "*one_cmpldi2_2_rex64"
10418 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10420 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10421 (not:DI (match_dup 1)))]
10422 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10423 && ix86_unary_operator_ok (NOT, DImode, operands)"
10425 [(set_attr "type" "alu1")
10426 (set_attr "mode" "DI")])
10430 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10432 (set (match_operand:DI 0 "nonimmediate_operand" "")
10433 (not:DI (match_dup 1)))]
10434 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10435 [(parallel [(set (reg:CCNO FLAGS_REG)
10436 (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10439 (xor:DI (match_dup 1) (const_int -1)))])]
10442 (define_expand "one_cmplsi2"
10443 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10444 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10446 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10448 (define_insn "*one_cmplsi2_1"
10449 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10450 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10451 "ix86_unary_operator_ok (NOT, SImode, operands)"
10453 [(set_attr "type" "negnot")
10454 (set_attr "mode" "SI")])
10456 ;; ??? Currently never generated - xor is used instead.
10457 (define_insn "*one_cmplsi2_1_zext"
10458 [(set (match_operand:DI 0 "register_operand" "=r")
10459 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10460 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10462 [(set_attr "type" "negnot")
10463 (set_attr "mode" "SI")])
10465 (define_insn "*one_cmplsi2_2"
10467 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10469 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10470 (not:SI (match_dup 1)))]
10471 "ix86_match_ccmode (insn, CCNOmode)
10472 && ix86_unary_operator_ok (NOT, SImode, operands)"
10474 [(set_attr "type" "alu1")
10475 (set_attr "mode" "SI")])
10479 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10481 (set (match_operand:SI 0 "nonimmediate_operand" "")
10482 (not:SI (match_dup 1)))]
10483 "ix86_match_ccmode (insn, CCNOmode)"
10484 [(parallel [(set (reg:CCNO FLAGS_REG)
10485 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10488 (xor:SI (match_dup 1) (const_int -1)))])]
10491 ;; ??? Currently never generated - xor is used instead.
10492 (define_insn "*one_cmplsi2_2_zext"
10494 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10496 (set (match_operand:DI 0 "register_operand" "=r")
10497 (zero_extend:DI (not:SI (match_dup 1))))]
10498 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10499 && ix86_unary_operator_ok (NOT, SImode, operands)"
10501 [(set_attr "type" "alu1")
10502 (set_attr "mode" "SI")])
10506 (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10508 (set (match_operand:DI 0 "register_operand" "")
10509 (zero_extend:DI (not:SI (match_dup 1))))]
10510 "ix86_match_ccmode (insn, CCNOmode)"
10511 [(parallel [(set (reg:CCNO FLAGS_REG)
10512 (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10515 (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10518 (define_expand "one_cmplhi2"
10519 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10520 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10521 "TARGET_HIMODE_MATH"
10522 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10524 (define_insn "*one_cmplhi2_1"
10525 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10526 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10527 "ix86_unary_operator_ok (NOT, HImode, operands)"
10529 [(set_attr "type" "negnot")
10530 (set_attr "mode" "HI")])
10532 (define_insn "*one_cmplhi2_2"
10534 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10536 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10537 (not:HI (match_dup 1)))]
10538 "ix86_match_ccmode (insn, CCNOmode)
10539 && ix86_unary_operator_ok (NEG, HImode, operands)"
10541 [(set_attr "type" "alu1")
10542 (set_attr "mode" "HI")])
10546 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10548 (set (match_operand:HI 0 "nonimmediate_operand" "")
10549 (not:HI (match_dup 1)))]
10550 "ix86_match_ccmode (insn, CCNOmode)"
10551 [(parallel [(set (reg:CCNO FLAGS_REG)
10552 (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10555 (xor:HI (match_dup 1) (const_int -1)))])]
10558 ;; %%% Potential partial reg stall on alternative 1. What to do?
10559 (define_expand "one_cmplqi2"
10560 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10561 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10562 "TARGET_QIMODE_MATH"
10563 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10565 (define_insn "*one_cmplqi2_1"
10566 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10567 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10568 "ix86_unary_operator_ok (NOT, QImode, operands)"
10572 [(set_attr "type" "negnot")
10573 (set_attr "mode" "QI,SI")])
10575 (define_insn "*one_cmplqi2_2"
10577 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10579 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10580 (not:QI (match_dup 1)))]
10581 "ix86_match_ccmode (insn, CCNOmode)
10582 && ix86_unary_operator_ok (NOT, QImode, operands)"
10584 [(set_attr "type" "alu1")
10585 (set_attr "mode" "QI")])
10589 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10591 (set (match_operand:QI 0 "nonimmediate_operand" "")
10592 (not:QI (match_dup 1)))]
10593 "ix86_match_ccmode (insn, CCNOmode)"
10594 [(parallel [(set (reg:CCNO FLAGS_REG)
10595 (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10598 (xor:QI (match_dup 1) (const_int -1)))])]
10601 ;; Arithmetic shift instructions
10603 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10604 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10605 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10606 ;; from the assembler input.
10608 ;; This instruction shifts the target reg/mem as usual, but instead of
10609 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10610 ;; is a left shift double, bits are taken from the high order bits of
10611 ;; reg, else if the insn is a shift right double, bits are taken from the
10612 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10613 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10615 ;; Since sh[lr]d does not change the `reg' operand, that is done
10616 ;; separately, making all shifts emit pairs of shift double and normal
10617 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10618 ;; support a 63 bit shift, each shift where the count is in a reg expands
10619 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10621 ;; If the shift count is a constant, we need never emit more than one
10622 ;; shift pair, instead using moves and sign extension for counts greater
10625 (define_expand "ashldi3"
10626 [(set (match_operand:DI 0 "shiftdi_operand" "")
10627 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10628 (match_operand:QI 2 "nonmemory_operand" "")))]
10630 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10632 (define_insn "*ashldi3_1_rex64"
10633 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10634 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
10635 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10636 (clobber (reg:CC FLAGS_REG))]
10637 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10639 switch (get_attr_type (insn))
10642 if (operands[2] != const1_rtx)
10644 if (!rtx_equal_p (operands[0], operands[1]))
10646 return "add{q}\t{%0, %0|%0, %0}";
10649 if (GET_CODE (operands[2]) != CONST_INT
10650 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10652 operands[1] = gen_rtx_MULT (DImode, operands[1],
10653 GEN_INT (1 << INTVAL (operands[2])));
10654 return "lea{q}\t{%a1, %0|%0, %a1}";
10657 if (REG_P (operands[2]))
10658 return "sal{q}\t{%b2, %0|%0, %b2}";
10659 else if (operands[2] == const1_rtx
10660 && (TARGET_SHIFT1 || optimize_size))
10661 return "sal{q}\t%0";
10663 return "sal{q}\t{%2, %0|%0, %2}";
10666 [(set (attr "type")
10667 (cond [(eq_attr "alternative" "1")
10668 (const_string "lea")
10669 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10671 (match_operand 0 "register_operand" ""))
10672 (match_operand 2 "const1_operand" ""))
10673 (const_string "alu")
10675 (const_string "ishift")))
10676 (set_attr "mode" "DI")])
10678 ;; Convert lea to the lea pattern to avoid flags dependency.
10680 [(set (match_operand:DI 0 "register_operand" "")
10681 (ashift:DI (match_operand:DI 1 "register_operand" "")
10682 (match_operand:QI 2 "immediate_operand" "")))
10683 (clobber (reg:CC FLAGS_REG))]
10684 "TARGET_64BIT && reload_completed
10685 && true_regnum (operands[0]) != true_regnum (operands[1])"
10686 [(set (match_dup 0)
10687 (mult:DI (match_dup 1)
10689 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10691 ;; This pattern can't accept a variable shift count, since shifts by
10692 ;; zero don't affect the flags. We assume that shifts by constant
10693 ;; zero are optimized away.
10694 (define_insn "*ashldi3_cmp_rex64"
10697 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10698 (match_operand:QI 2 "immediate_operand" "e"))
10700 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10701 (ashift:DI (match_dup 1) (match_dup 2)))]
10702 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10703 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10705 switch (get_attr_type (insn))
10708 if (operands[2] != const1_rtx)
10710 return "add{q}\t{%0, %0|%0, %0}";
10713 if (REG_P (operands[2]))
10714 return "sal{q}\t{%b2, %0|%0, %b2}";
10715 else if (operands[2] == const1_rtx
10716 && (TARGET_SHIFT1 || optimize_size))
10717 return "sal{q}\t%0";
10719 return "sal{q}\t{%2, %0|%0, %2}";
10722 [(set (attr "type")
10723 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10725 (match_operand 0 "register_operand" ""))
10726 (match_operand 2 "const1_operand" ""))
10727 (const_string "alu")
10729 (const_string "ishift")))
10730 (set_attr "mode" "DI")])
10732 (define_insn "*ashldi3_1"
10733 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10734 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10735 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10736 (clobber (reg:CC FLAGS_REG))]
10739 [(set_attr "type" "multi")])
10741 ;; By default we don't ask for a scratch register, because when DImode
10742 ;; values are manipulated, registers are already at a premium. But if
10743 ;; we have one handy, we won't turn it away.
10745 [(match_scratch:SI 3 "r")
10746 (parallel [(set (match_operand:DI 0 "register_operand" "")
10747 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10748 (match_operand:QI 2 "nonmemory_operand" "")))
10749 (clobber (reg:CC FLAGS_REG))])
10751 "!TARGET_64BIT && TARGET_CMOVE"
10753 "ix86_split_ashldi (operands, operands[3]); DONE;")
10756 [(set (match_operand:DI 0 "register_operand" "")
10757 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10758 (match_operand:QI 2 "nonmemory_operand" "")))
10759 (clobber (reg:CC FLAGS_REG))]
10760 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10762 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10764 (define_insn "x86_shld_1"
10765 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10766 (ior:SI (ashift:SI (match_dup 0)
10767 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10768 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10769 (minus:QI (const_int 32) (match_dup 2)))))
10770 (clobber (reg:CC FLAGS_REG))]
10773 shld{l}\t{%2, %1, %0|%0, %1, %2}
10774 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10775 [(set_attr "type" "ishift")
10776 (set_attr "prefix_0f" "1")
10777 (set_attr "mode" "SI")
10778 (set_attr "pent_pair" "np")
10779 (set_attr "athlon_decode" "vector")])
10781 (define_expand "x86_shift_adj_1"
10782 [(set (reg:CCZ FLAGS_REG)
10783 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10786 (set (match_operand:SI 0 "register_operand" "")
10787 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10788 (match_operand:SI 1 "register_operand" "")
10791 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10792 (match_operand:SI 3 "register_operand" "r")
10797 (define_expand "x86_shift_adj_2"
10798 [(use (match_operand:SI 0 "register_operand" ""))
10799 (use (match_operand:SI 1 "register_operand" ""))
10800 (use (match_operand:QI 2 "register_operand" ""))]
10803 rtx label = gen_label_rtx ();
10806 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10808 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10809 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10810 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10811 gen_rtx_LABEL_REF (VOIDmode, label),
10813 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10814 JUMP_LABEL (tmp) = label;
10816 emit_move_insn (operands[0], operands[1]);
10817 ix86_expand_clear (operands[1]);
10819 emit_label (label);
10820 LABEL_NUSES (label) = 1;
10825 (define_expand "ashlsi3"
10826 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10827 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10828 (match_operand:QI 2 "nonmemory_operand" "")))
10829 (clobber (reg:CC FLAGS_REG))]
10831 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10833 (define_insn "*ashlsi3_1"
10834 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10835 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
10836 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10837 (clobber (reg:CC FLAGS_REG))]
10838 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10840 switch (get_attr_type (insn))
10843 if (operands[2] != const1_rtx)
10845 if (!rtx_equal_p (operands[0], operands[1]))
10847 return "add{l}\t{%0, %0|%0, %0}";
10853 if (REG_P (operands[2]))
10854 return "sal{l}\t{%b2, %0|%0, %b2}";
10855 else if (operands[2] == const1_rtx
10856 && (TARGET_SHIFT1 || optimize_size))
10857 return "sal{l}\t%0";
10859 return "sal{l}\t{%2, %0|%0, %2}";
10862 [(set (attr "type")
10863 (cond [(eq_attr "alternative" "1")
10864 (const_string "lea")
10865 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10867 (match_operand 0 "register_operand" ""))
10868 (match_operand 2 "const1_operand" ""))
10869 (const_string "alu")
10871 (const_string "ishift")))
10872 (set_attr "mode" "SI")])
10874 ;; Convert lea to the lea pattern to avoid flags dependency.
10876 [(set (match_operand 0 "register_operand" "")
10877 (ashift (match_operand 1 "index_register_operand" "")
10878 (match_operand:QI 2 "const_int_operand" "")))
10879 (clobber (reg:CC FLAGS_REG))]
10881 && true_regnum (operands[0]) != true_regnum (operands[1])"
10885 operands[0] = gen_lowpart (SImode, operands[0]);
10886 operands[1] = gen_lowpart (Pmode, operands[1]);
10887 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10888 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10889 if (Pmode != SImode)
10890 pat = gen_rtx_SUBREG (SImode, pat, 0);
10891 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10895 ;; Rare case of shifting RSP is handled by generating move and shift
10897 [(set (match_operand 0 "register_operand" "")
10898 (ashift (match_operand 1 "register_operand" "")
10899 (match_operand:QI 2 "const_int_operand" "")))
10900 (clobber (reg:CC FLAGS_REG))]
10902 && true_regnum (operands[0]) != true_regnum (operands[1])"
10906 emit_move_insn (operands[1], operands[0]);
10907 pat = gen_rtx_SET (VOIDmode, operands[0],
10908 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10909 operands[0], operands[2]));
10910 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10911 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10915 (define_insn "*ashlsi3_1_zext"
10916 [(set (match_operand:DI 0 "register_operand" "=r,r")
10917 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
10918 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10919 (clobber (reg:CC FLAGS_REG))]
10920 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10922 switch (get_attr_type (insn))
10925 if (operands[2] != const1_rtx)
10927 return "add{l}\t{%k0, %k0|%k0, %k0}";
10933 if (REG_P (operands[2]))
10934 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10935 else if (operands[2] == const1_rtx
10936 && (TARGET_SHIFT1 || optimize_size))
10937 return "sal{l}\t%k0";
10939 return "sal{l}\t{%2, %k0|%k0, %2}";
10942 [(set (attr "type")
10943 (cond [(eq_attr "alternative" "1")
10944 (const_string "lea")
10945 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10947 (match_operand 2 "const1_operand" ""))
10948 (const_string "alu")
10950 (const_string "ishift")))
10951 (set_attr "mode" "SI")])
10953 ;; Convert lea to the lea pattern to avoid flags dependency.
10955 [(set (match_operand:DI 0 "register_operand" "")
10956 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10957 (match_operand:QI 2 "const_int_operand" ""))))
10958 (clobber (reg:CC FLAGS_REG))]
10959 "TARGET_64BIT && reload_completed
10960 && true_regnum (operands[0]) != true_regnum (operands[1])"
10961 [(set (match_dup 0) (zero_extend:DI
10962 (subreg:SI (mult:SI (match_dup 1)
10963 (match_dup 2)) 0)))]
10965 operands[1] = gen_lowpart (Pmode, operands[1]);
10966 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10969 ;; This pattern can't accept a variable shift count, since shifts by
10970 ;; zero don't affect the flags. We assume that shifts by constant
10971 ;; zero are optimized away.
10972 (define_insn "*ashlsi3_cmp"
10975 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10976 (match_operand:QI 2 "const_int_1_31_operand" "I"))
10978 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10979 (ashift:SI (match_dup 1) (match_dup 2)))]
10980 "ix86_match_ccmode (insn, CCGOCmode)
10981 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10983 switch (get_attr_type (insn))
10986 if (operands[2] != const1_rtx)
10988 return "add{l}\t{%0, %0|%0, %0}";
10991 if (REG_P (operands[2]))
10992 return "sal{l}\t{%b2, %0|%0, %b2}";
10993 else if (operands[2] == const1_rtx
10994 && (TARGET_SHIFT1 || optimize_size))
10995 return "sal{l}\t%0";
10997 return "sal{l}\t{%2, %0|%0, %2}";
11000 [(set (attr "type")
11001 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11003 (match_operand 0 "register_operand" ""))
11004 (match_operand 2 "const1_operand" ""))
11005 (const_string "alu")
11007 (const_string "ishift")))
11008 (set_attr "mode" "SI")])
11010 (define_insn "*ashlsi3_cmp_zext"
11013 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11014 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11016 (set (match_operand:DI 0 "register_operand" "=r")
11017 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11018 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11019 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11021 switch (get_attr_type (insn))
11024 if (operands[2] != const1_rtx)
11026 return "add{l}\t{%k0, %k0|%k0, %k0}";
11029 if (REG_P (operands[2]))
11030 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11031 else if (operands[2] == const1_rtx
11032 && (TARGET_SHIFT1 || optimize_size))
11033 return "sal{l}\t%k0";
11035 return "sal{l}\t{%2, %k0|%k0, %2}";
11038 [(set (attr "type")
11039 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11041 (match_operand 2 "const1_operand" ""))
11042 (const_string "alu")
11044 (const_string "ishift")))
11045 (set_attr "mode" "SI")])
11047 (define_expand "ashlhi3"
11048 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11049 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11050 (match_operand:QI 2 "nonmemory_operand" "")))
11051 (clobber (reg:CC FLAGS_REG))]
11052 "TARGET_HIMODE_MATH"
11053 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11055 (define_insn "*ashlhi3_1_lea"
11056 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11057 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11058 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11059 (clobber (reg:CC FLAGS_REG))]
11060 "!TARGET_PARTIAL_REG_STALL
11061 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11063 switch (get_attr_type (insn))
11068 if (operands[2] != const1_rtx)
11070 return "add{w}\t{%0, %0|%0, %0}";
11073 if (REG_P (operands[2]))
11074 return "sal{w}\t{%b2, %0|%0, %b2}";
11075 else if (operands[2] == const1_rtx
11076 && (TARGET_SHIFT1 || optimize_size))
11077 return "sal{w}\t%0";
11079 return "sal{w}\t{%2, %0|%0, %2}";
11082 [(set (attr "type")
11083 (cond [(eq_attr "alternative" "1")
11084 (const_string "lea")
11085 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11087 (match_operand 0 "register_operand" ""))
11088 (match_operand 2 "const1_operand" ""))
11089 (const_string "alu")
11091 (const_string "ishift")))
11092 (set_attr "mode" "HI,SI")])
11094 (define_insn "*ashlhi3_1"
11095 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11096 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11097 (match_operand:QI 2 "nonmemory_operand" "cI")))
11098 (clobber (reg:CC FLAGS_REG))]
11099 "TARGET_PARTIAL_REG_STALL
11100 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11102 switch (get_attr_type (insn))
11105 if (operands[2] != const1_rtx)
11107 return "add{w}\t{%0, %0|%0, %0}";
11110 if (REG_P (operands[2]))
11111 return "sal{w}\t{%b2, %0|%0, %b2}";
11112 else if (operands[2] == const1_rtx
11113 && (TARGET_SHIFT1 || optimize_size))
11114 return "sal{w}\t%0";
11116 return "sal{w}\t{%2, %0|%0, %2}";
11119 [(set (attr "type")
11120 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11122 (match_operand 0 "register_operand" ""))
11123 (match_operand 2 "const1_operand" ""))
11124 (const_string "alu")
11126 (const_string "ishift")))
11127 (set_attr "mode" "HI")])
11129 ;; This pattern can't accept a variable shift count, since shifts by
11130 ;; zero don't affect the flags. We assume that shifts by constant
11131 ;; zero are optimized away.
11132 (define_insn "*ashlhi3_cmp"
11135 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11136 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11138 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11139 (ashift:HI (match_dup 1) (match_dup 2)))]
11140 "ix86_match_ccmode (insn, CCGOCmode)
11141 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11143 switch (get_attr_type (insn))
11146 if (operands[2] != const1_rtx)
11148 return "add{w}\t{%0, %0|%0, %0}";
11151 if (REG_P (operands[2]))
11152 return "sal{w}\t{%b2, %0|%0, %b2}";
11153 else if (operands[2] == const1_rtx
11154 && (TARGET_SHIFT1 || optimize_size))
11155 return "sal{w}\t%0";
11157 return "sal{w}\t{%2, %0|%0, %2}";
11160 [(set (attr "type")
11161 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11163 (match_operand 0 "register_operand" ""))
11164 (match_operand 2 "const1_operand" ""))
11165 (const_string "alu")
11167 (const_string "ishift")))
11168 (set_attr "mode" "HI")])
11170 (define_expand "ashlqi3"
11171 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11172 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11173 (match_operand:QI 2 "nonmemory_operand" "")))
11174 (clobber (reg:CC FLAGS_REG))]
11175 "TARGET_QIMODE_MATH"
11176 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11178 ;; %%% Potential partial reg stall on alternative 2. What to do?
11180 (define_insn "*ashlqi3_1_lea"
11181 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11182 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11183 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11184 (clobber (reg:CC FLAGS_REG))]
11185 "!TARGET_PARTIAL_REG_STALL
11186 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11188 switch (get_attr_type (insn))
11193 if (operands[2] != const1_rtx)
11195 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11196 return "add{l}\t{%k0, %k0|%k0, %k0}";
11198 return "add{b}\t{%0, %0|%0, %0}";
11201 if (REG_P (operands[2]))
11203 if (get_attr_mode (insn) == MODE_SI)
11204 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11206 return "sal{b}\t{%b2, %0|%0, %b2}";
11208 else if (operands[2] == const1_rtx
11209 && (TARGET_SHIFT1 || optimize_size))
11211 if (get_attr_mode (insn) == MODE_SI)
11212 return "sal{l}\t%0";
11214 return "sal{b}\t%0";
11218 if (get_attr_mode (insn) == MODE_SI)
11219 return "sal{l}\t{%2, %k0|%k0, %2}";
11221 return "sal{b}\t{%2, %0|%0, %2}";
11225 [(set (attr "type")
11226 (cond [(eq_attr "alternative" "2")
11227 (const_string "lea")
11228 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11230 (match_operand 0 "register_operand" ""))
11231 (match_operand 2 "const1_operand" ""))
11232 (const_string "alu")
11234 (const_string "ishift")))
11235 (set_attr "mode" "QI,SI,SI")])
11237 (define_insn "*ashlqi3_1"
11238 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11239 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11240 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11241 (clobber (reg:CC FLAGS_REG))]
11242 "TARGET_PARTIAL_REG_STALL
11243 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11245 switch (get_attr_type (insn))
11248 if (operands[2] != const1_rtx)
11250 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11251 return "add{l}\t{%k0, %k0|%k0, %k0}";
11253 return "add{b}\t{%0, %0|%0, %0}";
11256 if (REG_P (operands[2]))
11258 if (get_attr_mode (insn) == MODE_SI)
11259 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11261 return "sal{b}\t{%b2, %0|%0, %b2}";
11263 else if (operands[2] == const1_rtx
11264 && (TARGET_SHIFT1 || optimize_size))
11266 if (get_attr_mode (insn) == MODE_SI)
11267 return "sal{l}\t%0";
11269 return "sal{b}\t%0";
11273 if (get_attr_mode (insn) == MODE_SI)
11274 return "sal{l}\t{%2, %k0|%k0, %2}";
11276 return "sal{b}\t{%2, %0|%0, %2}";
11280 [(set (attr "type")
11281 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11283 (match_operand 0 "register_operand" ""))
11284 (match_operand 2 "const1_operand" ""))
11285 (const_string "alu")
11287 (const_string "ishift")))
11288 (set_attr "mode" "QI,SI")])
11290 ;; This pattern can't accept a variable shift count, since shifts by
11291 ;; zero don't affect the flags. We assume that shifts by constant
11292 ;; zero are optimized away.
11293 (define_insn "*ashlqi3_cmp"
11296 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11297 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11299 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11300 (ashift:QI (match_dup 1) (match_dup 2)))]
11301 "ix86_match_ccmode (insn, CCGOCmode)
11302 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11304 switch (get_attr_type (insn))
11307 if (operands[2] != const1_rtx)
11309 return "add{b}\t{%0, %0|%0, %0}";
11312 if (REG_P (operands[2]))
11313 return "sal{b}\t{%b2, %0|%0, %b2}";
11314 else if (operands[2] == const1_rtx
11315 && (TARGET_SHIFT1 || optimize_size))
11316 return "sal{b}\t%0";
11318 return "sal{b}\t{%2, %0|%0, %2}";
11321 [(set (attr "type")
11322 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11324 (match_operand 0 "register_operand" ""))
11325 (match_operand 2 "const1_operand" ""))
11326 (const_string "alu")
11328 (const_string "ishift")))
11329 (set_attr "mode" "QI")])
11331 ;; See comment above `ashldi3' about how this works.
11333 (define_expand "ashrdi3"
11334 [(set (match_operand:DI 0 "shiftdi_operand" "")
11335 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11336 (match_operand:QI 2 "nonmemory_operand" "")))]
11338 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11340 (define_insn "*ashrdi3_63_rex64"
11341 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11342 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11343 (match_operand:DI 2 "const_int_operand" "i,i")))
11344 (clobber (reg:CC FLAGS_REG))]
11345 "TARGET_64BIT && INTVAL (operands[2]) == 63
11346 && (TARGET_USE_CLTD || optimize_size)
11347 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11350 sar{q}\t{%2, %0|%0, %2}"
11351 [(set_attr "type" "imovx,ishift")
11352 (set_attr "prefix_0f" "0,*")
11353 (set_attr "length_immediate" "0,*")
11354 (set_attr "modrm" "0,1")
11355 (set_attr "mode" "DI")])
11357 (define_insn "*ashrdi3_1_one_bit_rex64"
11358 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11359 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11360 (match_operand:QI 2 "const1_operand" "")))
11361 (clobber (reg:CC FLAGS_REG))]
11362 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11363 && (TARGET_SHIFT1 || optimize_size)"
11365 [(set_attr "type" "ishift")
11366 (set (attr "length")
11367 (if_then_else (match_operand:DI 0 "register_operand" "")
11369 (const_string "*")))])
11371 (define_insn "*ashrdi3_1_rex64"
11372 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11373 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11374 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11375 (clobber (reg:CC FLAGS_REG))]
11376 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11378 sar{q}\t{%2, %0|%0, %2}
11379 sar{q}\t{%b2, %0|%0, %b2}"
11380 [(set_attr "type" "ishift")
11381 (set_attr "mode" "DI")])
11383 ;; This pattern can't accept a variable shift count, since shifts by
11384 ;; zero don't affect the flags. We assume that shifts by constant
11385 ;; zero are optimized away.
11386 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11389 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11390 (match_operand:QI 2 "const1_operand" ""))
11392 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11393 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11394 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11395 && (TARGET_SHIFT1 || optimize_size)
11396 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11398 [(set_attr "type" "ishift")
11399 (set (attr "length")
11400 (if_then_else (match_operand:DI 0 "register_operand" "")
11402 (const_string "*")))])
11404 ;; This pattern can't accept a variable shift count, since shifts by
11405 ;; zero don't affect the flags. We assume that shifts by constant
11406 ;; zero are optimized away.
11407 (define_insn "*ashrdi3_cmp_rex64"
11410 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11411 (match_operand:QI 2 "const_int_operand" "n"))
11413 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11414 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11415 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11416 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11417 "sar{q}\t{%2, %0|%0, %2}"
11418 [(set_attr "type" "ishift")
11419 (set_attr "mode" "DI")])
11421 (define_insn "*ashrdi3_1"
11422 [(set (match_operand:DI 0 "register_operand" "=r")
11423 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11424 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11425 (clobber (reg:CC FLAGS_REG))]
11428 [(set_attr "type" "multi")])
11430 ;; By default we don't ask for a scratch register, because when DImode
11431 ;; values are manipulated, registers are already at a premium. But if
11432 ;; we have one handy, we won't turn it away.
11434 [(match_scratch:SI 3 "r")
11435 (parallel [(set (match_operand:DI 0 "register_operand" "")
11436 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11437 (match_operand:QI 2 "nonmemory_operand" "")))
11438 (clobber (reg:CC FLAGS_REG))])
11440 "!TARGET_64BIT && TARGET_CMOVE"
11442 "ix86_split_ashrdi (operands, operands[3]); DONE;")
11445 [(set (match_operand:DI 0 "register_operand" "")
11446 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11447 (match_operand:QI 2 "nonmemory_operand" "")))
11448 (clobber (reg:CC FLAGS_REG))]
11449 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11451 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11453 (define_insn "x86_shrd_1"
11454 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11455 (ior:SI (ashiftrt:SI (match_dup 0)
11456 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11457 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11458 (minus:QI (const_int 32) (match_dup 2)))))
11459 (clobber (reg:CC FLAGS_REG))]
11462 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11463 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11464 [(set_attr "type" "ishift")
11465 (set_attr "prefix_0f" "1")
11466 (set_attr "pent_pair" "np")
11467 (set_attr "mode" "SI")])
11469 (define_expand "x86_shift_adj_3"
11470 [(use (match_operand:SI 0 "register_operand" ""))
11471 (use (match_operand:SI 1 "register_operand" ""))
11472 (use (match_operand:QI 2 "register_operand" ""))]
11475 rtx label = gen_label_rtx ();
11478 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11480 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11481 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11482 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11483 gen_rtx_LABEL_REF (VOIDmode, label),
11485 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11486 JUMP_LABEL (tmp) = label;
11488 emit_move_insn (operands[0], operands[1]);
11489 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11491 emit_label (label);
11492 LABEL_NUSES (label) = 1;
11497 (define_insn "ashrsi3_31"
11498 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11499 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11500 (match_operand:SI 2 "const_int_operand" "i,i")))
11501 (clobber (reg:CC FLAGS_REG))]
11502 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11503 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11506 sar{l}\t{%2, %0|%0, %2}"
11507 [(set_attr "type" "imovx,ishift")
11508 (set_attr "prefix_0f" "0,*")
11509 (set_attr "length_immediate" "0,*")
11510 (set_attr "modrm" "0,1")
11511 (set_attr "mode" "SI")])
11513 (define_insn "*ashrsi3_31_zext"
11514 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11515 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11516 (match_operand:SI 2 "const_int_operand" "i,i"))))
11517 (clobber (reg:CC FLAGS_REG))]
11518 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11519 && INTVAL (operands[2]) == 31
11520 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11523 sar{l}\t{%2, %k0|%k0, %2}"
11524 [(set_attr "type" "imovx,ishift")
11525 (set_attr "prefix_0f" "0,*")
11526 (set_attr "length_immediate" "0,*")
11527 (set_attr "modrm" "0,1")
11528 (set_attr "mode" "SI")])
11530 (define_expand "ashrsi3"
11531 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11532 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11533 (match_operand:QI 2 "nonmemory_operand" "")))
11534 (clobber (reg:CC FLAGS_REG))]
11536 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11538 (define_insn "*ashrsi3_1_one_bit"
11539 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11540 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11541 (match_operand:QI 2 "const1_operand" "")))
11542 (clobber (reg:CC FLAGS_REG))]
11543 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11544 && (TARGET_SHIFT1 || optimize_size)"
11546 [(set_attr "type" "ishift")
11547 (set (attr "length")
11548 (if_then_else (match_operand:SI 0 "register_operand" "")
11550 (const_string "*")))])
11552 (define_insn "*ashrsi3_1_one_bit_zext"
11553 [(set (match_operand:DI 0 "register_operand" "=r")
11554 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11555 (match_operand:QI 2 "const1_operand" ""))))
11556 (clobber (reg:CC FLAGS_REG))]
11557 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11558 && (TARGET_SHIFT1 || optimize_size)"
11560 [(set_attr "type" "ishift")
11561 (set_attr "length" "2")])
11563 (define_insn "*ashrsi3_1"
11564 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11565 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11566 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11567 (clobber (reg:CC FLAGS_REG))]
11568 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11570 sar{l}\t{%2, %0|%0, %2}
11571 sar{l}\t{%b2, %0|%0, %b2}"
11572 [(set_attr "type" "ishift")
11573 (set_attr "mode" "SI")])
11575 (define_insn "*ashrsi3_1_zext"
11576 [(set (match_operand:DI 0 "register_operand" "=r,r")
11577 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11578 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11579 (clobber (reg:CC FLAGS_REG))]
11580 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11582 sar{l}\t{%2, %k0|%k0, %2}
11583 sar{l}\t{%b2, %k0|%k0, %b2}"
11584 [(set_attr "type" "ishift")
11585 (set_attr "mode" "SI")])
11587 ;; This pattern can't accept a variable shift count, since shifts by
11588 ;; zero don't affect the flags. We assume that shifts by constant
11589 ;; zero are optimized away.
11590 (define_insn "*ashrsi3_one_bit_cmp"
11593 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11594 (match_operand:QI 2 "const1_operand" ""))
11596 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11597 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11598 "ix86_match_ccmode (insn, CCGOCmode)
11599 && (TARGET_SHIFT1 || optimize_size)
11600 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11602 [(set_attr "type" "ishift")
11603 (set (attr "length")
11604 (if_then_else (match_operand:SI 0 "register_operand" "")
11606 (const_string "*")))])
11608 (define_insn "*ashrsi3_one_bit_cmp_zext"
11611 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11612 (match_operand:QI 2 "const1_operand" ""))
11614 (set (match_operand:DI 0 "register_operand" "=r")
11615 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11616 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11617 && (TARGET_SHIFT1 || optimize_size)
11618 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11620 [(set_attr "type" "ishift")
11621 (set_attr "length" "2")])
11623 ;; This pattern can't accept a variable shift count, since shifts by
11624 ;; zero don't affect the flags. We assume that shifts by constant
11625 ;; zero are optimized away.
11626 (define_insn "*ashrsi3_cmp"
11629 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11630 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11632 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11633 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11634 "ix86_match_ccmode (insn, CCGOCmode)
11635 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11636 "sar{l}\t{%2, %0|%0, %2}"
11637 [(set_attr "type" "ishift")
11638 (set_attr "mode" "SI")])
11640 (define_insn "*ashrsi3_cmp_zext"
11643 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11644 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11646 (set (match_operand:DI 0 "register_operand" "=r")
11647 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11648 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11649 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11650 "sar{l}\t{%2, %k0|%k0, %2}"
11651 [(set_attr "type" "ishift")
11652 (set_attr "mode" "SI")])
11654 (define_expand "ashrhi3"
11655 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11656 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11657 (match_operand:QI 2 "nonmemory_operand" "")))
11658 (clobber (reg:CC FLAGS_REG))]
11659 "TARGET_HIMODE_MATH"
11660 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11662 (define_insn "*ashrhi3_1_one_bit"
11663 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11664 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11665 (match_operand:QI 2 "const1_operand" "")))
11666 (clobber (reg:CC FLAGS_REG))]
11667 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11668 && (TARGET_SHIFT1 || optimize_size)"
11670 [(set_attr "type" "ishift")
11671 (set (attr "length")
11672 (if_then_else (match_operand 0 "register_operand" "")
11674 (const_string "*")))])
11676 (define_insn "*ashrhi3_1"
11677 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11678 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11679 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11680 (clobber (reg:CC FLAGS_REG))]
11681 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11683 sar{w}\t{%2, %0|%0, %2}
11684 sar{w}\t{%b2, %0|%0, %b2}"
11685 [(set_attr "type" "ishift")
11686 (set_attr "mode" "HI")])
11688 ;; This pattern can't accept a variable shift count, since shifts by
11689 ;; zero don't affect the flags. We assume that shifts by constant
11690 ;; zero are optimized away.
11691 (define_insn "*ashrhi3_one_bit_cmp"
11694 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11695 (match_operand:QI 2 "const1_operand" ""))
11697 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11698 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11699 "ix86_match_ccmode (insn, CCGOCmode)
11700 && (TARGET_SHIFT1 || optimize_size)
11701 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11703 [(set_attr "type" "ishift")
11704 (set (attr "length")
11705 (if_then_else (match_operand 0 "register_operand" "")
11707 (const_string "*")))])
11709 ;; This pattern can't accept a variable shift count, since shifts by
11710 ;; zero don't affect the flags. We assume that shifts by constant
11711 ;; zero are optimized away.
11712 (define_insn "*ashrhi3_cmp"
11715 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11716 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11718 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11719 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11720 "ix86_match_ccmode (insn, CCGOCmode)
11721 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11722 "sar{w}\t{%2, %0|%0, %2}"
11723 [(set_attr "type" "ishift")
11724 (set_attr "mode" "HI")])
11726 (define_expand "ashrqi3"
11727 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11728 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11729 (match_operand:QI 2 "nonmemory_operand" "")))
11730 (clobber (reg:CC FLAGS_REG))]
11731 "TARGET_QIMODE_MATH"
11732 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11734 (define_insn "*ashrqi3_1_one_bit"
11735 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11736 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11737 (match_operand:QI 2 "const1_operand" "")))
11738 (clobber (reg:CC FLAGS_REG))]
11739 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11740 && (TARGET_SHIFT1 || optimize_size)"
11742 [(set_attr "type" "ishift")
11743 (set (attr "length")
11744 (if_then_else (match_operand 0 "register_operand" "")
11746 (const_string "*")))])
11748 (define_insn "*ashrqi3_1_one_bit_slp"
11749 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11750 (ashiftrt:QI (match_dup 0)
11751 (match_operand:QI 1 "const1_operand" "")))
11752 (clobber (reg:CC FLAGS_REG))]
11753 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11754 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11755 && (TARGET_SHIFT1 || optimize_size)"
11757 [(set_attr "type" "ishift1")
11758 (set (attr "length")
11759 (if_then_else (match_operand 0 "register_operand" "")
11761 (const_string "*")))])
11763 (define_insn "*ashrqi3_1"
11764 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11765 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11766 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11767 (clobber (reg:CC FLAGS_REG))]
11768 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11770 sar{b}\t{%2, %0|%0, %2}
11771 sar{b}\t{%b2, %0|%0, %b2}"
11772 [(set_attr "type" "ishift")
11773 (set_attr "mode" "QI")])
11775 (define_insn "*ashrqi3_1_slp"
11776 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11777 (ashiftrt:QI (match_dup 0)
11778 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11779 (clobber (reg:CC FLAGS_REG))]
11780 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11781 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11783 sar{b}\t{%1, %0|%0, %1}
11784 sar{b}\t{%b1, %0|%0, %b1}"
11785 [(set_attr "type" "ishift1")
11786 (set_attr "mode" "QI")])
11788 ;; This pattern can't accept a variable shift count, since shifts by
11789 ;; zero don't affect the flags. We assume that shifts by constant
11790 ;; zero are optimized away.
11791 (define_insn "*ashrqi3_one_bit_cmp"
11794 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11795 (match_operand:QI 2 "const1_operand" "I"))
11797 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11798 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11799 "ix86_match_ccmode (insn, CCGOCmode)
11800 && (TARGET_SHIFT1 || optimize_size)
11801 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11803 [(set_attr "type" "ishift")
11804 (set (attr "length")
11805 (if_then_else (match_operand 0 "register_operand" "")
11807 (const_string "*")))])
11809 ;; This pattern can't accept a variable shift count, since shifts by
11810 ;; zero don't affect the flags. We assume that shifts by constant
11811 ;; zero are optimized away.
11812 (define_insn "*ashrqi3_cmp"
11815 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11816 (match_operand:QI 2 "const_int_1_31_operand" "I"))
11818 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11819 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11820 "ix86_match_ccmode (insn, CCGOCmode)
11821 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11822 "sar{b}\t{%2, %0|%0, %2}"
11823 [(set_attr "type" "ishift")
11824 (set_attr "mode" "QI")])
11826 ;; Logical shift instructions
11828 ;; See comment above `ashldi3' about how this works.
11830 (define_expand "lshrdi3"
11831 [(set (match_operand:DI 0 "shiftdi_operand" "")
11832 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11833 (match_operand:QI 2 "nonmemory_operand" "")))]
11835 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11837 (define_insn "*lshrdi3_1_one_bit_rex64"
11838 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11839 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11840 (match_operand:QI 2 "const1_operand" "")))
11841 (clobber (reg:CC FLAGS_REG))]
11842 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11843 && (TARGET_SHIFT1 || optimize_size)"
11845 [(set_attr "type" "ishift")
11846 (set (attr "length")
11847 (if_then_else (match_operand:DI 0 "register_operand" "")
11849 (const_string "*")))])
11851 (define_insn "*lshrdi3_1_rex64"
11852 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11853 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11854 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11855 (clobber (reg:CC FLAGS_REG))]
11856 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11858 shr{q}\t{%2, %0|%0, %2}
11859 shr{q}\t{%b2, %0|%0, %b2}"
11860 [(set_attr "type" "ishift")
11861 (set_attr "mode" "DI")])
11863 ;; This pattern can't accept a variable shift count, since shifts by
11864 ;; zero don't affect the flags. We assume that shifts by constant
11865 ;; zero are optimized away.
11866 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11869 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11870 (match_operand:QI 2 "const1_operand" ""))
11872 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11873 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11874 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11875 && (TARGET_SHIFT1 || optimize_size)
11876 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11878 [(set_attr "type" "ishift")
11879 (set (attr "length")
11880 (if_then_else (match_operand:DI 0 "register_operand" "")
11882 (const_string "*")))])
11884 ;; This pattern can't accept a variable shift count, since shifts by
11885 ;; zero don't affect the flags. We assume that shifts by constant
11886 ;; zero are optimized away.
11887 (define_insn "*lshrdi3_cmp_rex64"
11890 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11891 (match_operand:QI 2 "const_int_operand" "e"))
11893 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11894 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11895 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11896 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11897 "shr{q}\t{%2, %0|%0, %2}"
11898 [(set_attr "type" "ishift")
11899 (set_attr "mode" "DI")])
11901 (define_insn "*lshrdi3_1"
11902 [(set (match_operand:DI 0 "register_operand" "=r")
11903 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11904 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11905 (clobber (reg:CC FLAGS_REG))]
11908 [(set_attr "type" "multi")])
11910 ;; By default we don't ask for a scratch register, because when DImode
11911 ;; values are manipulated, registers are already at a premium. But if
11912 ;; we have one handy, we won't turn it away.
11914 [(match_scratch:SI 3 "r")
11915 (parallel [(set (match_operand:DI 0 "register_operand" "")
11916 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11917 (match_operand:QI 2 "nonmemory_operand" "")))
11918 (clobber (reg:CC FLAGS_REG))])
11920 "!TARGET_64BIT && TARGET_CMOVE"
11922 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11925 [(set (match_operand:DI 0 "register_operand" "")
11926 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11927 (match_operand:QI 2 "nonmemory_operand" "")))
11928 (clobber (reg:CC FLAGS_REG))]
11929 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11931 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11933 (define_expand "lshrsi3"
11934 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11935 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11936 (match_operand:QI 2 "nonmemory_operand" "")))
11937 (clobber (reg:CC FLAGS_REG))]
11939 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11941 (define_insn "*lshrsi3_1_one_bit"
11942 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11943 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11944 (match_operand:QI 2 "const1_operand" "")))
11945 (clobber (reg:CC FLAGS_REG))]
11946 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11947 && (TARGET_SHIFT1 || optimize_size)"
11949 [(set_attr "type" "ishift")
11950 (set (attr "length")
11951 (if_then_else (match_operand:SI 0 "register_operand" "")
11953 (const_string "*")))])
11955 (define_insn "*lshrsi3_1_one_bit_zext"
11956 [(set (match_operand:DI 0 "register_operand" "=r")
11957 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11958 (match_operand:QI 2 "const1_operand" "")))
11959 (clobber (reg:CC FLAGS_REG))]
11960 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11961 && (TARGET_SHIFT1 || optimize_size)"
11963 [(set_attr "type" "ishift")
11964 (set_attr "length" "2")])
11966 (define_insn "*lshrsi3_1"
11967 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11968 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11969 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11970 (clobber (reg:CC FLAGS_REG))]
11971 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11973 shr{l}\t{%2, %0|%0, %2}
11974 shr{l}\t{%b2, %0|%0, %b2}"
11975 [(set_attr "type" "ishift")
11976 (set_attr "mode" "SI")])
11978 (define_insn "*lshrsi3_1_zext"
11979 [(set (match_operand:DI 0 "register_operand" "=r,r")
11981 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11982 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11983 (clobber (reg:CC FLAGS_REG))]
11984 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11986 shr{l}\t{%2, %k0|%k0, %2}
11987 shr{l}\t{%b2, %k0|%k0, %b2}"
11988 [(set_attr "type" "ishift")
11989 (set_attr "mode" "SI")])
11991 ;; This pattern can't accept a variable shift count, since shifts by
11992 ;; zero don't affect the flags. We assume that shifts by constant
11993 ;; zero are optimized away.
11994 (define_insn "*lshrsi3_one_bit_cmp"
11997 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11998 (match_operand:QI 2 "const1_operand" ""))
12000 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12001 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12002 "ix86_match_ccmode (insn, CCGOCmode)
12003 && (TARGET_SHIFT1 || optimize_size)
12004 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12006 [(set_attr "type" "ishift")
12007 (set (attr "length")
12008 (if_then_else (match_operand:SI 0 "register_operand" "")
12010 (const_string "*")))])
12012 (define_insn "*lshrsi3_cmp_one_bit_zext"
12015 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12016 (match_operand:QI 2 "const1_operand" ""))
12018 (set (match_operand:DI 0 "register_operand" "=r")
12019 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12020 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12021 && (TARGET_SHIFT1 || optimize_size)
12022 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12024 [(set_attr "type" "ishift")
12025 (set_attr "length" "2")])
12027 ;; This pattern can't accept a variable shift count, since shifts by
12028 ;; zero don't affect the flags. We assume that shifts by constant
12029 ;; zero are optimized away.
12030 (define_insn "*lshrsi3_cmp"
12033 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12034 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12036 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12037 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12038 "ix86_match_ccmode (insn, CCGOCmode)
12039 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12040 "shr{l}\t{%2, %0|%0, %2}"
12041 [(set_attr "type" "ishift")
12042 (set_attr "mode" "SI")])
12044 (define_insn "*lshrsi3_cmp_zext"
12047 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12048 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12050 (set (match_operand:DI 0 "register_operand" "=r")
12051 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12052 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12053 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12054 "shr{l}\t{%2, %k0|%k0, %2}"
12055 [(set_attr "type" "ishift")
12056 (set_attr "mode" "SI")])
12058 (define_expand "lshrhi3"
12059 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12060 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12061 (match_operand:QI 2 "nonmemory_operand" "")))
12062 (clobber (reg:CC FLAGS_REG))]
12063 "TARGET_HIMODE_MATH"
12064 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12066 (define_insn "*lshrhi3_1_one_bit"
12067 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12068 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12069 (match_operand:QI 2 "const1_operand" "")))
12070 (clobber (reg:CC FLAGS_REG))]
12071 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12072 && (TARGET_SHIFT1 || optimize_size)"
12074 [(set_attr "type" "ishift")
12075 (set (attr "length")
12076 (if_then_else (match_operand 0 "register_operand" "")
12078 (const_string "*")))])
12080 (define_insn "*lshrhi3_1"
12081 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12082 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12083 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12084 (clobber (reg:CC FLAGS_REG))]
12085 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12087 shr{w}\t{%2, %0|%0, %2}
12088 shr{w}\t{%b2, %0|%0, %b2}"
12089 [(set_attr "type" "ishift")
12090 (set_attr "mode" "HI")])
12092 ;; This pattern can't accept a variable shift count, since shifts by
12093 ;; zero don't affect the flags. We assume that shifts by constant
12094 ;; zero are optimized away.
12095 (define_insn "*lshrhi3_one_bit_cmp"
12098 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12099 (match_operand:QI 2 "const1_operand" ""))
12101 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12102 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12103 "ix86_match_ccmode (insn, CCGOCmode)
12104 && (TARGET_SHIFT1 || optimize_size)
12105 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12107 [(set_attr "type" "ishift")
12108 (set (attr "length")
12109 (if_then_else (match_operand:SI 0 "register_operand" "")
12111 (const_string "*")))])
12113 ;; This pattern can't accept a variable shift count, since shifts by
12114 ;; zero don't affect the flags. We assume that shifts by constant
12115 ;; zero are optimized away.
12116 (define_insn "*lshrhi3_cmp"
12119 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12120 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12122 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12123 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12124 "ix86_match_ccmode (insn, CCGOCmode)
12125 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12126 "shr{w}\t{%2, %0|%0, %2}"
12127 [(set_attr "type" "ishift")
12128 (set_attr "mode" "HI")])
12130 (define_expand "lshrqi3"
12131 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12132 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12133 (match_operand:QI 2 "nonmemory_operand" "")))
12134 (clobber (reg:CC FLAGS_REG))]
12135 "TARGET_QIMODE_MATH"
12136 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12138 (define_insn "*lshrqi3_1_one_bit"
12139 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12140 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12141 (match_operand:QI 2 "const1_operand" "")))
12142 (clobber (reg:CC FLAGS_REG))]
12143 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12144 && (TARGET_SHIFT1 || optimize_size)"
12146 [(set_attr "type" "ishift")
12147 (set (attr "length")
12148 (if_then_else (match_operand 0 "register_operand" "")
12150 (const_string "*")))])
12152 (define_insn "*lshrqi3_1_one_bit_slp"
12153 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12154 (lshiftrt:QI (match_dup 0)
12155 (match_operand:QI 1 "const1_operand" "")))
12156 (clobber (reg:CC FLAGS_REG))]
12157 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12158 && (TARGET_SHIFT1 || optimize_size)"
12160 [(set_attr "type" "ishift1")
12161 (set (attr "length")
12162 (if_then_else (match_operand 0 "register_operand" "")
12164 (const_string "*")))])
12166 (define_insn "*lshrqi3_1"
12167 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12168 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12169 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12170 (clobber (reg:CC FLAGS_REG))]
12171 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12173 shr{b}\t{%2, %0|%0, %2}
12174 shr{b}\t{%b2, %0|%0, %b2}"
12175 [(set_attr "type" "ishift")
12176 (set_attr "mode" "QI")])
12178 (define_insn "*lshrqi3_1_slp"
12179 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12180 (lshiftrt:QI (match_dup 0)
12181 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12182 (clobber (reg:CC FLAGS_REG))]
12183 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12184 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12186 shr{b}\t{%1, %0|%0, %1}
12187 shr{b}\t{%b1, %0|%0, %b1}"
12188 [(set_attr "type" "ishift1")
12189 (set_attr "mode" "QI")])
12191 ;; This pattern can't accept a variable shift count, since shifts by
12192 ;; zero don't affect the flags. We assume that shifts by constant
12193 ;; zero are optimized away.
12194 (define_insn "*lshrqi2_one_bit_cmp"
12197 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12198 (match_operand:QI 2 "const1_operand" ""))
12200 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12201 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12202 "ix86_match_ccmode (insn, CCGOCmode)
12203 && (TARGET_SHIFT1 || optimize_size)
12204 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12206 [(set_attr "type" "ishift")
12207 (set (attr "length")
12208 (if_then_else (match_operand:SI 0 "register_operand" "")
12210 (const_string "*")))])
12212 ;; This pattern can't accept a variable shift count, since shifts by
12213 ;; zero don't affect the flags. We assume that shifts by constant
12214 ;; zero are optimized away.
12215 (define_insn "*lshrqi2_cmp"
12218 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12219 (match_operand:QI 2 "const_int_1_31_operand" "I"))
12221 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12222 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12223 "ix86_match_ccmode (insn, CCGOCmode)
12224 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12225 "shr{b}\t{%2, %0|%0, %2}"
12226 [(set_attr "type" "ishift")
12227 (set_attr "mode" "QI")])
12229 ;; Rotate instructions
12231 (define_expand "rotldi3"
12232 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12233 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12234 (match_operand:QI 2 "nonmemory_operand" "")))
12235 (clobber (reg:CC FLAGS_REG))]
12237 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12239 (define_insn "*rotlsi3_1_one_bit_rex64"
12240 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12241 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12242 (match_operand:QI 2 "const1_operand" "")))
12243 (clobber (reg:CC FLAGS_REG))]
12244 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12245 && (TARGET_SHIFT1 || optimize_size)"
12247 [(set_attr "type" "rotate")
12248 (set (attr "length")
12249 (if_then_else (match_operand:DI 0 "register_operand" "")
12251 (const_string "*")))])
12253 (define_insn "*rotldi3_1_rex64"
12254 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12255 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12256 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12257 (clobber (reg:CC FLAGS_REG))]
12258 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12260 rol{q}\t{%2, %0|%0, %2}
12261 rol{q}\t{%b2, %0|%0, %b2}"
12262 [(set_attr "type" "rotate")
12263 (set_attr "mode" "DI")])
12265 (define_expand "rotlsi3"
12266 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12267 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12268 (match_operand:QI 2 "nonmemory_operand" "")))
12269 (clobber (reg:CC FLAGS_REG))]
12271 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12273 (define_insn "*rotlsi3_1_one_bit"
12274 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12275 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12276 (match_operand:QI 2 "const1_operand" "")))
12277 (clobber (reg:CC FLAGS_REG))]
12278 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12279 && (TARGET_SHIFT1 || optimize_size)"
12281 [(set_attr "type" "rotate")
12282 (set (attr "length")
12283 (if_then_else (match_operand:SI 0 "register_operand" "")
12285 (const_string "*")))])
12287 (define_insn "*rotlsi3_1_one_bit_zext"
12288 [(set (match_operand:DI 0 "register_operand" "=r")
12290 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12291 (match_operand:QI 2 "const1_operand" ""))))
12292 (clobber (reg:CC FLAGS_REG))]
12293 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12294 && (TARGET_SHIFT1 || optimize_size)"
12296 [(set_attr "type" "rotate")
12297 (set_attr "length" "2")])
12299 (define_insn "*rotlsi3_1"
12300 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12301 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12302 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12303 (clobber (reg:CC FLAGS_REG))]
12304 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12306 rol{l}\t{%2, %0|%0, %2}
12307 rol{l}\t{%b2, %0|%0, %b2}"
12308 [(set_attr "type" "rotate")
12309 (set_attr "mode" "SI")])
12311 (define_insn "*rotlsi3_1_zext"
12312 [(set (match_operand:DI 0 "register_operand" "=r,r")
12314 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12315 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12316 (clobber (reg:CC FLAGS_REG))]
12317 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12319 rol{l}\t{%2, %k0|%k0, %2}
12320 rol{l}\t{%b2, %k0|%k0, %b2}"
12321 [(set_attr "type" "rotate")
12322 (set_attr "mode" "SI")])
12324 (define_expand "rotlhi3"
12325 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12326 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12327 (match_operand:QI 2 "nonmemory_operand" "")))
12328 (clobber (reg:CC FLAGS_REG))]
12329 "TARGET_HIMODE_MATH"
12330 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12332 (define_insn "*rotlhi3_1_one_bit"
12333 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12334 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12335 (match_operand:QI 2 "const1_operand" "")))
12336 (clobber (reg:CC FLAGS_REG))]
12337 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12338 && (TARGET_SHIFT1 || optimize_size)"
12340 [(set_attr "type" "rotate")
12341 (set (attr "length")
12342 (if_then_else (match_operand 0 "register_operand" "")
12344 (const_string "*")))])
12346 (define_insn "*rotlhi3_1"
12347 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12348 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12349 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12350 (clobber (reg:CC FLAGS_REG))]
12351 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12353 rol{w}\t{%2, %0|%0, %2}
12354 rol{w}\t{%b2, %0|%0, %b2}"
12355 [(set_attr "type" "rotate")
12356 (set_attr "mode" "HI")])
12358 (define_expand "rotlqi3"
12359 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12360 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12361 (match_operand:QI 2 "nonmemory_operand" "")))
12362 (clobber (reg:CC FLAGS_REG))]
12363 "TARGET_QIMODE_MATH"
12364 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12366 (define_insn "*rotlqi3_1_one_bit_slp"
12367 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12368 (rotate:QI (match_dup 0)
12369 (match_operand:QI 1 "const1_operand" "")))
12370 (clobber (reg:CC FLAGS_REG))]
12371 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12372 && (TARGET_SHIFT1 || optimize_size)"
12374 [(set_attr "type" "rotate1")
12375 (set (attr "length")
12376 (if_then_else (match_operand 0 "register_operand" "")
12378 (const_string "*")))])
12380 (define_insn "*rotlqi3_1_one_bit"
12381 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12382 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12383 (match_operand:QI 2 "const1_operand" "")))
12384 (clobber (reg:CC FLAGS_REG))]
12385 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12386 && (TARGET_SHIFT1 || optimize_size)"
12388 [(set_attr "type" "rotate")
12389 (set (attr "length")
12390 (if_then_else (match_operand 0 "register_operand" "")
12392 (const_string "*")))])
12394 (define_insn "*rotlqi3_1_slp"
12395 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12396 (rotate:QI (match_dup 0)
12397 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12398 (clobber (reg:CC FLAGS_REG))]
12399 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12400 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12402 rol{b}\t{%1, %0|%0, %1}
12403 rol{b}\t{%b1, %0|%0, %b1}"
12404 [(set_attr "type" "rotate1")
12405 (set_attr "mode" "QI")])
12407 (define_insn "*rotlqi3_1"
12408 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12409 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12410 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12411 (clobber (reg:CC FLAGS_REG))]
12412 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12414 rol{b}\t{%2, %0|%0, %2}
12415 rol{b}\t{%b2, %0|%0, %b2}"
12416 [(set_attr "type" "rotate")
12417 (set_attr "mode" "QI")])
12419 (define_expand "rotrdi3"
12420 [(set (match_operand:DI 0 "nonimmediate_operand" "")
12421 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12422 (match_operand:QI 2 "nonmemory_operand" "")))
12423 (clobber (reg:CC FLAGS_REG))]
12425 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12427 (define_insn "*rotrdi3_1_one_bit_rex64"
12428 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12429 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12430 (match_operand:QI 2 "const1_operand" "")))
12431 (clobber (reg:CC FLAGS_REG))]
12432 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12433 && (TARGET_SHIFT1 || optimize_size)"
12435 [(set_attr "type" "rotate")
12436 (set (attr "length")
12437 (if_then_else (match_operand:DI 0 "register_operand" "")
12439 (const_string "*")))])
12441 (define_insn "*rotrdi3_1_rex64"
12442 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12443 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12444 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12445 (clobber (reg:CC FLAGS_REG))]
12446 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12448 ror{q}\t{%2, %0|%0, %2}
12449 ror{q}\t{%b2, %0|%0, %b2}"
12450 [(set_attr "type" "rotate")
12451 (set_attr "mode" "DI")])
12453 (define_expand "rotrsi3"
12454 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12455 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12456 (match_operand:QI 2 "nonmemory_operand" "")))
12457 (clobber (reg:CC FLAGS_REG))]
12459 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12461 (define_insn "*rotrsi3_1_one_bit"
12462 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12463 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12464 (match_operand:QI 2 "const1_operand" "")))
12465 (clobber (reg:CC FLAGS_REG))]
12466 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12467 && (TARGET_SHIFT1 || optimize_size)"
12469 [(set_attr "type" "rotate")
12470 (set (attr "length")
12471 (if_then_else (match_operand:SI 0 "register_operand" "")
12473 (const_string "*")))])
12475 (define_insn "*rotrsi3_1_one_bit_zext"
12476 [(set (match_operand:DI 0 "register_operand" "=r")
12478 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12479 (match_operand:QI 2 "const1_operand" ""))))
12480 (clobber (reg:CC FLAGS_REG))]
12481 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12482 && (TARGET_SHIFT1 || optimize_size)"
12484 [(set_attr "type" "rotate")
12485 (set (attr "length")
12486 (if_then_else (match_operand:SI 0 "register_operand" "")
12488 (const_string "*")))])
12490 (define_insn "*rotrsi3_1"
12491 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12492 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12493 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12494 (clobber (reg:CC FLAGS_REG))]
12495 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12497 ror{l}\t{%2, %0|%0, %2}
12498 ror{l}\t{%b2, %0|%0, %b2}"
12499 [(set_attr "type" "rotate")
12500 (set_attr "mode" "SI")])
12502 (define_insn "*rotrsi3_1_zext"
12503 [(set (match_operand:DI 0 "register_operand" "=r,r")
12505 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12506 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12507 (clobber (reg:CC FLAGS_REG))]
12508 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12510 ror{l}\t{%2, %k0|%k0, %2}
12511 ror{l}\t{%b2, %k0|%k0, %b2}"
12512 [(set_attr "type" "rotate")
12513 (set_attr "mode" "SI")])
12515 (define_expand "rotrhi3"
12516 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12517 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12518 (match_operand:QI 2 "nonmemory_operand" "")))
12519 (clobber (reg:CC FLAGS_REG))]
12520 "TARGET_HIMODE_MATH"
12521 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12523 (define_insn "*rotrhi3_one_bit"
12524 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12525 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12526 (match_operand:QI 2 "const1_operand" "")))
12527 (clobber (reg:CC FLAGS_REG))]
12528 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12529 && (TARGET_SHIFT1 || optimize_size)"
12531 [(set_attr "type" "rotate")
12532 (set (attr "length")
12533 (if_then_else (match_operand 0 "register_operand" "")
12535 (const_string "*")))])
12537 (define_insn "*rotrhi3"
12538 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12539 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12540 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12541 (clobber (reg:CC FLAGS_REG))]
12542 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12544 ror{w}\t{%2, %0|%0, %2}
12545 ror{w}\t{%b2, %0|%0, %b2}"
12546 [(set_attr "type" "rotate")
12547 (set_attr "mode" "HI")])
12549 (define_expand "rotrqi3"
12550 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12551 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12552 (match_operand:QI 2 "nonmemory_operand" "")))
12553 (clobber (reg:CC FLAGS_REG))]
12554 "TARGET_QIMODE_MATH"
12555 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12557 (define_insn "*rotrqi3_1_one_bit"
12558 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12559 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12560 (match_operand:QI 2 "const1_operand" "")))
12561 (clobber (reg:CC FLAGS_REG))]
12562 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12563 && (TARGET_SHIFT1 || optimize_size)"
12565 [(set_attr "type" "rotate")
12566 (set (attr "length")
12567 (if_then_else (match_operand 0 "register_operand" "")
12569 (const_string "*")))])
12571 (define_insn "*rotrqi3_1_one_bit_slp"
12572 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12573 (rotatert:QI (match_dup 0)
12574 (match_operand:QI 1 "const1_operand" "")))
12575 (clobber (reg:CC FLAGS_REG))]
12576 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12577 && (TARGET_SHIFT1 || optimize_size)"
12579 [(set_attr "type" "rotate1")
12580 (set (attr "length")
12581 (if_then_else (match_operand 0 "register_operand" "")
12583 (const_string "*")))])
12585 (define_insn "*rotrqi3_1"
12586 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12587 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12588 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12589 (clobber (reg:CC FLAGS_REG))]
12590 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12592 ror{b}\t{%2, %0|%0, %2}
12593 ror{b}\t{%b2, %0|%0, %b2}"
12594 [(set_attr "type" "rotate")
12595 (set_attr "mode" "QI")])
12597 (define_insn "*rotrqi3_1_slp"
12598 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12599 (rotatert:QI (match_dup 0)
12600 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12601 (clobber (reg:CC FLAGS_REG))]
12602 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12603 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12605 ror{b}\t{%1, %0|%0, %1}
12606 ror{b}\t{%b1, %0|%0, %b1}"
12607 [(set_attr "type" "rotate1")
12608 (set_attr "mode" "QI")])
12610 ;; Bit set / bit test instructions
12612 (define_expand "extv"
12613 [(set (match_operand:SI 0 "register_operand" "")
12614 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12615 (match_operand:SI 2 "immediate_operand" "")
12616 (match_operand:SI 3 "immediate_operand" "")))]
12619 /* Handle extractions from %ah et al. */
12620 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12623 /* From mips.md: extract_bit_field doesn't verify that our source
12624 matches the predicate, so check it again here. */
12625 if (! register_operand (operands[1], VOIDmode))
12629 (define_expand "extzv"
12630 [(set (match_operand:SI 0 "register_operand" "")
12631 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12632 (match_operand:SI 2 "immediate_operand" "")
12633 (match_operand:SI 3 "immediate_operand" "")))]
12636 /* Handle extractions from %ah et al. */
12637 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12640 /* From mips.md: extract_bit_field doesn't verify that our source
12641 matches the predicate, so check it again here. */
12642 if (! register_operand (operands[1], VOIDmode))
12646 (define_expand "insv"
12647 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12648 (match_operand 1 "immediate_operand" "")
12649 (match_operand 2 "immediate_operand" ""))
12650 (match_operand 3 "register_operand" ""))]
12653 /* Handle extractions from %ah et al. */
12654 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12657 /* From mips.md: insert_bit_field doesn't verify that our source
12658 matches the predicate, so check it again here. */
12659 if (! register_operand (operands[0], VOIDmode))
12663 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12665 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12670 ;; %%% bts, btr, btc, bt.
12672 ;; Store-flag instructions.
12674 ;; For all sCOND expanders, also expand the compare or test insn that
12675 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12677 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12678 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12679 ;; way, which can later delete the movzx if only QImode is needed.
12681 (define_expand "seq"
12682 [(set (match_operand:QI 0 "register_operand" "")
12683 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12685 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12687 (define_expand "sne"
12688 [(set (match_operand:QI 0 "register_operand" "")
12689 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12691 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12693 (define_expand "sgt"
12694 [(set (match_operand:QI 0 "register_operand" "")
12695 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12697 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12699 (define_expand "sgtu"
12700 [(set (match_operand:QI 0 "register_operand" "")
12701 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12703 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12705 (define_expand "slt"
12706 [(set (match_operand:QI 0 "register_operand" "")
12707 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12709 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12711 (define_expand "sltu"
12712 [(set (match_operand:QI 0 "register_operand" "")
12713 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12715 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12717 (define_expand "sge"
12718 [(set (match_operand:QI 0 "register_operand" "")
12719 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12721 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12723 (define_expand "sgeu"
12724 [(set (match_operand:QI 0 "register_operand" "")
12725 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12727 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12729 (define_expand "sle"
12730 [(set (match_operand:QI 0 "register_operand" "")
12731 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12733 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12735 (define_expand "sleu"
12736 [(set (match_operand:QI 0 "register_operand" "")
12737 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12739 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12741 (define_expand "sunordered"
12742 [(set (match_operand:QI 0 "register_operand" "")
12743 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744 "TARGET_80387 || TARGET_SSE"
12745 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12747 (define_expand "sordered"
12748 [(set (match_operand:QI 0 "register_operand" "")
12749 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12751 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12753 (define_expand "suneq"
12754 [(set (match_operand:QI 0 "register_operand" "")
12755 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756 "TARGET_80387 || TARGET_SSE"
12757 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12759 (define_expand "sunge"
12760 [(set (match_operand:QI 0 "register_operand" "")
12761 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762 "TARGET_80387 || TARGET_SSE"
12763 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12765 (define_expand "sungt"
12766 [(set (match_operand:QI 0 "register_operand" "")
12767 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768 "TARGET_80387 || TARGET_SSE"
12769 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12771 (define_expand "sunle"
12772 [(set (match_operand:QI 0 "register_operand" "")
12773 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774 "TARGET_80387 || TARGET_SSE"
12775 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12777 (define_expand "sunlt"
12778 [(set (match_operand:QI 0 "register_operand" "")
12779 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12780 "TARGET_80387 || TARGET_SSE"
12781 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12783 (define_expand "sltgt"
12784 [(set (match_operand:QI 0 "register_operand" "")
12785 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12786 "TARGET_80387 || TARGET_SSE"
12787 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12789 (define_insn "*setcc_1"
12790 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12791 (match_operator:QI 1 "ix86_comparison_operator"
12792 [(reg 17) (const_int 0)]))]
12795 [(set_attr "type" "setcc")
12796 (set_attr "mode" "QI")])
12798 (define_insn "*setcc_2"
12799 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12800 (match_operator:QI 1 "ix86_comparison_operator"
12801 [(reg 17) (const_int 0)]))]
12804 [(set_attr "type" "setcc")
12805 (set_attr "mode" "QI")])
12807 ;; In general it is not safe to assume too much about CCmode registers,
12808 ;; so simplify-rtx stops when it sees a second one. Under certain
12809 ;; conditions this is safe on x86, so help combine not create
12816 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12817 (ne:QI (match_operator 1 "ix86_comparison_operator"
12818 [(reg 17) (const_int 0)])
12821 [(set (match_dup 0) (match_dup 1))]
12823 PUT_MODE (operands[1], QImode);
12827 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12828 (ne:QI (match_operator 1 "ix86_comparison_operator"
12829 [(reg 17) (const_int 0)])
12832 [(set (match_dup 0) (match_dup 1))]
12834 PUT_MODE (operands[1], QImode);
12838 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12839 (eq:QI (match_operator 1 "ix86_comparison_operator"
12840 [(reg 17) (const_int 0)])
12843 [(set (match_dup 0) (match_dup 1))]
12845 rtx new_op1 = copy_rtx (operands[1]);
12846 operands[1] = new_op1;
12847 PUT_MODE (new_op1, QImode);
12848 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12849 GET_MODE (XEXP (new_op1, 0))));
12851 /* Make sure that (a) the CCmode we have for the flags is strong
12852 enough for the reversed compare or (b) we have a valid FP compare. */
12853 if (! ix86_comparison_operator (new_op1, VOIDmode))
12858 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12859 (eq:QI (match_operator 1 "ix86_comparison_operator"
12860 [(reg 17) (const_int 0)])
12863 [(set (match_dup 0) (match_dup 1))]
12865 rtx new_op1 = copy_rtx (operands[1]);
12866 operands[1] = new_op1;
12867 PUT_MODE (new_op1, QImode);
12868 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12869 GET_MODE (XEXP (new_op1, 0))));
12871 /* Make sure that (a) the CCmode we have for the flags is strong
12872 enough for the reversed compare or (b) we have a valid FP compare. */
12873 if (! ix86_comparison_operator (new_op1, VOIDmode))
12877 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12878 ;; subsequent logical operations are used to imitate conditional moves.
12879 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12880 ;; it directly. Further holding this value in pseudo register might bring
12881 ;; problem in implicit normalization in spill code.
12882 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
12883 ;; instructions after reload by splitting the conditional move patterns.
12885 (define_insn "*sse_setccsf"
12886 [(set (match_operand:SF 0 "register_operand" "=x")
12887 (match_operator:SF 1 "sse_comparison_operator"
12888 [(match_operand:SF 2 "register_operand" "0")
12889 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12890 "TARGET_SSE && reload_completed"
12891 "cmp%D1ss\t{%3, %0|%0, %3}"
12892 [(set_attr "type" "ssecmp")
12893 (set_attr "mode" "SF")])
12895 (define_insn "*sse_setccdf"
12896 [(set (match_operand:DF 0 "register_operand" "=Y")
12897 (match_operator:DF 1 "sse_comparison_operator"
12898 [(match_operand:DF 2 "register_operand" "0")
12899 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12900 "TARGET_SSE2 && reload_completed"
12901 "cmp%D1sd\t{%3, %0|%0, %3}"
12902 [(set_attr "type" "ssecmp")
12903 (set_attr "mode" "DF")])
12905 ;; Basic conditional jump instructions.
12906 ;; We ignore the overflow flag for signed branch instructions.
12908 ;; For all bCOND expanders, also expand the compare or test insn that
12909 ;; generates reg 17. Generate an equality comparison if `beq' or `bne'.
12911 (define_expand "beq"
12913 (if_then_else (match_dup 1)
12914 (label_ref (match_operand 0 "" ""))
12917 "ix86_expand_branch (EQ, operands[0]); DONE;")
12919 (define_expand "bne"
12921 (if_then_else (match_dup 1)
12922 (label_ref (match_operand 0 "" ""))
12925 "ix86_expand_branch (NE, operands[0]); DONE;")
12927 (define_expand "bgt"
12929 (if_then_else (match_dup 1)
12930 (label_ref (match_operand 0 "" ""))
12933 "ix86_expand_branch (GT, operands[0]); DONE;")
12935 (define_expand "bgtu"
12937 (if_then_else (match_dup 1)
12938 (label_ref (match_operand 0 "" ""))
12941 "ix86_expand_branch (GTU, operands[0]); DONE;")
12943 (define_expand "blt"
12945 (if_then_else (match_dup 1)
12946 (label_ref (match_operand 0 "" ""))
12949 "ix86_expand_branch (LT, operands[0]); DONE;")
12951 (define_expand "bltu"
12953 (if_then_else (match_dup 1)
12954 (label_ref (match_operand 0 "" ""))
12957 "ix86_expand_branch (LTU, operands[0]); DONE;")
12959 (define_expand "bge"
12961 (if_then_else (match_dup 1)
12962 (label_ref (match_operand 0 "" ""))
12965 "ix86_expand_branch (GE, operands[0]); DONE;")
12967 (define_expand "bgeu"
12969 (if_then_else (match_dup 1)
12970 (label_ref (match_operand 0 "" ""))
12973 "ix86_expand_branch (GEU, operands[0]); DONE;")
12975 (define_expand "ble"
12977 (if_then_else (match_dup 1)
12978 (label_ref (match_operand 0 "" ""))
12981 "ix86_expand_branch (LE, operands[0]); DONE;")
12983 (define_expand "bleu"
12985 (if_then_else (match_dup 1)
12986 (label_ref (match_operand 0 "" ""))
12989 "ix86_expand_branch (LEU, operands[0]); DONE;")
12991 (define_expand "bunordered"
12993 (if_then_else (match_dup 1)
12994 (label_ref (match_operand 0 "" ""))
12996 "TARGET_80387 || TARGET_SSE"
12997 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12999 (define_expand "bordered"
13001 (if_then_else (match_dup 1)
13002 (label_ref (match_operand 0 "" ""))
13004 "TARGET_80387 || TARGET_SSE"
13005 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13007 (define_expand "buneq"
13009 (if_then_else (match_dup 1)
13010 (label_ref (match_operand 0 "" ""))
13012 "TARGET_80387 || TARGET_SSE"
13013 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13015 (define_expand "bunge"
13017 (if_then_else (match_dup 1)
13018 (label_ref (match_operand 0 "" ""))
13020 "TARGET_80387 || TARGET_SSE"
13021 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13023 (define_expand "bungt"
13025 (if_then_else (match_dup 1)
13026 (label_ref (match_operand 0 "" ""))
13028 "TARGET_80387 || TARGET_SSE"
13029 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13031 (define_expand "bunle"
13033 (if_then_else (match_dup 1)
13034 (label_ref (match_operand 0 "" ""))
13036 "TARGET_80387 || TARGET_SSE"
13037 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13039 (define_expand "bunlt"
13041 (if_then_else (match_dup 1)
13042 (label_ref (match_operand 0 "" ""))
13044 "TARGET_80387 || TARGET_SSE"
13045 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13047 (define_expand "bltgt"
13049 (if_then_else (match_dup 1)
13050 (label_ref (match_operand 0 "" ""))
13052 "TARGET_80387 || TARGET_SSE"
13053 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13055 (define_insn "*jcc_1"
13057 (if_then_else (match_operator 1 "ix86_comparison_operator"
13058 [(reg 17) (const_int 0)])
13059 (label_ref (match_operand 0 "" ""))
13063 [(set_attr "type" "ibr")
13064 (set_attr "modrm" "0")
13065 (set (attr "length")
13066 (if_then_else (and (ge (minus (match_dup 0) (pc))
13068 (lt (minus (match_dup 0) (pc))
13073 (define_insn "*jcc_2"
13075 (if_then_else (match_operator 1 "ix86_comparison_operator"
13076 [(reg 17) (const_int 0)])
13078 (label_ref (match_operand 0 "" ""))))]
13081 [(set_attr "type" "ibr")
13082 (set_attr "modrm" "0")
13083 (set (attr "length")
13084 (if_then_else (and (ge (minus (match_dup 0) (pc))
13086 (lt (minus (match_dup 0) (pc))
13091 ;; In general it is not safe to assume too much about CCmode registers,
13092 ;; so simplify-rtx stops when it sees a second one. Under certain
13093 ;; conditions this is safe on x86, so help combine not create
13101 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13102 [(reg 17) (const_int 0)])
13104 (label_ref (match_operand 1 "" ""))
13108 (if_then_else (match_dup 0)
13109 (label_ref (match_dup 1))
13112 PUT_MODE (operands[0], VOIDmode);
13117 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13118 [(reg 17) (const_int 0)])
13120 (label_ref (match_operand 1 "" ""))
13124 (if_then_else (match_dup 0)
13125 (label_ref (match_dup 1))
13128 rtx new_op0 = copy_rtx (operands[0]);
13129 operands[0] = new_op0;
13130 PUT_MODE (new_op0, VOIDmode);
13131 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13132 GET_MODE (XEXP (new_op0, 0))));
13134 /* Make sure that (a) the CCmode we have for the flags is strong
13135 enough for the reversed compare or (b) we have a valid FP compare. */
13136 if (! ix86_comparison_operator (new_op0, VOIDmode))
13140 ;; Define combination compare-and-branch fp compare instructions to use
13141 ;; during early optimization. Splitting the operation apart early makes
13142 ;; for bad code when we want to reverse the operation.
13144 (define_insn "*fp_jcc_1"
13146 (if_then_else (match_operator 0 "comparison_operator"
13147 [(match_operand 1 "register_operand" "f")
13148 (match_operand 2 "register_operand" "f")])
13149 (label_ref (match_operand 3 "" ""))
13151 (clobber (reg:CCFP FPSR_REG))
13152 (clobber (reg:CCFP FLAGS_REG))]
13153 "TARGET_CMOVE && TARGET_80387
13154 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13155 && FLOAT_MODE_P (GET_MODE (operands[1]))
13156 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13157 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13160 (define_insn "*fp_jcc_1_sse"
13162 (if_then_else (match_operator 0 "comparison_operator"
13163 [(match_operand 1 "register_operand" "f#x,x#f")
13164 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13165 (label_ref (match_operand 3 "" ""))
13167 (clobber (reg:CCFP FPSR_REG))
13168 (clobber (reg:CCFP FLAGS_REG))]
13170 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13171 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13172 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13175 (define_insn "*fp_jcc_1_sse_only"
13177 (if_then_else (match_operator 0 "comparison_operator"
13178 [(match_operand 1 "register_operand" "x")
13179 (match_operand 2 "nonimmediate_operand" "xm")])
13180 (label_ref (match_operand 3 "" ""))
13182 (clobber (reg:CCFP FPSR_REG))
13183 (clobber (reg:CCFP FLAGS_REG))]
13184 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13185 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13186 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13189 (define_insn "*fp_jcc_2"
13191 (if_then_else (match_operator 0 "comparison_operator"
13192 [(match_operand 1 "register_operand" "f")
13193 (match_operand 2 "register_operand" "f")])
13195 (label_ref (match_operand 3 "" ""))))
13196 (clobber (reg:CCFP FPSR_REG))
13197 (clobber (reg:CCFP FLAGS_REG))]
13198 "TARGET_CMOVE && TARGET_80387
13199 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13200 && FLOAT_MODE_P (GET_MODE (operands[1]))
13201 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13202 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13205 (define_insn "*fp_jcc_2_sse"
13207 (if_then_else (match_operator 0 "comparison_operator"
13208 [(match_operand 1 "register_operand" "f#x,x#f")
13209 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13211 (label_ref (match_operand 3 "" ""))))
13212 (clobber (reg:CCFP FPSR_REG))
13213 (clobber (reg:CCFP FLAGS_REG))]
13215 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13216 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13217 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13220 (define_insn "*fp_jcc_2_sse_only"
13222 (if_then_else (match_operator 0 "comparison_operator"
13223 [(match_operand 1 "register_operand" "x")
13224 (match_operand 2 "nonimmediate_operand" "xm")])
13226 (label_ref (match_operand 3 "" ""))))
13227 (clobber (reg:CCFP FPSR_REG))
13228 (clobber (reg:CCFP FLAGS_REG))]
13229 "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13230 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13231 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13234 (define_insn "*fp_jcc_3"
13236 (if_then_else (match_operator 0 "comparison_operator"
13237 [(match_operand 1 "register_operand" "f")
13238 (match_operand 2 "nonimmediate_operand" "fm")])
13239 (label_ref (match_operand 3 "" ""))
13241 (clobber (reg:CCFP FPSR_REG))
13242 (clobber (reg:CCFP FLAGS_REG))
13243 (clobber (match_scratch:HI 4 "=a"))]
13245 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13246 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13247 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13248 && SELECT_CC_MODE (GET_CODE (operands[0]),
13249 operands[1], operands[2]) == CCFPmode
13250 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13253 (define_insn "*fp_jcc_4"
13255 (if_then_else (match_operator 0 "comparison_operator"
13256 [(match_operand 1 "register_operand" "f")
13257 (match_operand 2 "nonimmediate_operand" "fm")])
13259 (label_ref (match_operand 3 "" ""))))
13260 (clobber (reg:CCFP FPSR_REG))
13261 (clobber (reg:CCFP FLAGS_REG))
13262 (clobber (match_scratch:HI 4 "=a"))]
13264 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13265 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13266 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13267 && SELECT_CC_MODE (GET_CODE (operands[0]),
13268 operands[1], operands[2]) == CCFPmode
13269 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13272 (define_insn "*fp_jcc_5"
13274 (if_then_else (match_operator 0 "comparison_operator"
13275 [(match_operand 1 "register_operand" "f")
13276 (match_operand 2 "register_operand" "f")])
13277 (label_ref (match_operand 3 "" ""))
13279 (clobber (reg:CCFP FPSR_REG))
13280 (clobber (reg:CCFP FLAGS_REG))
13281 (clobber (match_scratch:HI 4 "=a"))]
13283 && FLOAT_MODE_P (GET_MODE (operands[1]))
13284 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13285 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13288 (define_insn "*fp_jcc_6"
13290 (if_then_else (match_operator 0 "comparison_operator"
13291 [(match_operand 1 "register_operand" "f")
13292 (match_operand 2 "register_operand" "f")])
13294 (label_ref (match_operand 3 "" ""))))
13295 (clobber (reg:CCFP FPSR_REG))
13296 (clobber (reg:CCFP FLAGS_REG))
13297 (clobber (match_scratch:HI 4 "=a"))]
13299 && FLOAT_MODE_P (GET_MODE (operands[1]))
13300 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13301 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13304 (define_insn "*fp_jcc_7"
13306 (if_then_else (match_operator 0 "comparison_operator"
13307 [(match_operand 1 "register_operand" "f")
13308 (match_operand 2 "const_double_operand" "C")])
13309 (label_ref (match_operand 3 "" ""))
13311 (clobber (reg:CCFP FPSR_REG))
13312 (clobber (reg:CCFP FLAGS_REG))
13313 (clobber (match_scratch:HI 4 "=a"))]
13315 && FLOAT_MODE_P (GET_MODE (operands[1]))
13316 && operands[2] == CONST0_RTX (GET_MODE (operands[1]))
13317 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13318 && SELECT_CC_MODE (GET_CODE (operands[0]),
13319 operands[1], operands[2]) == CCFPmode
13320 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13325 (if_then_else (match_operator 0 "comparison_operator"
13326 [(match_operand 1 "register_operand" "")
13327 (match_operand 2 "nonimmediate_operand" "")])
13328 (match_operand 3 "" "")
13329 (match_operand 4 "" "")))
13330 (clobber (reg:CCFP FPSR_REG))
13331 (clobber (reg:CCFP FLAGS_REG))]
13335 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13336 operands[3], operands[4], NULL_RTX);
13342 (if_then_else (match_operator 0 "comparison_operator"
13343 [(match_operand 1 "register_operand" "")
13344 (match_operand 2 "general_operand" "")])
13345 (match_operand 3 "" "")
13346 (match_operand 4 "" "")))
13347 (clobber (reg:CCFP FPSR_REG))
13348 (clobber (reg:CCFP FLAGS_REG))
13349 (clobber (match_scratch:HI 5 "=a"))]
13353 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13354 operands[3], operands[4], operands[5]);
13358 ;; Unconditional and other jump instructions
13360 (define_insn "jump"
13362 (label_ref (match_operand 0 "" "")))]
13365 [(set_attr "type" "ibr")
13366 (set (attr "length")
13367 (if_then_else (and (ge (minus (match_dup 0) (pc))
13369 (lt (minus (match_dup 0) (pc))
13373 (set_attr "modrm" "0")])
13375 (define_expand "indirect_jump"
13376 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13380 (define_insn "*indirect_jump"
13381 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13384 [(set_attr "type" "ibr")
13385 (set_attr "length_immediate" "0")])
13387 (define_insn "*indirect_jump_rtx64"
13388 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13391 [(set_attr "type" "ibr")
13392 (set_attr "length_immediate" "0")])
13394 (define_expand "tablejump"
13395 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13396 (use (label_ref (match_operand 1 "" "")))])]
13399 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13400 relative. Convert the relative address to an absolute address. */
13404 enum rtx_code code;
13410 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13412 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13416 op1 = pic_offset_table_rtx;
13421 op0 = pic_offset_table_rtx;
13425 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13430 (define_insn "*tablejump_1"
13431 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13432 (use (label_ref (match_operand 1 "" "")))]
13435 [(set_attr "type" "ibr")
13436 (set_attr "length_immediate" "0")])
13438 (define_insn "*tablejump_1_rtx64"
13439 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13440 (use (label_ref (match_operand 1 "" "")))]
13443 [(set_attr "type" "ibr")
13444 (set_attr "length_immediate" "0")])
13446 ;; Loop instruction
13448 ;; This is all complicated by the fact that since this is a jump insn
13449 ;; we must handle our own reloads.
13451 (define_expand "doloop_end"
13452 [(use (match_operand 0 "" "")) ; loop pseudo
13453 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13454 (use (match_operand 2 "" "")) ; max iterations
13455 (use (match_operand 3 "" "")) ; loop level
13456 (use (match_operand 4 "" ""))] ; label
13457 "!TARGET_64BIT && TARGET_USE_LOOP"
13460 /* Only use cloop on innermost loops. */
13461 if (INTVAL (operands[3]) > 1)
13463 if (GET_MODE (operands[0]) != SImode)
13465 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13470 (define_insn "doloop_end_internal"
13472 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13474 (label_ref (match_operand 0 "" ""))
13476 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13477 (plus:SI (match_dup 1)
13479 (clobber (match_scratch:SI 3 "=X,X,r"))
13480 (clobber (reg:CC FLAGS_REG))]
13481 "!TARGET_64BIT && TARGET_USE_LOOP
13482 && (reload_in_progress || reload_completed
13483 || register_operand (operands[2], VOIDmode))"
13485 if (which_alternative != 0)
13487 if (get_attr_length (insn) == 2)
13488 return "%+loop\t%l0";
13490 return "dec{l}\t%1\;%+jne\t%l0";
13492 [(set (attr "length")
13493 (if_then_else (and (eq_attr "alternative" "0")
13494 (and (ge (minus (match_dup 0) (pc))
13496 (lt (minus (match_dup 0) (pc))
13500 ;; We don't know the type before shorten branches. Optimistically expect
13501 ;; the loop instruction to match.
13502 (set (attr "type") (const_string "ibr"))])
13506 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13508 (match_operand 0 "" "")
13511 (plus:SI (match_dup 1)
13513 (clobber (match_scratch:SI 2 ""))
13514 (clobber (reg:CC FLAGS_REG))]
13515 "!TARGET_64BIT && TARGET_USE_LOOP
13516 && reload_completed
13517 && REGNO (operands[1]) != 2"
13518 [(parallel [(set (reg:CCZ FLAGS_REG)
13519 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13521 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13522 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13529 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13531 (match_operand 0 "" "")
13533 (set (match_operand:SI 2 "nonimmediate_operand" "")
13534 (plus:SI (match_dup 1)
13536 (clobber (match_scratch:SI 3 ""))
13537 (clobber (reg:CC FLAGS_REG))]
13538 "!TARGET_64BIT && TARGET_USE_LOOP
13539 && reload_completed
13540 && (! REG_P (operands[2])
13541 || ! rtx_equal_p (operands[1], operands[2]))"
13542 [(set (match_dup 3) (match_dup 1))
13543 (parallel [(set (reg:CCZ FLAGS_REG)
13544 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13546 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13547 (set (match_dup 2) (match_dup 3))
13548 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13553 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13556 [(set (reg 17) (match_operand 0 "" ""))
13557 (set (match_operand:QI 1 "register_operand" "")
13558 (match_operator:QI 2 "ix86_comparison_operator"
13559 [(reg 17) (const_int 0)]))
13560 (set (match_operand 3 "q_regs_operand" "")
13561 (zero_extend (match_dup 1)))]
13562 "(peep2_reg_dead_p (3, operands[1])
13563 || operands_match_p (operands[1], operands[3]))
13564 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13565 [(set (match_dup 4) (match_dup 0))
13566 (set (strict_low_part (match_dup 5))
13569 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13570 operands[5] = gen_lowpart (QImode, operands[3]);
13571 ix86_expand_clear (operands[3]);
13574 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13577 [(set (reg 17) (match_operand 0 "" ""))
13578 (set (match_operand:QI 1 "register_operand" "")
13579 (match_operator:QI 2 "ix86_comparison_operator"
13580 [(reg 17) (const_int 0)]))
13581 (parallel [(set (match_operand 3 "q_regs_operand" "")
13582 (zero_extend (match_dup 1)))
13583 (clobber (reg:CC FLAGS_REG))])]
13584 "(peep2_reg_dead_p (3, operands[1])
13585 || operands_match_p (operands[1], operands[3]))
13586 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13587 [(set (match_dup 4) (match_dup 0))
13588 (set (strict_low_part (match_dup 5))
13591 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13592 operands[5] = gen_lowpart (QImode, operands[3]);
13593 ix86_expand_clear (operands[3]);
13596 ;; Call instructions.
13598 ;; The predicates normally associated with named expanders are not properly
13599 ;; checked for calls. This is a bug in the generic code, but it isn't that
13600 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13602 ;; Call subroutine returning no value.
13604 (define_expand "call_pop"
13605 [(parallel [(call (match_operand:QI 0 "" "")
13606 (match_operand:SI 1 "" ""))
13607 (set (reg:SI SP_REG)
13608 (plus:SI (reg:SI SP_REG)
13609 (match_operand:SI 3 "" "")))])]
13612 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13616 (define_insn "*call_pop_0"
13617 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13618 (match_operand:SI 1 "" ""))
13619 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13620 (match_operand:SI 2 "immediate_operand" "")))]
13623 if (SIBLING_CALL_P (insn))
13626 return "call\t%P0";
13628 [(set_attr "type" "call")])
13630 (define_insn "*call_pop_1"
13631 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13632 (match_operand:SI 1 "" ""))
13633 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13634 (match_operand:SI 2 "immediate_operand" "i")))]
13637 if (constant_call_address_operand (operands[0], Pmode))
13639 if (SIBLING_CALL_P (insn))
13642 return "call\t%P0";
13644 if (SIBLING_CALL_P (insn))
13647 return "call\t%A0";
13649 [(set_attr "type" "call")])
13651 (define_expand "call"
13652 [(call (match_operand:QI 0 "" "")
13653 (match_operand 1 "" ""))
13654 (use (match_operand 2 "" ""))]
13657 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13661 (define_expand "sibcall"
13662 [(call (match_operand:QI 0 "" "")
13663 (match_operand 1 "" ""))
13664 (use (match_operand 2 "" ""))]
13667 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13671 (define_insn "*call_0"
13672 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13673 (match_operand 1 "" ""))]
13676 if (SIBLING_CALL_P (insn))
13679 return "call\t%P0";
13681 [(set_attr "type" "call")])
13683 (define_insn "*call_1"
13684 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13685 (match_operand 1 "" ""))]
13686 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13688 if (constant_call_address_operand (operands[0], Pmode))
13689 return "call\t%P0";
13690 return "call\t%A0";
13692 [(set_attr "type" "call")])
13694 (define_insn "*sibcall_1"
13695 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13696 (match_operand 1 "" ""))]
13697 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13699 if (constant_call_address_operand (operands[0], Pmode))
13703 [(set_attr "type" "call")])
13705 (define_insn "*call_1_rex64"
13706 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13707 (match_operand 1 "" ""))]
13708 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13710 if (constant_call_address_operand (operands[0], Pmode))
13711 return "call\t%P0";
13712 return "call\t%A0";
13714 [(set_attr "type" "call")])
13716 (define_insn "*sibcall_1_rex64"
13717 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13718 (match_operand 1 "" ""))]
13719 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13721 [(set_attr "type" "call")])
13723 (define_insn "*sibcall_1_rex64_v"
13724 [(call (mem:QI (reg:DI 40))
13725 (match_operand 0 "" ""))]
13726 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13728 [(set_attr "type" "call")])
13731 ;; Call subroutine, returning value in operand 0
13733 (define_expand "call_value_pop"
13734 [(parallel [(set (match_operand 0 "" "")
13735 (call (match_operand:QI 1 "" "")
13736 (match_operand:SI 2 "" "")))
13737 (set (reg:SI SP_REG)
13738 (plus:SI (reg:SI SP_REG)
13739 (match_operand:SI 4 "" "")))])]
13742 ix86_expand_call (operands[0], operands[1], operands[2],
13743 operands[3], operands[4], 0);
13747 (define_expand "call_value"
13748 [(set (match_operand 0 "" "")
13749 (call (match_operand:QI 1 "" "")
13750 (match_operand:SI 2 "" "")))
13751 (use (match_operand:SI 3 "" ""))]
13752 ;; Operand 2 not used on the i386.
13755 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13759 (define_expand "sibcall_value"
13760 [(set (match_operand 0 "" "")
13761 (call (match_operand:QI 1 "" "")
13762 (match_operand:SI 2 "" "")))
13763 (use (match_operand:SI 3 "" ""))]
13764 ;; Operand 2 not used on the i386.
13767 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13771 ;; Call subroutine returning any type.
13773 (define_expand "untyped_call"
13774 [(parallel [(call (match_operand 0 "" "")
13776 (match_operand 1 "" "")
13777 (match_operand 2 "" "")])]
13782 /* In order to give reg-stack an easier job in validating two
13783 coprocessor registers as containing a possible return value,
13784 simply pretend the untyped call returns a complex long double
13787 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13788 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13789 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13792 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13794 rtx set = XVECEXP (operands[2], 0, i);
13795 emit_move_insn (SET_DEST (set), SET_SRC (set));
13798 /* The optimizer does not know that the call sets the function value
13799 registers we stored in the result block. We avoid problems by
13800 claiming that all hard registers are used and clobbered at this
13802 emit_insn (gen_blockage (const0_rtx));
13807 ;; Prologue and epilogue instructions
13809 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13810 ;; all of memory. This blocks insns from being moved across this point.
13812 (define_insn "blockage"
13813 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13816 [(set_attr "length" "0")])
13818 ;; Insn emitted into the body of a function to return from a function.
13819 ;; This is only done if the function's epilogue is known to be simple.
13820 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13822 (define_expand "return"
13824 "ix86_can_use_return_insn_p ()"
13826 if (current_function_pops_args)
13828 rtx popc = GEN_INT (current_function_pops_args);
13829 emit_jump_insn (gen_return_pop_internal (popc));
13834 (define_insn "return_internal"
13838 [(set_attr "length" "1")
13839 (set_attr "length_immediate" "0")
13840 (set_attr "modrm" "0")])
13842 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13843 ;; instruction Athlon and K8 have.
13845 (define_insn "return_internal_long"
13847 (unspec [(const_int 0)] UNSPEC_REP)]
13850 [(set_attr "length" "1")
13851 (set_attr "length_immediate" "0")
13852 (set_attr "prefix_rep" "1")
13853 (set_attr "modrm" "0")])
13855 (define_insn "return_pop_internal"
13857 (use (match_operand:SI 0 "const_int_operand" ""))]
13860 [(set_attr "length" "3")
13861 (set_attr "length_immediate" "2")
13862 (set_attr "modrm" "0")])
13864 (define_insn "return_indirect_internal"
13866 (use (match_operand:SI 0 "register_operand" "r"))]
13869 [(set_attr "type" "ibr")
13870 (set_attr "length_immediate" "0")])
13876 [(set_attr "length" "1")
13877 (set_attr "length_immediate" "0")
13878 (set_attr "modrm" "0")])
13880 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13881 ;; branch prediction penalty for the third jump in a 16-byte
13884 (define_insn "align"
13885 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13888 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13889 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13891 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13892 The align insn is used to avoid 3 jump instructions in the row to improve
13893 branch prediction and the benefits hardly outweight the cost of extra 8
13894 nops on the average inserted by full alignment pseudo operation. */
13898 [(set_attr "length" "16")])
13900 (define_expand "prologue"
13903 "ix86_expand_prologue (); DONE;")
13905 (define_insn "set_got"
13906 [(set (match_operand:SI 0 "register_operand" "=r")
13907 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13908 (clobber (reg:CC FLAGS_REG))]
13910 { return output_set_got (operands[0]); }
13911 [(set_attr "type" "multi")
13912 (set_attr "length" "12")])
13914 (define_expand "epilogue"
13917 "ix86_expand_epilogue (1); DONE;")
13919 (define_expand "sibcall_epilogue"
13922 "ix86_expand_epilogue (0); DONE;")
13924 (define_expand "eh_return"
13925 [(use (match_operand 0 "register_operand" ""))]
13928 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13930 /* Tricky bit: we write the address of the handler to which we will
13931 be returning into someone else's stack frame, one word below the
13932 stack address we wish to restore. */
13933 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13934 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13935 tmp = gen_rtx_MEM (Pmode, tmp);
13936 emit_move_insn (tmp, ra);
13938 if (Pmode == SImode)
13939 emit_jump_insn (gen_eh_return_si (sa));
13941 emit_jump_insn (gen_eh_return_di (sa));
13946 (define_insn_and_split "eh_return_si"
13948 (unspec [(match_operand:SI 0 "register_operand" "c")]
13949 UNSPEC_EH_RETURN))]
13954 "ix86_expand_epilogue (2); DONE;")
13956 (define_insn_and_split "eh_return_di"
13958 (unspec [(match_operand:DI 0 "register_operand" "c")]
13959 UNSPEC_EH_RETURN))]
13964 "ix86_expand_epilogue (2); DONE;")
13966 (define_insn "leave"
13967 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13968 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13969 (clobber (mem:BLK (scratch)))]
13972 [(set_attr "type" "leave")])
13974 (define_insn "leave_rex64"
13975 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13976 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13977 (clobber (mem:BLK (scratch)))]
13980 [(set_attr "type" "leave")])
13982 (define_expand "ffssi2"
13984 [(set (match_operand:SI 0 "register_operand" "")
13985 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13986 (clobber (match_scratch:SI 2 ""))
13987 (clobber (reg:CC FLAGS_REG))])]
13991 (define_insn_and_split "*ffs_cmove"
13992 [(set (match_operand:SI 0 "register_operand" "=r")
13993 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13994 (clobber (match_scratch:SI 2 "=&r"))
13995 (clobber (reg:CC FLAGS_REG))]
13998 "&& reload_completed"
13999 [(set (match_dup 2) (const_int -1))
14000 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14001 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14002 (set (match_dup 0) (if_then_else:SI
14003 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14006 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14007 (clobber (reg:CC FLAGS_REG))])]
14010 (define_insn_and_split "*ffs_no_cmove"
14011 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14012 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14013 (clobber (match_scratch:SI 2 "=&q"))
14014 (clobber (reg:CC FLAGS_REG))]
14018 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14019 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14020 (set (strict_low_part (match_dup 3))
14021 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14022 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14023 (clobber (reg:CC FLAGS_REG))])
14024 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14025 (clobber (reg:CC FLAGS_REG))])
14026 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14027 (clobber (reg:CC FLAGS_REG))])]
14029 operands[3] = gen_lowpart (QImode, operands[2]);
14030 ix86_expand_clear (operands[2]);
14033 (define_insn "*ffssi_1"
14034 [(set (reg:CCZ FLAGS_REG)
14035 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14037 (set (match_operand:SI 0 "register_operand" "=r")
14038 (ctz:SI (match_dup 1)))]
14040 "bsf{l}\t{%1, %0|%0, %1}"
14041 [(set_attr "prefix_0f" "1")])
14043 (define_expand "ffsdi2"
14045 [(set (match_operand:DI 0 "register_operand" "")
14046 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14047 (clobber (match_scratch:DI 2 ""))
14048 (clobber (reg:CC 17))])]
14049 "TARGET_64BIT && TARGET_CMOVE"
14052 (define_insn_and_split "*ffs_rex64"
14053 [(set (match_operand:DI 0 "register_operand" "=r")
14054 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14055 (clobber (match_scratch:DI 2 "=&r"))
14056 (clobber (reg:CC 17))]
14057 "TARGET_64BIT && TARGET_CMOVE"
14059 "&& reload_completed"
14060 [(set (match_dup 2) (const_int -1))
14061 (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14062 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14063 (set (match_dup 0) (if_then_else:DI
14064 (eq (reg:CCZ 17) (const_int 0))
14067 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14068 (clobber (reg:CC 17))])]
14071 (define_insn "*ffsdi_1"
14073 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14075 (set (match_operand:DI 0 "register_operand" "=r")
14076 (ctz:DI (match_dup 1)))]
14078 "bsf{q}\t{%1, %0|%0, %1}"
14079 [(set_attr "prefix_0f" "1")])
14081 (define_insn "ctzsi2"
14082 [(set (match_operand:SI 0 "register_operand" "=r")
14083 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14084 (clobber (reg:CC FLAGS_REG))]
14086 "bsf{l}\t{%1, %0|%0, %1}"
14087 [(set_attr "prefix_0f" "1")])
14089 (define_insn "ctzdi2"
14090 [(set (match_operand:DI 0 "register_operand" "=r")
14091 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14092 (clobber (reg:CC 17))]
14094 "bsf{q}\t{%1, %0|%0, %1}"
14095 [(set_attr "prefix_0f" "1")])
14097 (define_expand "clzsi2"
14099 [(set (match_operand:SI 0 "register_operand" "")
14100 (minus:SI (const_int 31)
14101 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14102 (clobber (reg:CC FLAGS_REG))])
14104 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14105 (clobber (reg:CC FLAGS_REG))])]
14109 (define_insn "*bsr"
14110 [(set (match_operand:SI 0 "register_operand" "=r")
14111 (minus:SI (const_int 31)
14112 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14113 (clobber (reg:CC FLAGS_REG))]
14115 "bsr{l}\t{%1, %0|%0, %1}"
14116 [(set_attr "prefix_0f" "1")])
14118 (define_expand "clzdi2"
14120 [(set (match_operand:DI 0 "register_operand" "")
14121 (minus:DI (const_int 63)
14122 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14123 (clobber (reg:CC 17))])
14125 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14126 (clobber (reg:CC 17))])]
14130 (define_insn "*bsr_rex64"
14131 [(set (match_operand:DI 0 "register_operand" "=r")
14132 (minus:DI (const_int 63)
14133 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14134 (clobber (reg:CC 17))]
14136 "bsr{q}\t{%1, %0|%0, %1}"
14137 [(set_attr "prefix_0f" "1")])
14139 ;; Thread-local storage patterns for ELF.
14141 ;; Note that these code sequences must appear exactly as shown
14142 ;; in order to allow linker relaxation.
14144 (define_insn "*tls_global_dynamic_32_gnu"
14145 [(set (match_operand:SI 0 "register_operand" "=a")
14146 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14147 (match_operand:SI 2 "tls_symbolic_operand" "")
14148 (match_operand:SI 3 "call_insn_operand" "")]
14150 (clobber (match_scratch:SI 4 "=d"))
14151 (clobber (match_scratch:SI 5 "=c"))
14152 (clobber (reg:CC FLAGS_REG))]
14153 "!TARGET_64BIT && TARGET_GNU_TLS"
14154 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14155 [(set_attr "type" "multi")
14156 (set_attr "length" "12")])
14158 (define_insn "*tls_global_dynamic_32_sun"
14159 [(set (match_operand:SI 0 "register_operand" "=a")
14160 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14161 (match_operand:SI 2 "tls_symbolic_operand" "")
14162 (match_operand:SI 3 "call_insn_operand" "")]
14164 (clobber (match_scratch:SI 4 "=d"))
14165 (clobber (match_scratch:SI 5 "=c"))
14166 (clobber (reg:CC FLAGS_REG))]
14167 "!TARGET_64BIT && TARGET_SUN_TLS"
14168 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14169 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14170 [(set_attr "type" "multi")
14171 (set_attr "length" "14")])
14173 (define_expand "tls_global_dynamic_32"
14174 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14177 (match_operand:SI 1 "tls_symbolic_operand" "")
14180 (clobber (match_scratch:SI 4 ""))
14181 (clobber (match_scratch:SI 5 ""))
14182 (clobber (reg:CC FLAGS_REG))])]
14186 operands[2] = pic_offset_table_rtx;
14189 operands[2] = gen_reg_rtx (Pmode);
14190 emit_insn (gen_set_got (operands[2]));
14192 operands[3] = ix86_tls_get_addr ();
14195 (define_insn "*tls_global_dynamic_64"
14196 [(set (match_operand:DI 0 "register_operand" "=a")
14197 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14198 (match_operand:DI 3 "" "")))
14199 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14202 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14203 [(set_attr "type" "multi")
14204 (set_attr "length" "16")])
14206 (define_expand "tls_global_dynamic_64"
14207 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14208 (call (mem:QI (match_dup 2)) (const_int 0)))
14209 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14213 operands[2] = ix86_tls_get_addr ();
14216 (define_insn "*tls_local_dynamic_base_32_gnu"
14217 [(set (match_operand:SI 0 "register_operand" "=a")
14218 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14219 (match_operand:SI 2 "call_insn_operand" "")]
14220 UNSPEC_TLS_LD_BASE))
14221 (clobber (match_scratch:SI 3 "=d"))
14222 (clobber (match_scratch:SI 4 "=c"))
14223 (clobber (reg:CC FLAGS_REG))]
14224 "!TARGET_64BIT && TARGET_GNU_TLS"
14225 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14226 [(set_attr "type" "multi")
14227 (set_attr "length" "11")])
14229 (define_insn "*tls_local_dynamic_base_32_sun"
14230 [(set (match_operand:SI 0 "register_operand" "=a")
14231 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14232 (match_operand:SI 2 "call_insn_operand" "")]
14233 UNSPEC_TLS_LD_BASE))
14234 (clobber (match_scratch:SI 3 "=d"))
14235 (clobber (match_scratch:SI 4 "=c"))
14236 (clobber (reg:CC FLAGS_REG))]
14237 "!TARGET_64BIT && TARGET_SUN_TLS"
14238 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14239 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14240 [(set_attr "type" "multi")
14241 (set_attr "length" "13")])
14243 (define_expand "tls_local_dynamic_base_32"
14244 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14245 (unspec:SI [(match_dup 1) (match_dup 2)]
14246 UNSPEC_TLS_LD_BASE))
14247 (clobber (match_scratch:SI 3 ""))
14248 (clobber (match_scratch:SI 4 ""))
14249 (clobber (reg:CC FLAGS_REG))])]
14253 operands[1] = pic_offset_table_rtx;
14256 operands[1] = gen_reg_rtx (Pmode);
14257 emit_insn (gen_set_got (operands[1]));
14259 operands[2] = ix86_tls_get_addr ();
14262 (define_insn "*tls_local_dynamic_base_64"
14263 [(set (match_operand:DI 0 "register_operand" "=a")
14264 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14265 (match_operand:DI 2 "" "")))
14266 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14268 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14269 [(set_attr "type" "multi")
14270 (set_attr "length" "12")])
14272 (define_expand "tls_local_dynamic_base_64"
14273 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14274 (call (mem:QI (match_dup 1)) (const_int 0)))
14275 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14278 operands[1] = ix86_tls_get_addr ();
14281 ;; Local dynamic of a single variable is a lose. Show combine how
14282 ;; to convert that back to global dynamic.
14284 (define_insn_and_split "*tls_local_dynamic_32_once"
14285 [(set (match_operand:SI 0 "register_operand" "=a")
14286 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14287 (match_operand:SI 2 "call_insn_operand" "")]
14288 UNSPEC_TLS_LD_BASE)
14289 (const:SI (unspec:SI
14290 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14292 (clobber (match_scratch:SI 4 "=d"))
14293 (clobber (match_scratch:SI 5 "=c"))
14294 (clobber (reg:CC FLAGS_REG))]
14298 [(parallel [(set (match_dup 0)
14299 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14301 (clobber (match_dup 4))
14302 (clobber (match_dup 5))
14303 (clobber (reg:CC FLAGS_REG))])]
14306 ;; Load and add the thread base pointer from %gs:0.
14308 (define_insn "*load_tp_si"
14309 [(set (match_operand:SI 0 "register_operand" "=r")
14310 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14312 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14313 [(set_attr "type" "imov")
14314 (set_attr "modrm" "0")
14315 (set_attr "length" "7")
14316 (set_attr "memory" "load")
14317 (set_attr "imm_disp" "false")])
14319 (define_insn "*add_tp_si"
14320 [(set (match_operand:SI 0 "register_operand" "=r")
14321 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14322 (match_operand:SI 1 "register_operand" "0")))
14323 (clobber (reg:CC FLAGS_REG))]
14325 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14326 [(set_attr "type" "alu")
14327 (set_attr "modrm" "0")
14328 (set_attr "length" "7")
14329 (set_attr "memory" "load")
14330 (set_attr "imm_disp" "false")])
14332 (define_insn "*load_tp_di"
14333 [(set (match_operand:DI 0 "register_operand" "=r")
14334 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14336 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14337 [(set_attr "type" "imov")
14338 (set_attr "modrm" "0")
14339 (set_attr "length" "7")
14340 (set_attr "memory" "load")
14341 (set_attr "imm_disp" "false")])
14343 (define_insn "*add_tp_di"
14344 [(set (match_operand:DI 0 "register_operand" "=r")
14345 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14346 (match_operand:DI 1 "register_operand" "0")))
14347 (clobber (reg:CC FLAGS_REG))]
14349 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14350 [(set_attr "type" "alu")
14351 (set_attr "modrm" "0")
14352 (set_attr "length" "7")
14353 (set_attr "memory" "load")
14354 (set_attr "imm_disp" "false")])
14356 ;; These patterns match the binary 387 instructions for addM3, subM3,
14357 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14358 ;; SFmode. The first is the normal insn, the second the same insn but
14359 ;; with one operand a conversion, and the third the same insn but with
14360 ;; the other operand a conversion. The conversion may be SFmode or
14361 ;; SImode if the target mode DFmode, but only SImode if the target mode
14364 ;; Gcc is slightly more smart about handling normal two address instructions
14365 ;; so use special patterns for add and mull.
14366 (define_insn "*fop_sf_comm_nosse"
14367 [(set (match_operand:SF 0 "register_operand" "=f")
14368 (match_operator:SF 3 "binary_fp_operator"
14369 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14370 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14371 "TARGET_80387 && !TARGET_SSE_MATH
14372 && COMMUTATIVE_ARITH_P (operands[3])
14373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14374 "* return output_387_binary_op (insn, operands);"
14375 [(set (attr "type")
14376 (if_then_else (match_operand:SF 3 "mult_operator" "")
14377 (const_string "fmul")
14378 (const_string "fop")))
14379 (set_attr "mode" "SF")])
14381 (define_insn "*fop_sf_comm"
14382 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14383 (match_operator:SF 3 "binary_fp_operator"
14384 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14385 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14386 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14387 && COMMUTATIVE_ARITH_P (operands[3])
14388 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14389 "* return output_387_binary_op (insn, operands);"
14390 [(set (attr "type")
14391 (if_then_else (eq_attr "alternative" "1")
14392 (if_then_else (match_operand:SF 3 "mult_operator" "")
14393 (const_string "ssemul")
14394 (const_string "sseadd"))
14395 (if_then_else (match_operand:SF 3 "mult_operator" "")
14396 (const_string "fmul")
14397 (const_string "fop"))))
14398 (set_attr "mode" "SF")])
14400 (define_insn "*fop_sf_comm_sse"
14401 [(set (match_operand:SF 0 "register_operand" "=x")
14402 (match_operator:SF 3 "binary_fp_operator"
14403 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14404 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14405 "TARGET_SSE_MATH && COMMUTATIVE_ARITH_P (operands[3])
14406 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14407 "* return output_387_binary_op (insn, operands);"
14408 [(set (attr "type")
14409 (if_then_else (match_operand:SF 3 "mult_operator" "")
14410 (const_string "ssemul")
14411 (const_string "sseadd")))
14412 (set_attr "mode" "SF")])
14414 (define_insn "*fop_df_comm_nosse"
14415 [(set (match_operand:DF 0 "register_operand" "=f")
14416 (match_operator:DF 3 "binary_fp_operator"
14417 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14418 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14419 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14420 && COMMUTATIVE_ARITH_P (operands[3])
14421 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14422 "* return output_387_binary_op (insn, operands);"
14423 [(set (attr "type")
14424 (if_then_else (match_operand:SF 3 "mult_operator" "")
14425 (const_string "fmul")
14426 (const_string "fop")))
14427 (set_attr "mode" "DF")])
14429 (define_insn "*fop_df_comm"
14430 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14431 (match_operator:DF 3 "binary_fp_operator"
14432 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14433 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14434 "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14435 && COMMUTATIVE_ARITH_P (operands[3])
14436 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14437 "* return output_387_binary_op (insn, operands);"
14438 [(set (attr "type")
14439 (if_then_else (eq_attr "alternative" "1")
14440 (if_then_else (match_operand:SF 3 "mult_operator" "")
14441 (const_string "ssemul")
14442 (const_string "sseadd"))
14443 (if_then_else (match_operand:SF 3 "mult_operator" "")
14444 (const_string "fmul")
14445 (const_string "fop"))))
14446 (set_attr "mode" "DF")])
14448 (define_insn "*fop_df_comm_sse"
14449 [(set (match_operand:DF 0 "register_operand" "=Y")
14450 (match_operator:DF 3 "binary_fp_operator"
14451 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14452 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14453 "TARGET_SSE2 && TARGET_SSE_MATH
14454 && COMMUTATIVE_ARITH_P (operands[3])
14455 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14456 "* return output_387_binary_op (insn, operands);"
14457 [(set (attr "type")
14458 (if_then_else (match_operand:SF 3 "mult_operator" "")
14459 (const_string "ssemul")
14460 (const_string "sseadd")))
14461 (set_attr "mode" "DF")])
14463 (define_insn "*fop_xf_comm"
14464 [(set (match_operand:XF 0 "register_operand" "=f")
14465 (match_operator:XF 3 "binary_fp_operator"
14466 [(match_operand:XF 1 "register_operand" "%0")
14467 (match_operand:XF 2 "register_operand" "f")]))]
14469 && COMMUTATIVE_ARITH_P (operands[3])"
14470 "* return output_387_binary_op (insn, operands);"
14471 [(set (attr "type")
14472 (if_then_else (match_operand:XF 3 "mult_operator" "")
14473 (const_string "fmul")
14474 (const_string "fop")))
14475 (set_attr "mode" "XF")])
14477 (define_insn "*fop_sf_1_nosse"
14478 [(set (match_operand:SF 0 "register_operand" "=f,f")
14479 (match_operator:SF 3 "binary_fp_operator"
14480 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14481 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14482 "TARGET_80387 && !TARGET_SSE_MATH
14483 && !COMMUTATIVE_ARITH_P (operands[3])
14484 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14485 "* return output_387_binary_op (insn, operands);"
14486 [(set (attr "type")
14487 (cond [(match_operand:SF 3 "mult_operator" "")
14488 (const_string "fmul")
14489 (match_operand:SF 3 "div_operator" "")
14490 (const_string "fdiv")
14492 (const_string "fop")))
14493 (set_attr "mode" "SF")])
14495 (define_insn "*fop_sf_1"
14496 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14497 (match_operator:SF 3 "binary_fp_operator"
14498 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14499 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14500 "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14501 && !COMMUTATIVE_ARITH_P (operands[3])
14502 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14503 "* return output_387_binary_op (insn, operands);"
14504 [(set (attr "type")
14505 (cond [(and (eq_attr "alternative" "2")
14506 (match_operand:SF 3 "mult_operator" ""))
14507 (const_string "ssemul")
14508 (and (eq_attr "alternative" "2")
14509 (match_operand:SF 3 "div_operator" ""))
14510 (const_string "ssediv")
14511 (eq_attr "alternative" "2")
14512 (const_string "sseadd")
14513 (match_operand:SF 3 "mult_operator" "")
14514 (const_string "fmul")
14515 (match_operand:SF 3 "div_operator" "")
14516 (const_string "fdiv")
14518 (const_string "fop")))
14519 (set_attr "mode" "SF")])
14521 (define_insn "*fop_sf_1_sse"
14522 [(set (match_operand:SF 0 "register_operand" "=x")
14523 (match_operator:SF 3 "binary_fp_operator"
14524 [(match_operand:SF 1 "register_operand" "0")
14525 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14527 && !COMMUTATIVE_ARITH_P (operands[3])"
14528 "* return output_387_binary_op (insn, operands);"
14529 [(set (attr "type")
14530 (cond [(match_operand:SF 3 "mult_operator" "")
14531 (const_string "ssemul")
14532 (match_operand:SF 3 "div_operator" "")
14533 (const_string "ssediv")
14535 (const_string "sseadd")))
14536 (set_attr "mode" "SF")])
14538 ;; ??? Add SSE splitters for these!
14539 (define_insn "*fop_sf_2"
14540 [(set (match_operand:SF 0 "register_operand" "=f,f")
14541 (match_operator:SF 3 "binary_fp_operator"
14542 [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14543 (match_operand:SF 2 "register_operand" "0,0")]))]
14544 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14545 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14546 [(set (attr "type")
14547 (cond [(match_operand:SF 3 "mult_operator" "")
14548 (const_string "fmul")
14549 (match_operand:SF 3 "div_operator" "")
14550 (const_string "fdiv")
14552 (const_string "fop")))
14553 (set_attr "fp_int_src" "true")
14554 (set_attr "mode" "SI")])
14556 (define_insn "*fop_sf_3"
14557 [(set (match_operand:SF 0 "register_operand" "=f,f")
14558 (match_operator:SF 3 "binary_fp_operator"
14559 [(match_operand:SF 1 "register_operand" "0,0")
14560 (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14561 "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14562 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14563 [(set (attr "type")
14564 (cond [(match_operand:SF 3 "mult_operator" "")
14565 (const_string "fmul")
14566 (match_operand:SF 3 "div_operator" "")
14567 (const_string "fdiv")
14569 (const_string "fop")))
14570 (set_attr "fp_int_src" "true")
14571 (set_attr "mode" "SI")])
14573 (define_insn "*fop_df_1_nosse"
14574 [(set (match_operand:DF 0 "register_operand" "=f,f")
14575 (match_operator:DF 3 "binary_fp_operator"
14576 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14577 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14578 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14579 && !COMMUTATIVE_ARITH_P (operands[3])
14580 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14581 "* return output_387_binary_op (insn, operands);"
14582 [(set (attr "type")
14583 (cond [(match_operand:DF 3 "mult_operator" "")
14584 (const_string "fmul")
14585 (match_operand:DF 3 "div_operator" "")
14586 (const_string "fdiv")
14588 (const_string "fop")))
14589 (set_attr "mode" "DF")])
14592 (define_insn "*fop_df_1"
14593 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14594 (match_operator:DF 3 "binary_fp_operator"
14595 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14596 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14597 "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14598 && !COMMUTATIVE_ARITH_P (operands[3])
14599 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14600 "* return output_387_binary_op (insn, operands);"
14601 [(set (attr "type")
14602 (cond [(and (eq_attr "alternative" "2")
14603 (match_operand:SF 3 "mult_operator" ""))
14604 (const_string "ssemul")
14605 (and (eq_attr "alternative" "2")
14606 (match_operand:SF 3 "div_operator" ""))
14607 (const_string "ssediv")
14608 (eq_attr "alternative" "2")
14609 (const_string "sseadd")
14610 (match_operand:DF 3 "mult_operator" "")
14611 (const_string "fmul")
14612 (match_operand:DF 3 "div_operator" "")
14613 (const_string "fdiv")
14615 (const_string "fop")))
14616 (set_attr "mode" "DF")])
14618 (define_insn "*fop_df_1_sse"
14619 [(set (match_operand:DF 0 "register_operand" "=Y")
14620 (match_operator:DF 3 "binary_fp_operator"
14621 [(match_operand:DF 1 "register_operand" "0")
14622 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14623 "TARGET_SSE2 && TARGET_SSE_MATH
14624 && !COMMUTATIVE_ARITH_P (operands[3])"
14625 "* return output_387_binary_op (insn, operands);"
14626 [(set_attr "mode" "DF")
14628 (cond [(match_operand:SF 3 "mult_operator" "")
14629 (const_string "ssemul")
14630 (match_operand:SF 3 "div_operator" "")
14631 (const_string "ssediv")
14633 (const_string "sseadd")))])
14635 ;; ??? Add SSE splitters for these!
14636 (define_insn "*fop_df_2"
14637 [(set (match_operand:DF 0 "register_operand" "=f,f")
14638 (match_operator:DF 3 "binary_fp_operator"
14639 [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14640 (match_operand:DF 2 "register_operand" "0,0")]))]
14641 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14642 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14643 [(set (attr "type")
14644 (cond [(match_operand:DF 3 "mult_operator" "")
14645 (const_string "fmul")
14646 (match_operand:DF 3 "div_operator" "")
14647 (const_string "fdiv")
14649 (const_string "fop")))
14650 (set_attr "fp_int_src" "true")
14651 (set_attr "mode" "SI")])
14653 (define_insn "*fop_df_3"
14654 [(set (match_operand:DF 0 "register_operand" "=f,f")
14655 (match_operator:DF 3 "binary_fp_operator"
14656 [(match_operand:DF 1 "register_operand" "0,0")
14657 (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14658 "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14659 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14660 [(set (attr "type")
14661 (cond [(match_operand:DF 3 "mult_operator" "")
14662 (const_string "fmul")
14663 (match_operand:DF 3 "div_operator" "")
14664 (const_string "fdiv")
14666 (const_string "fop")))
14667 (set_attr "fp_int_src" "true")
14668 (set_attr "mode" "SI")])
14670 (define_insn "*fop_df_4"
14671 [(set (match_operand:DF 0 "register_operand" "=f,f")
14672 (match_operator:DF 3 "binary_fp_operator"
14673 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14674 (match_operand:DF 2 "register_operand" "0,f")]))]
14675 "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14676 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14677 "* return output_387_binary_op (insn, operands);"
14678 [(set (attr "type")
14679 (cond [(match_operand:DF 3 "mult_operator" "")
14680 (const_string "fmul")
14681 (match_operand:DF 3 "div_operator" "")
14682 (const_string "fdiv")
14684 (const_string "fop")))
14685 (set_attr "mode" "SF")])
14687 (define_insn "*fop_df_5"
14688 [(set (match_operand:DF 0 "register_operand" "=f,f")
14689 (match_operator:DF 3 "binary_fp_operator"
14690 [(match_operand:DF 1 "register_operand" "0,f")
14692 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14693 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14694 "* return output_387_binary_op (insn, operands);"
14695 [(set (attr "type")
14696 (cond [(match_operand:DF 3 "mult_operator" "")
14697 (const_string "fmul")
14698 (match_operand:DF 3 "div_operator" "")
14699 (const_string "fdiv")
14701 (const_string "fop")))
14702 (set_attr "mode" "SF")])
14704 (define_insn "*fop_df_6"
14705 [(set (match_operand:DF 0 "register_operand" "=f,f")
14706 (match_operator:DF 3 "binary_fp_operator"
14708 (match_operand:SF 1 "register_operand" "0,f"))
14710 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14711 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14712 "* return output_387_binary_op (insn, operands);"
14713 [(set (attr "type")
14714 (cond [(match_operand:DF 3 "mult_operator" "")
14715 (const_string "fmul")
14716 (match_operand:DF 3 "div_operator" "")
14717 (const_string "fdiv")
14719 (const_string "fop")))
14720 (set_attr "mode" "SF")])
14722 (define_insn "*fop_xf_1"
14723 [(set (match_operand:XF 0 "register_operand" "=f,f")
14724 (match_operator:XF 3 "binary_fp_operator"
14725 [(match_operand:XF 1 "register_operand" "0,f")
14726 (match_operand:XF 2 "register_operand" "f,0")]))]
14728 && !COMMUTATIVE_ARITH_P (operands[3])"
14729 "* return output_387_binary_op (insn, operands);"
14730 [(set (attr "type")
14731 (cond [(match_operand:XF 3 "mult_operator" "")
14732 (const_string "fmul")
14733 (match_operand:XF 3 "div_operator" "")
14734 (const_string "fdiv")
14736 (const_string "fop")))
14737 (set_attr "mode" "XF")])
14739 (define_insn "*fop_xf_2"
14740 [(set (match_operand:XF 0 "register_operand" "=f,f")
14741 (match_operator:XF 3 "binary_fp_operator"
14742 [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14743 (match_operand:XF 2 "register_operand" "0,0")]))]
14744 "TARGET_80387 && TARGET_USE_FIOP"
14745 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14746 [(set (attr "type")
14747 (cond [(match_operand:XF 3 "mult_operator" "")
14748 (const_string "fmul")
14749 (match_operand:XF 3 "div_operator" "")
14750 (const_string "fdiv")
14752 (const_string "fop")))
14753 (set_attr "fp_int_src" "true")
14754 (set_attr "mode" "SI")])
14756 (define_insn "*fop_xf_3"
14757 [(set (match_operand:XF 0 "register_operand" "=f,f")
14758 (match_operator:XF 3 "binary_fp_operator"
14759 [(match_operand:XF 1 "register_operand" "0,0")
14760 (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14761 "TARGET_80387 && TARGET_USE_FIOP"
14762 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14763 [(set (attr "type")
14764 (cond [(match_operand:XF 3 "mult_operator" "")
14765 (const_string "fmul")
14766 (match_operand:XF 3 "div_operator" "")
14767 (const_string "fdiv")
14769 (const_string "fop")))
14770 (set_attr "fp_int_src" "true")
14771 (set_attr "mode" "SI")])
14773 (define_insn "*fop_xf_4"
14774 [(set (match_operand:XF 0 "register_operand" "=f,f")
14775 (match_operator:XF 3 "binary_fp_operator"
14776 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14777 (match_operand:XF 2 "register_operand" "0,f")]))]
14779 "* return output_387_binary_op (insn, operands);"
14780 [(set (attr "type")
14781 (cond [(match_operand:XF 3 "mult_operator" "")
14782 (const_string "fmul")
14783 (match_operand:XF 3 "div_operator" "")
14784 (const_string "fdiv")
14786 (const_string "fop")))
14787 (set_attr "mode" "SF")])
14789 (define_insn "*fop_xf_5"
14790 [(set (match_operand:XF 0 "register_operand" "=f,f")
14791 (match_operator:XF 3 "binary_fp_operator"
14792 [(match_operand:XF 1 "register_operand" "0,f")
14794 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14796 "* return output_387_binary_op (insn, operands);"
14797 [(set (attr "type")
14798 (cond [(match_operand:XF 3 "mult_operator" "")
14799 (const_string "fmul")
14800 (match_operand:XF 3 "div_operator" "")
14801 (const_string "fdiv")
14803 (const_string "fop")))
14804 (set_attr "mode" "SF")])
14806 (define_insn "*fop_xf_6"
14807 [(set (match_operand:XF 0 "register_operand" "=f,f")
14808 (match_operator:XF 3 "binary_fp_operator"
14810 (match_operand 1 "register_operand" "0,f"))
14812 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14814 "* return output_387_binary_op (insn, operands);"
14815 [(set (attr "type")
14816 (cond [(match_operand:XF 3 "mult_operator" "")
14817 (const_string "fmul")
14818 (match_operand:XF 3 "div_operator" "")
14819 (const_string "fdiv")
14821 (const_string "fop")))
14822 (set_attr "mode" "SF")])
14825 [(set (match_operand 0 "register_operand" "")
14826 (match_operator 3 "binary_fp_operator"
14827 [(float (match_operand:SI 1 "register_operand" ""))
14828 (match_operand 2 "register_operand" "")]))]
14829 "TARGET_80387 && reload_completed
14830 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14833 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14834 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14835 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14836 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14837 GET_MODE (operands[3]),
14840 ix86_free_from_memory (GET_MODE (operands[1]));
14845 [(set (match_operand 0 "register_operand" "")
14846 (match_operator 3 "binary_fp_operator"
14847 [(match_operand 1 "register_operand" "")
14848 (float (match_operand:SI 2 "register_operand" ""))]))]
14849 "TARGET_80387 && reload_completed
14850 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14853 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14854 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14855 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14856 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14857 GET_MODE (operands[3]),
14860 ix86_free_from_memory (GET_MODE (operands[2]));
14864 ;; FPU special functions.
14866 (define_expand "sqrtsf2"
14867 [(set (match_operand:SF 0 "register_operand" "")
14868 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14869 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
14871 if (!TARGET_SSE_MATH)
14872 operands[1] = force_reg (SFmode, operands[1]);
14875 (define_insn "sqrtsf2_1"
14876 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14877 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14878 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14879 && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14882 sqrtss\t{%1, %0|%0, %1}"
14883 [(set_attr "type" "fpspc,sse")
14884 (set_attr "mode" "SF,SF")
14885 (set_attr "athlon_decode" "direct,*")])
14887 (define_insn "sqrtsf2_1_sse_only"
14888 [(set (match_operand:SF 0 "register_operand" "=x")
14889 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14890 "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14891 "sqrtss\t{%1, %0|%0, %1}"
14892 [(set_attr "type" "sse")
14893 (set_attr "mode" "SF")
14894 (set_attr "athlon_decode" "*")])
14896 (define_insn "sqrtsf2_i387"
14897 [(set (match_operand:SF 0 "register_operand" "=f")
14898 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14899 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14900 && !TARGET_SSE_MATH"
14902 [(set_attr "type" "fpspc")
14903 (set_attr "mode" "SF")
14904 (set_attr "athlon_decode" "direct")])
14906 (define_expand "sqrtdf2"
14907 [(set (match_operand:DF 0 "register_operand" "")
14908 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14909 "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
14910 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14912 if (!TARGET_SSE2 || !TARGET_SSE_MATH)
14913 operands[1] = force_reg (DFmode, operands[1]);
14916 (define_insn "sqrtdf2_1"
14917 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14918 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14919 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14920 && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
14923 sqrtsd\t{%1, %0|%0, %1}"
14924 [(set_attr "type" "fpspc,sse")
14925 (set_attr "mode" "DF,DF")
14926 (set_attr "athlon_decode" "direct,*")])
14928 (define_insn "sqrtdf2_1_sse_only"
14929 [(set (match_operand:DF 0 "register_operand" "=Y")
14930 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14931 "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
14932 "sqrtsd\t{%1, %0|%0, %1}"
14933 [(set_attr "type" "sse")
14934 (set_attr "mode" "DF")
14935 (set_attr "athlon_decode" "*")])
14937 (define_insn "sqrtdf2_i387"
14938 [(set (match_operand:DF 0 "register_operand" "=f")
14939 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14940 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14941 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
14943 [(set_attr "type" "fpspc")
14944 (set_attr "mode" "DF")
14945 (set_attr "athlon_decode" "direct")])
14947 (define_insn "*sqrtextendsfdf2"
14948 [(set (match_operand:DF 0 "register_operand" "=f")
14949 (sqrt:DF (float_extend:DF
14950 (match_operand:SF 1 "register_operand" "0"))))]
14951 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14952 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14954 [(set_attr "type" "fpspc")
14955 (set_attr "mode" "DF")
14956 (set_attr "athlon_decode" "direct")])
14958 (define_insn "sqrtxf2"
14959 [(set (match_operand:XF 0 "register_operand" "=f")
14960 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14961 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
14962 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14964 [(set_attr "type" "fpspc")
14965 (set_attr "mode" "XF")
14966 (set_attr "athlon_decode" "direct")])
14968 (define_insn "*sqrtextenddfxf2"
14969 [(set (match_operand:XF 0 "register_operand" "=f")
14970 (sqrt:XF (float_extend:XF
14971 (match_operand:DF 1 "register_operand" "0"))))]
14972 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14974 [(set_attr "type" "fpspc")
14975 (set_attr "mode" "XF")
14976 (set_attr "athlon_decode" "direct")])
14978 (define_insn "*sqrtextendsfxf2"
14979 [(set (match_operand:XF 0 "register_operand" "=f")
14980 (sqrt:XF (float_extend:XF
14981 (match_operand:SF 1 "register_operand" "0"))))]
14982 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
14984 [(set_attr "type" "fpspc")
14985 (set_attr "mode" "XF")
14986 (set_attr "athlon_decode" "direct")])
14988 (define_insn "fpremxf4"
14989 [(set (match_operand:XF 0 "register_operand" "=f")
14990 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14991 (match_operand:XF 3 "register_operand" "1")]
14993 (set (match_operand:XF 1 "register_operand" "=u")
14994 (unspec:XF [(match_dup 2) (match_dup 3)]
14996 (set (reg:CCFP FPSR_REG)
14997 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14998 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
14999 && flag_unsafe_math_optimizations"
15001 [(set_attr "type" "fpspc")
15002 (set_attr "mode" "XF")])
15004 (define_expand "fmodsf3"
15005 [(use (match_operand:SF 0 "register_operand" ""))
15006 (use (match_operand:SF 1 "register_operand" ""))
15007 (use (match_operand:SF 2 "register_operand" ""))]
15008 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15009 && flag_unsafe_math_optimizations"
15011 rtx label = gen_label_rtx ();
15013 rtx op1 = gen_reg_rtx (XFmode);
15014 rtx op2 = gen_reg_rtx (XFmode);
15016 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15017 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15019 emit_label (label);
15021 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15022 ix86_emit_fp_unordered_jump (label);
15024 emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15028 (define_expand "fmoddf3"
15029 [(use (match_operand:DF 0 "register_operand" ""))
15030 (use (match_operand:DF 1 "register_operand" ""))
15031 (use (match_operand:DF 2 "register_operand" ""))]
15032 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15033 && flag_unsafe_math_optimizations"
15035 rtx label = gen_label_rtx ();
15037 rtx op1 = gen_reg_rtx (XFmode);
15038 rtx op2 = gen_reg_rtx (XFmode);
15040 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15041 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15043 emit_label (label);
15045 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15046 ix86_emit_fp_unordered_jump (label);
15048 emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15052 (define_expand "fmodxf3"
15053 [(use (match_operand:XF 0 "register_operand" ""))
15054 (use (match_operand:XF 1 "register_operand" ""))
15055 (use (match_operand:XF 2 "register_operand" ""))]
15056 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15057 && flag_unsafe_math_optimizations"
15059 rtx label = gen_label_rtx ();
15061 emit_label (label);
15063 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15064 operands[1], operands[2]));
15065 ix86_emit_fp_unordered_jump (label);
15067 emit_move_insn (operands[0], operands[1]);
15071 (define_insn "fprem1xf4"
15072 [(set (match_operand:XF 0 "register_operand" "=f")
15073 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15074 (match_operand:XF 3 "register_operand" "1")]
15076 (set (match_operand:XF 1 "register_operand" "=u")
15077 (unspec:XF [(match_dup 2) (match_dup 3)]
15079 (set (reg:CCFP FPSR_REG)
15080 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15081 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15082 && flag_unsafe_math_optimizations"
15084 [(set_attr "type" "fpspc")
15085 (set_attr "mode" "XF")])
15087 (define_expand "dremsf3"
15088 [(use (match_operand:SF 0 "register_operand" ""))
15089 (use (match_operand:SF 1 "register_operand" ""))
15090 (use (match_operand:SF 2 "register_operand" ""))]
15091 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15092 && flag_unsafe_math_optimizations"
15094 rtx label = gen_label_rtx ();
15096 rtx op1 = gen_reg_rtx (XFmode);
15097 rtx op2 = gen_reg_rtx (XFmode);
15099 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15100 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15102 emit_label (label);
15104 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15105 ix86_emit_fp_unordered_jump (label);
15107 emit_insn (gen_truncxfsf2_noop (operands[0], op1));
15111 (define_expand "dremdf3"
15112 [(use (match_operand:DF 0 "register_operand" ""))
15113 (use (match_operand:DF 1 "register_operand" ""))
15114 (use (match_operand:DF 2 "register_operand" ""))]
15115 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15116 && flag_unsafe_math_optimizations"
15118 rtx label = gen_label_rtx ();
15120 rtx op1 = gen_reg_rtx (XFmode);
15121 rtx op2 = gen_reg_rtx (XFmode);
15123 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15124 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15126 emit_label (label);
15128 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15129 ix86_emit_fp_unordered_jump (label);
15131 emit_insn (gen_truncxfdf2_noop (operands[0], op1));
15135 (define_expand "dremxf3"
15136 [(use (match_operand:XF 0 "register_operand" ""))
15137 (use (match_operand:XF 1 "register_operand" ""))
15138 (use (match_operand:XF 2 "register_operand" ""))]
15139 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15140 && flag_unsafe_math_optimizations"
15142 rtx label = gen_label_rtx ();
15144 emit_label (label);
15146 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15147 operands[1], operands[2]));
15148 ix86_emit_fp_unordered_jump (label);
15150 emit_move_insn (operands[0], operands[1]);
15154 (define_insn "*sindf2"
15155 [(set (match_operand:DF 0 "register_operand" "=f")
15156 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15157 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15158 && flag_unsafe_math_optimizations"
15160 [(set_attr "type" "fpspc")
15161 (set_attr "mode" "DF")])
15163 (define_insn "*sinsf2"
15164 [(set (match_operand:SF 0 "register_operand" "=f")
15165 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15166 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15167 && flag_unsafe_math_optimizations"
15169 [(set_attr "type" "fpspc")
15170 (set_attr "mode" "SF")])
15172 (define_insn "*sinextendsfdf2"
15173 [(set (match_operand:DF 0 "register_operand" "=f")
15174 (unspec:DF [(float_extend:DF
15175 (match_operand:SF 1 "register_operand" "0"))]
15177 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15178 && flag_unsafe_math_optimizations"
15180 [(set_attr "type" "fpspc")
15181 (set_attr "mode" "DF")])
15183 (define_insn "*sinxf2"
15184 [(set (match_operand:XF 0 "register_operand" "=f")
15185 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15186 "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15187 && flag_unsafe_math_optimizations"
15189 [(set_attr "type" "fpspc")
15190 (set_attr "mode" "XF")])
15192 (define_insn "*cosdf2"
15193 [(set (match_operand:DF 0 "register_operand" "=f")
15194 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15195 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15196 && flag_unsafe_math_optimizations"
15198 [(set_attr "type" "fpspc")
15199 (set_attr "mode" "DF")])
15201 (define_insn "*cossf2"
15202 [(set (match_operand:SF 0 "register_operand" "=f")
15203 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15204 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15205 && flag_unsafe_math_optimizations"
15207 [(set_attr "type" "fpspc")
15208 (set_attr "mode" "SF")])
15210 (define_insn "*cosextendsfdf2"
15211 [(set (match_operand:DF 0 "register_operand" "=f")
15212 (unspec:DF [(float_extend:DF
15213 (match_operand:SF 1 "register_operand" "0"))]
15215 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15216 && flag_unsafe_math_optimizations"
15218 [(set_attr "type" "fpspc")
15219 (set_attr "mode" "DF")])
15221 (define_insn "*cosxf2"
15222 [(set (match_operand:XF 0 "register_operand" "=f")
15223 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15224 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15225 && flag_unsafe_math_optimizations"
15227 [(set_attr "type" "fpspc")
15228 (set_attr "mode" "XF")])
15230 ;; With sincos pattern defined, sin and cos builtin function will be
15231 ;; expanded to sincos pattern with one of its outputs left unused.
15232 ;; Cse pass will detected, if two sincos patterns can be combined,
15233 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15234 ;; depending on the unused output.
15236 (define_insn "sincosdf3"
15237 [(set (match_operand:DF 0 "register_operand" "=f")
15238 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15239 UNSPEC_SINCOS_COS))
15240 (set (match_operand:DF 1 "register_operand" "=u")
15241 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15242 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15243 && flag_unsafe_math_optimizations"
15245 [(set_attr "type" "fpspc")
15246 (set_attr "mode" "DF")])
15249 [(set (match_operand:DF 0 "register_operand" "")
15250 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15251 UNSPEC_SINCOS_COS))
15252 (set (match_operand:DF 1 "register_operand" "")
15253 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15254 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15255 && !reload_completed && !reload_in_progress"
15256 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15260 [(set (match_operand:DF 0 "register_operand" "")
15261 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15262 UNSPEC_SINCOS_COS))
15263 (set (match_operand:DF 1 "register_operand" "")
15264 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15265 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15266 && !reload_completed && !reload_in_progress"
15267 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15270 (define_insn "sincossf3"
15271 [(set (match_operand:SF 0 "register_operand" "=f")
15272 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15273 UNSPEC_SINCOS_COS))
15274 (set (match_operand:SF 1 "register_operand" "=u")
15275 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15276 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15277 && flag_unsafe_math_optimizations"
15279 [(set_attr "type" "fpspc")
15280 (set_attr "mode" "SF")])
15283 [(set (match_operand:SF 0 "register_operand" "")
15284 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15285 UNSPEC_SINCOS_COS))
15286 (set (match_operand:SF 1 "register_operand" "")
15287 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15288 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15289 && !reload_completed && !reload_in_progress"
15290 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15294 [(set (match_operand:SF 0 "register_operand" "")
15295 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15296 UNSPEC_SINCOS_COS))
15297 (set (match_operand:SF 1 "register_operand" "")
15298 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15299 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15300 && !reload_completed && !reload_in_progress"
15301 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15304 (define_insn "*sincosextendsfdf3"
15305 [(set (match_operand:DF 0 "register_operand" "=f")
15306 (unspec:DF [(float_extend:DF
15307 (match_operand:SF 2 "register_operand" "0"))]
15308 UNSPEC_SINCOS_COS))
15309 (set (match_operand:DF 1 "register_operand" "=u")
15310 (unspec:DF [(float_extend:DF
15311 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15312 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15313 && flag_unsafe_math_optimizations"
15315 [(set_attr "type" "fpspc")
15316 (set_attr "mode" "DF")])
15319 [(set (match_operand:DF 0 "register_operand" "")
15320 (unspec:DF [(float_extend:DF
15321 (match_operand:SF 2 "register_operand" ""))]
15322 UNSPEC_SINCOS_COS))
15323 (set (match_operand:DF 1 "register_operand" "")
15324 (unspec:DF [(float_extend:DF
15325 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15326 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15327 && !reload_completed && !reload_in_progress"
15328 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15329 (match_dup 2))] UNSPEC_SIN))]
15333 [(set (match_operand:DF 0 "register_operand" "")
15334 (unspec:DF [(float_extend:DF
15335 (match_operand:SF 2 "register_operand" ""))]
15336 UNSPEC_SINCOS_COS))
15337 (set (match_operand:DF 1 "register_operand" "")
15338 (unspec:DF [(float_extend:DF
15339 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15340 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15341 && !reload_completed && !reload_in_progress"
15342 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15343 (match_dup 2))] UNSPEC_COS))]
15346 (define_insn "sincosxf3"
15347 [(set (match_operand:XF 0 "register_operand" "=f")
15348 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15349 UNSPEC_SINCOS_COS))
15350 (set (match_operand:XF 1 "register_operand" "=u")
15351 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15352 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15353 && flag_unsafe_math_optimizations"
15355 [(set_attr "type" "fpspc")
15356 (set_attr "mode" "XF")])
15359 [(set (match_operand:XF 0 "register_operand" "")
15360 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15361 UNSPEC_SINCOS_COS))
15362 (set (match_operand:XF 1 "register_operand" "")
15363 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15364 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15365 && !reload_completed && !reload_in_progress"
15366 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15370 [(set (match_operand:XF 0 "register_operand" "")
15371 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15372 UNSPEC_SINCOS_COS))
15373 (set (match_operand:XF 1 "register_operand" "")
15374 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15375 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15376 && !reload_completed && !reload_in_progress"
15377 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15380 (define_insn "*tandf3_1"
15381 [(set (match_operand:DF 0 "register_operand" "=f")
15382 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15384 (set (match_operand:DF 1 "register_operand" "=u")
15385 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15386 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15387 && flag_unsafe_math_optimizations"
15389 [(set_attr "type" "fpspc")
15390 (set_attr "mode" "DF")])
15392 ;; optimize sequence: fptan
15395 ;; into fptan insn.
15398 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15399 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15401 (set (match_operand:DF 1 "register_operand" "")
15402 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15404 (match_operand:DF 3 "immediate_operand" ""))]
15405 "standard_80387_constant_p (operands[3]) == 2"
15406 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15407 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15410 (define_expand "tandf2"
15411 [(parallel [(set (match_dup 2)
15412 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15414 (set (match_operand:DF 0 "register_operand" "")
15415 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15416 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15417 && flag_unsafe_math_optimizations"
15419 operands[2] = gen_reg_rtx (DFmode);
15422 (define_insn "*tansf3_1"
15423 [(set (match_operand:SF 0 "register_operand" "=f")
15424 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15426 (set (match_operand:SF 1 "register_operand" "=u")
15427 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15428 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15429 && flag_unsafe_math_optimizations"
15431 [(set_attr "type" "fpspc")
15432 (set_attr "mode" "SF")])
15434 ;; optimize sequence: fptan
15437 ;; into fptan insn.
15440 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15441 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15443 (set (match_operand:SF 1 "register_operand" "")
15444 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15446 (match_operand:SF 3 "immediate_operand" ""))]
15447 "standard_80387_constant_p (operands[3]) == 2"
15448 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15449 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15452 (define_expand "tansf2"
15453 [(parallel [(set (match_dup 2)
15454 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15456 (set (match_operand:SF 0 "register_operand" "")
15457 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15458 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15459 && flag_unsafe_math_optimizations"
15461 operands[2] = gen_reg_rtx (SFmode);
15464 (define_insn "*tanxf3_1"
15465 [(set (match_operand:XF 0 "register_operand" "=f")
15466 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15468 (set (match_operand:XF 1 "register_operand" "=u")
15469 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15470 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15471 && flag_unsafe_math_optimizations"
15473 [(set_attr "type" "fpspc")
15474 (set_attr "mode" "XF")])
15476 ;; optimize sequence: fptan
15479 ;; into fptan insn.
15482 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15483 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15485 (set (match_operand:XF 1 "register_operand" "")
15486 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15488 (match_operand:XF 3 "immediate_operand" ""))]
15489 "standard_80387_constant_p (operands[3]) == 2"
15490 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15491 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15494 (define_expand "tanxf2"
15495 [(parallel [(set (match_dup 2)
15496 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15498 (set (match_operand:XF 0 "register_operand" "")
15499 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15500 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15501 && flag_unsafe_math_optimizations"
15503 operands[2] = gen_reg_rtx (XFmode);
15506 (define_insn "atan2df3_1"
15507 [(set (match_operand:DF 0 "register_operand" "=f")
15508 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15509 (match_operand:DF 1 "register_operand" "u")]
15511 (clobber (match_scratch:DF 3 "=1"))]
15512 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15513 && flag_unsafe_math_optimizations"
15515 [(set_attr "type" "fpspc")
15516 (set_attr "mode" "DF")])
15518 (define_expand "atan2df3"
15519 [(use (match_operand:DF 0 "register_operand" "=f"))
15520 (use (match_operand:DF 2 "register_operand" "0"))
15521 (use (match_operand:DF 1 "register_operand" "u"))]
15522 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15523 && flag_unsafe_math_optimizations"
15525 rtx copy = gen_reg_rtx (DFmode);
15526 emit_move_insn (copy, operands[1]);
15527 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15531 (define_expand "atandf2"
15532 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15533 (unspec:DF [(match_dup 2)
15534 (match_operand:DF 1 "register_operand" "")]
15536 (clobber (match_scratch:DF 3 ""))])]
15537 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15538 && flag_unsafe_math_optimizations"
15540 operands[2] = gen_reg_rtx (DFmode);
15541 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15544 (define_insn "atan2sf3_1"
15545 [(set (match_operand:SF 0 "register_operand" "=f")
15546 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15547 (match_operand:SF 1 "register_operand" "u")]
15549 (clobber (match_scratch:SF 3 "=1"))]
15550 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15551 && flag_unsafe_math_optimizations"
15553 [(set_attr "type" "fpspc")
15554 (set_attr "mode" "SF")])
15556 (define_expand "atan2sf3"
15557 [(use (match_operand:SF 0 "register_operand" "=f"))
15558 (use (match_operand:SF 2 "register_operand" "0"))
15559 (use (match_operand:SF 1 "register_operand" "u"))]
15560 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15561 && flag_unsafe_math_optimizations"
15563 rtx copy = gen_reg_rtx (SFmode);
15564 emit_move_insn (copy, operands[1]);
15565 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15569 (define_expand "atansf2"
15570 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15571 (unspec:SF [(match_dup 2)
15572 (match_operand:SF 1 "register_operand" "")]
15574 (clobber (match_scratch:SF 3 ""))])]
15575 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15576 && flag_unsafe_math_optimizations"
15578 operands[2] = gen_reg_rtx (SFmode);
15579 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15582 (define_insn "atan2xf3_1"
15583 [(set (match_operand:XF 0 "register_operand" "=f")
15584 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15585 (match_operand:XF 1 "register_operand" "u")]
15587 (clobber (match_scratch:XF 3 "=1"))]
15588 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15589 && flag_unsafe_math_optimizations"
15591 [(set_attr "type" "fpspc")
15592 (set_attr "mode" "XF")])
15594 (define_expand "atan2xf3"
15595 [(use (match_operand:XF 0 "register_operand" "=f"))
15596 (use (match_operand:XF 2 "register_operand" "0"))
15597 (use (match_operand:XF 1 "register_operand" "u"))]
15598 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15599 && flag_unsafe_math_optimizations"
15601 rtx copy = gen_reg_rtx (XFmode);
15602 emit_move_insn (copy, operands[1]);
15603 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15607 (define_expand "atanxf2"
15608 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15609 (unspec:XF [(match_dup 2)
15610 (match_operand:XF 1 "register_operand" "")]
15612 (clobber (match_scratch:XF 3 ""))])]
15613 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15614 && flag_unsafe_math_optimizations"
15616 operands[2] = gen_reg_rtx (XFmode);
15617 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15620 (define_expand "asindf2"
15621 [(set (match_dup 2)
15622 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15623 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15624 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15625 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15626 (parallel [(set (match_dup 7)
15627 (unspec:XF [(match_dup 6) (match_dup 2)]
15629 (clobber (match_scratch:XF 8 ""))])
15630 (set (match_operand:DF 0 "register_operand" "")
15631 (float_truncate:DF (match_dup 7)))]
15632 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15633 && flag_unsafe_math_optimizations"
15637 for (i=2; i<8; i++)
15638 operands[i] = gen_reg_rtx (XFmode);
15640 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15643 (define_expand "asinsf2"
15644 [(set (match_dup 2)
15645 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15646 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15647 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15648 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15649 (parallel [(set (match_dup 7)
15650 (unspec:XF [(match_dup 6) (match_dup 2)]
15652 (clobber (match_scratch:XF 8 ""))])
15653 (set (match_operand:SF 0 "register_operand" "")
15654 (float_truncate:SF (match_dup 7)))]
15655 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15656 && flag_unsafe_math_optimizations"
15660 for (i=2; i<8; i++)
15661 operands[i] = gen_reg_rtx (XFmode);
15663 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15666 (define_expand "asinxf2"
15667 [(set (match_dup 2)
15668 (mult:XF (match_operand:XF 1 "register_operand" "")
15670 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15671 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15672 (parallel [(set (match_operand:XF 0 "register_operand" "")
15673 (unspec:XF [(match_dup 5) (match_dup 1)]
15675 (clobber (match_scratch:XF 6 ""))])]
15676 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15677 && flag_unsafe_math_optimizations"
15681 for (i=2; i<6; i++)
15682 operands[i] = gen_reg_rtx (XFmode);
15684 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15687 (define_expand "acosdf2"
15688 [(set (match_dup 2)
15689 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15690 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15691 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15692 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15693 (parallel [(set (match_dup 7)
15694 (unspec:XF [(match_dup 2) (match_dup 6)]
15696 (clobber (match_scratch:XF 8 ""))])
15697 (set (match_operand:DF 0 "register_operand" "")
15698 (float_truncate:DF (match_dup 7)))]
15699 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15700 && flag_unsafe_math_optimizations"
15704 for (i=2; i<8; i++)
15705 operands[i] = gen_reg_rtx (XFmode);
15707 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15710 (define_expand "acossf2"
15711 [(set (match_dup 2)
15712 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15713 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15714 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15715 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15716 (parallel [(set (match_dup 7)
15717 (unspec:XF [(match_dup 2) (match_dup 6)]
15719 (clobber (match_scratch:XF 8 ""))])
15720 (set (match_operand:SF 0 "register_operand" "")
15721 (float_truncate:SF (match_dup 7)))]
15722 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15723 && flag_unsafe_math_optimizations"
15727 for (i=2; i<8; i++)
15728 operands[i] = gen_reg_rtx (XFmode);
15730 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15733 (define_expand "acosxf2"
15734 [(set (match_dup 2)
15735 (mult:XF (match_operand:XF 1 "register_operand" "")
15737 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15738 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15739 (parallel [(set (match_operand:XF 0 "register_operand" "")
15740 (unspec:XF [(match_dup 1) (match_dup 5)]
15742 (clobber (match_scratch:XF 6 ""))])]
15743 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15744 && flag_unsafe_math_optimizations"
15748 for (i=2; i<6; i++)
15749 operands[i] = gen_reg_rtx (XFmode);
15751 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15754 (define_insn "fyl2x_xf3"
15755 [(set (match_operand:XF 0 "register_operand" "=f")
15756 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15757 (match_operand:XF 1 "register_operand" "u")]
15759 (clobber (match_scratch:XF 3 "=1"))]
15760 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15761 && flag_unsafe_math_optimizations"
15763 [(set_attr "type" "fpspc")
15764 (set_attr "mode" "XF")])
15766 (define_expand "logsf2"
15767 [(set (match_dup 2)
15768 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15769 (parallel [(set (match_dup 4)
15770 (unspec:XF [(match_dup 2)
15771 (match_dup 3)] UNSPEC_FYL2X))
15772 (clobber (match_scratch:XF 5 ""))])
15773 (set (match_operand:SF 0 "register_operand" "")
15774 (float_truncate:SF (match_dup 4)))]
15775 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15776 && flag_unsafe_math_optimizations"
15780 operands[2] = gen_reg_rtx (XFmode);
15781 operands[3] = gen_reg_rtx (XFmode);
15782 operands[4] = gen_reg_rtx (XFmode);
15784 temp = standard_80387_constant_rtx (4); /* fldln2 */
15785 emit_move_insn (operands[3], temp);
15788 (define_expand "logdf2"
15789 [(set (match_dup 2)
15790 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15791 (parallel [(set (match_dup 4)
15792 (unspec:XF [(match_dup 2)
15793 (match_dup 3)] UNSPEC_FYL2X))
15794 (clobber (match_scratch:XF 5 ""))])
15795 (set (match_operand:DF 0 "register_operand" "")
15796 (float_truncate:DF (match_dup 4)))]
15797 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15798 && flag_unsafe_math_optimizations"
15802 operands[2] = gen_reg_rtx (XFmode);
15803 operands[3] = gen_reg_rtx (XFmode);
15804 operands[4] = gen_reg_rtx (XFmode);
15806 temp = standard_80387_constant_rtx (4); /* fldln2 */
15807 emit_move_insn (operands[3], temp);
15810 (define_expand "logxf2"
15811 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15812 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15813 (match_dup 2)] UNSPEC_FYL2X))
15814 (clobber (match_scratch:XF 3 ""))])]
15815 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15816 && flag_unsafe_math_optimizations"
15820 operands[2] = gen_reg_rtx (XFmode);
15821 temp = standard_80387_constant_rtx (4); /* fldln2 */
15822 emit_move_insn (operands[2], temp);
15825 (define_expand "log10sf2"
15826 [(set (match_dup 2)
15827 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15828 (parallel [(set (match_dup 4)
15829 (unspec:XF [(match_dup 2)
15830 (match_dup 3)] UNSPEC_FYL2X))
15831 (clobber (match_scratch:XF 5 ""))])
15832 (set (match_operand:SF 0 "register_operand" "")
15833 (float_truncate:SF (match_dup 4)))]
15834 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15835 && flag_unsafe_math_optimizations"
15839 operands[2] = gen_reg_rtx (XFmode);
15840 operands[3] = gen_reg_rtx (XFmode);
15841 operands[4] = gen_reg_rtx (XFmode);
15843 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15844 emit_move_insn (operands[3], temp);
15847 (define_expand "log10df2"
15848 [(set (match_dup 2)
15849 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15850 (parallel [(set (match_dup 4)
15851 (unspec:XF [(match_dup 2)
15852 (match_dup 3)] UNSPEC_FYL2X))
15853 (clobber (match_scratch:XF 5 ""))])
15854 (set (match_operand:DF 0 "register_operand" "")
15855 (float_truncate:DF (match_dup 4)))]
15856 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15857 && flag_unsafe_math_optimizations"
15861 operands[2] = gen_reg_rtx (XFmode);
15862 operands[3] = gen_reg_rtx (XFmode);
15863 operands[4] = gen_reg_rtx (XFmode);
15865 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15866 emit_move_insn (operands[3], temp);
15869 (define_expand "log10xf2"
15870 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15871 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15872 (match_dup 2)] UNSPEC_FYL2X))
15873 (clobber (match_scratch:XF 3 ""))])]
15874 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15875 && flag_unsafe_math_optimizations"
15879 operands[2] = gen_reg_rtx (XFmode);
15880 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15881 emit_move_insn (operands[2], temp);
15884 (define_expand "log2sf2"
15885 [(set (match_dup 2)
15886 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15887 (parallel [(set (match_dup 4)
15888 (unspec:XF [(match_dup 2)
15889 (match_dup 3)] UNSPEC_FYL2X))
15890 (clobber (match_scratch:XF 5 ""))])
15891 (set (match_operand:SF 0 "register_operand" "")
15892 (float_truncate:SF (match_dup 4)))]
15893 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15894 && flag_unsafe_math_optimizations"
15896 operands[2] = gen_reg_rtx (XFmode);
15897 operands[3] = gen_reg_rtx (XFmode);
15898 operands[4] = gen_reg_rtx (XFmode);
15900 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15903 (define_expand "log2df2"
15904 [(set (match_dup 2)
15905 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15906 (parallel [(set (match_dup 4)
15907 (unspec:XF [(match_dup 2)
15908 (match_dup 3)] UNSPEC_FYL2X))
15909 (clobber (match_scratch:XF 5 ""))])
15910 (set (match_operand:DF 0 "register_operand" "")
15911 (float_truncate:DF (match_dup 4)))]
15912 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15913 && flag_unsafe_math_optimizations"
15915 operands[2] = gen_reg_rtx (XFmode);
15916 operands[3] = gen_reg_rtx (XFmode);
15917 operands[4] = gen_reg_rtx (XFmode);
15919 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15922 (define_expand "log2xf2"
15923 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15924 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15925 (match_dup 2)] UNSPEC_FYL2X))
15926 (clobber (match_scratch:XF 3 ""))])]
15927 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15928 && flag_unsafe_math_optimizations"
15930 operands[2] = gen_reg_rtx (XFmode);
15931 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15934 (define_insn "fyl2xp1_xf3"
15935 [(set (match_operand:XF 0 "register_operand" "=f")
15936 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15937 (match_operand:XF 1 "register_operand" "u")]
15939 (clobber (match_scratch:XF 3 "=1"))]
15940 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15941 && flag_unsafe_math_optimizations"
15943 [(set_attr "type" "fpspc")
15944 (set_attr "mode" "XF")])
15946 (define_expand "log1psf2"
15947 [(use (match_operand:XF 0 "register_operand" ""))
15948 (use (match_operand:XF 1 "register_operand" ""))]
15949 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15950 && flag_unsafe_math_optimizations"
15952 rtx op0 = gen_reg_rtx (XFmode);
15953 rtx op1 = gen_reg_rtx (XFmode);
15955 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15956 ix86_emit_i387_log1p (op0, op1);
15957 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
15961 (define_expand "log1pdf2"
15962 [(use (match_operand:XF 0 "register_operand" ""))
15963 (use (match_operand:XF 1 "register_operand" ""))]
15964 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15965 && flag_unsafe_math_optimizations"
15967 rtx op0 = gen_reg_rtx (XFmode);
15968 rtx op1 = gen_reg_rtx (XFmode);
15970 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15971 ix86_emit_i387_log1p (op0, op1);
15972 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
15976 (define_expand "log1pxf2"
15977 [(use (match_operand:XF 0 "register_operand" ""))
15978 (use (match_operand:XF 1 "register_operand" ""))]
15979 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15980 && flag_unsafe_math_optimizations"
15982 ix86_emit_i387_log1p (operands[0], operands[1]);
15986 (define_insn "*fxtractxf3"
15987 [(set (match_operand:XF 0 "register_operand" "=f")
15988 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15989 UNSPEC_XTRACT_FRACT))
15990 (set (match_operand:XF 1 "register_operand" "=u")
15991 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15992 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15993 && flag_unsafe_math_optimizations"
15995 [(set_attr "type" "fpspc")
15996 (set_attr "mode" "XF")])
15998 (define_expand "logbsf2"
15999 [(set (match_dup 2)
16000 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16001 (parallel [(set (match_dup 3)
16002 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16004 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16005 (set (match_operand:SF 0 "register_operand" "")
16006 (float_truncate:SF (match_dup 4)))]
16007 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16008 && flag_unsafe_math_optimizations"
16010 operands[2] = gen_reg_rtx (XFmode);
16011 operands[3] = gen_reg_rtx (XFmode);
16012 operands[4] = gen_reg_rtx (XFmode);
16015 (define_expand "logbdf2"
16016 [(set (match_dup 2)
16017 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16018 (parallel [(set (match_dup 3)
16019 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16021 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16022 (set (match_operand:DF 0 "register_operand" "")
16023 (float_truncate:DF (match_dup 4)))]
16024 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16025 && flag_unsafe_math_optimizations"
16027 operands[2] = gen_reg_rtx (XFmode);
16028 operands[3] = gen_reg_rtx (XFmode);
16029 operands[4] = gen_reg_rtx (XFmode);
16032 (define_expand "logbxf2"
16033 [(parallel [(set (match_dup 2)
16034 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16035 UNSPEC_XTRACT_FRACT))
16036 (set (match_operand:XF 0 "register_operand" "")
16037 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16038 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16039 && flag_unsafe_math_optimizations"
16041 operands[2] = gen_reg_rtx (XFmode);
16044 (define_expand "ilogbsi2"
16045 [(parallel [(set (match_dup 2)
16046 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16047 UNSPEC_XTRACT_FRACT))
16048 (set (match_operand:XF 3 "register_operand" "")
16049 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16050 (parallel [(set (match_operand:SI 0 "register_operand" "")
16051 (fix:SI (match_dup 3)))
16052 (clobber (reg:CC FLAGS_REG))])]
16053 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16054 && flag_unsafe_math_optimizations"
16056 operands[2] = gen_reg_rtx (XFmode);
16057 operands[3] = gen_reg_rtx (XFmode);
16060 (define_insn "*f2xm1xf2"
16061 [(set (match_operand:XF 0 "register_operand" "=f")
16062 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16064 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16065 && flag_unsafe_math_optimizations"
16067 [(set_attr "type" "fpspc")
16068 (set_attr "mode" "XF")])
16070 (define_insn "*fscalexf4"
16071 [(set (match_operand:XF 0 "register_operand" "=f")
16072 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16073 (match_operand:XF 3 "register_operand" "1")]
16074 UNSPEC_FSCALE_FRACT))
16075 (set (match_operand:XF 1 "register_operand" "=u")
16076 (unspec:XF [(match_dup 2) (match_dup 3)]
16077 UNSPEC_FSCALE_EXP))]
16078 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16079 && flag_unsafe_math_optimizations"
16081 [(set_attr "type" "fpspc")
16082 (set_attr "mode" "XF")])
16084 (define_expand "expsf2"
16085 [(set (match_dup 2)
16086 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16087 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16088 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16089 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16090 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16091 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16092 (parallel [(set (match_dup 10)
16093 (unspec:XF [(match_dup 9) (match_dup 5)]
16094 UNSPEC_FSCALE_FRACT))
16095 (set (match_dup 11)
16096 (unspec:XF [(match_dup 9) (match_dup 5)]
16097 UNSPEC_FSCALE_EXP))])
16098 (set (match_operand:SF 0 "register_operand" "")
16099 (float_truncate:SF (match_dup 10)))]
16100 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16101 && flag_unsafe_math_optimizations"
16106 for (i=2; i<12; i++)
16107 operands[i] = gen_reg_rtx (XFmode);
16108 temp = standard_80387_constant_rtx (5); /* fldl2e */
16109 emit_move_insn (operands[3], temp);
16110 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16113 (define_expand "expdf2"
16114 [(set (match_dup 2)
16115 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16116 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16117 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16118 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16119 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16120 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16121 (parallel [(set (match_dup 10)
16122 (unspec:XF [(match_dup 9) (match_dup 5)]
16123 UNSPEC_FSCALE_FRACT))
16124 (set (match_dup 11)
16125 (unspec:XF [(match_dup 9) (match_dup 5)]
16126 UNSPEC_FSCALE_EXP))])
16127 (set (match_operand:DF 0 "register_operand" "")
16128 (float_truncate:DF (match_dup 10)))]
16129 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16130 && flag_unsafe_math_optimizations"
16135 for (i=2; i<12; i++)
16136 operands[i] = gen_reg_rtx (XFmode);
16137 temp = standard_80387_constant_rtx (5); /* fldl2e */
16138 emit_move_insn (operands[3], temp);
16139 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16142 (define_expand "expxf2"
16143 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16145 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16146 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16147 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16148 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16149 (parallel [(set (match_operand:XF 0 "register_operand" "")
16150 (unspec:XF [(match_dup 8) (match_dup 4)]
16151 UNSPEC_FSCALE_FRACT))
16153 (unspec:XF [(match_dup 8) (match_dup 4)]
16154 UNSPEC_FSCALE_EXP))])]
16155 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16156 && flag_unsafe_math_optimizations"
16161 for (i=2; i<10; i++)
16162 operands[i] = gen_reg_rtx (XFmode);
16163 temp = standard_80387_constant_rtx (5); /* fldl2e */
16164 emit_move_insn (operands[2], temp);
16165 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16168 (define_expand "exp10sf2"
16169 [(set (match_dup 2)
16170 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16171 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16172 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16173 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16174 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16175 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16176 (parallel [(set (match_dup 10)
16177 (unspec:XF [(match_dup 9) (match_dup 5)]
16178 UNSPEC_FSCALE_FRACT))
16179 (set (match_dup 11)
16180 (unspec:XF [(match_dup 9) (match_dup 5)]
16181 UNSPEC_FSCALE_EXP))])
16182 (set (match_operand:SF 0 "register_operand" "")
16183 (float_truncate:SF (match_dup 10)))]
16184 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16185 && flag_unsafe_math_optimizations"
16190 for (i=2; i<12; i++)
16191 operands[i] = gen_reg_rtx (XFmode);
16192 temp = standard_80387_constant_rtx (6); /* fldl2t */
16193 emit_move_insn (operands[3], temp);
16194 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16197 (define_expand "exp10df2"
16198 [(set (match_dup 2)
16199 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16200 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16201 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16202 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16203 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16204 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16205 (parallel [(set (match_dup 10)
16206 (unspec:XF [(match_dup 9) (match_dup 5)]
16207 UNSPEC_FSCALE_FRACT))
16208 (set (match_dup 11)
16209 (unspec:XF [(match_dup 9) (match_dup 5)]
16210 UNSPEC_FSCALE_EXP))])
16211 (set (match_operand:DF 0 "register_operand" "")
16212 (float_truncate:DF (match_dup 10)))]
16213 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16214 && flag_unsafe_math_optimizations"
16219 for (i=2; i<12; i++)
16220 operands[i] = gen_reg_rtx (XFmode);
16221 temp = standard_80387_constant_rtx (6); /* fldl2t */
16222 emit_move_insn (operands[3], temp);
16223 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16226 (define_expand "exp10xf2"
16227 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16229 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16230 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16231 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16232 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16233 (parallel [(set (match_operand:XF 0 "register_operand" "")
16234 (unspec:XF [(match_dup 8) (match_dup 4)]
16235 UNSPEC_FSCALE_FRACT))
16237 (unspec:XF [(match_dup 8) (match_dup 4)]
16238 UNSPEC_FSCALE_EXP))])]
16239 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16240 && flag_unsafe_math_optimizations"
16245 for (i=2; i<10; i++)
16246 operands[i] = gen_reg_rtx (XFmode);
16247 temp = standard_80387_constant_rtx (6); /* fldl2t */
16248 emit_move_insn (operands[2], temp);
16249 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16252 (define_expand "exp2sf2"
16253 [(set (match_dup 2)
16254 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16255 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16256 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16257 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16258 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16259 (parallel [(set (match_dup 8)
16260 (unspec:XF [(match_dup 7) (match_dup 3)]
16261 UNSPEC_FSCALE_FRACT))
16263 (unspec:XF [(match_dup 7) (match_dup 3)]
16264 UNSPEC_FSCALE_EXP))])
16265 (set (match_operand:SF 0 "register_operand" "")
16266 (float_truncate:SF (match_dup 8)))]
16267 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16268 && flag_unsafe_math_optimizations"
16272 for (i=2; i<10; i++)
16273 operands[i] = gen_reg_rtx (XFmode);
16274 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16277 (define_expand "exp2df2"
16278 [(set (match_dup 2)
16279 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16280 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16281 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16282 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16283 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16284 (parallel [(set (match_dup 8)
16285 (unspec:XF [(match_dup 7) (match_dup 3)]
16286 UNSPEC_FSCALE_FRACT))
16288 (unspec:XF [(match_dup 7) (match_dup 3)]
16289 UNSPEC_FSCALE_EXP))])
16290 (set (match_operand:DF 0 "register_operand" "")
16291 (float_truncate:DF (match_dup 8)))]
16292 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16293 && flag_unsafe_math_optimizations"
16297 for (i=2; i<10; i++)
16298 operands[i] = gen_reg_rtx (XFmode);
16299 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16302 (define_expand "exp2xf2"
16303 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16304 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16305 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16306 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16307 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16308 (parallel [(set (match_operand:XF 0 "register_operand" "")
16309 (unspec:XF [(match_dup 7) (match_dup 3)]
16310 UNSPEC_FSCALE_FRACT))
16312 (unspec:XF [(match_dup 7) (match_dup 3)]
16313 UNSPEC_FSCALE_EXP))])]
16314 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16315 && flag_unsafe_math_optimizations"
16319 for (i=2; i<9; i++)
16320 operands[i] = gen_reg_rtx (XFmode);
16321 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16324 (define_expand "expm1df2"
16325 [(set (match_dup 2)
16326 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16327 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16328 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16329 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16330 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16331 (parallel [(set (match_dup 8)
16332 (unspec:XF [(match_dup 7) (match_dup 5)]
16333 UNSPEC_FSCALE_FRACT))
16335 (unspec:XF [(match_dup 7) (match_dup 5)]
16336 UNSPEC_FSCALE_EXP))])
16337 (parallel [(set (match_dup 11)
16338 (unspec:XF [(match_dup 10) (match_dup 9)]
16339 UNSPEC_FSCALE_FRACT))
16340 (set (match_dup 12)
16341 (unspec:XF [(match_dup 10) (match_dup 9)]
16342 UNSPEC_FSCALE_EXP))])
16343 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16344 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16345 (set (match_operand:DF 0 "register_operand" "")
16346 (float_truncate:DF (match_dup 14)))]
16347 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16348 && flag_unsafe_math_optimizations"
16353 for (i=2; i<15; i++)
16354 operands[i] = gen_reg_rtx (XFmode);
16355 temp = standard_80387_constant_rtx (5); /* fldl2e */
16356 emit_move_insn (operands[3], temp);
16357 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16360 (define_expand "expm1sf2"
16361 [(set (match_dup 2)
16362 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16363 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16364 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16365 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16366 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16367 (parallel [(set (match_dup 8)
16368 (unspec:XF [(match_dup 7) (match_dup 5)]
16369 UNSPEC_FSCALE_FRACT))
16371 (unspec:XF [(match_dup 7) (match_dup 5)]
16372 UNSPEC_FSCALE_EXP))])
16373 (parallel [(set (match_dup 11)
16374 (unspec:XF [(match_dup 10) (match_dup 9)]
16375 UNSPEC_FSCALE_FRACT))
16376 (set (match_dup 12)
16377 (unspec:XF [(match_dup 10) (match_dup 9)]
16378 UNSPEC_FSCALE_EXP))])
16379 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16380 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16381 (set (match_operand:SF 0 "register_operand" "")
16382 (float_truncate:SF (match_dup 14)))]
16383 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16384 && flag_unsafe_math_optimizations"
16389 for (i=2; i<15; i++)
16390 operands[i] = gen_reg_rtx (XFmode);
16391 temp = standard_80387_constant_rtx (5); /* fldl2e */
16392 emit_move_insn (operands[3], temp);
16393 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16396 (define_expand "expm1xf2"
16397 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16399 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16400 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16401 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16402 (parallel [(set (match_dup 7)
16403 (unspec:XF [(match_dup 6) (match_dup 4)]
16404 UNSPEC_FSCALE_FRACT))
16406 (unspec:XF [(match_dup 6) (match_dup 4)]
16407 UNSPEC_FSCALE_EXP))])
16408 (parallel [(set (match_dup 10)
16409 (unspec:XF [(match_dup 9) (match_dup 8)]
16410 UNSPEC_FSCALE_FRACT))
16411 (set (match_dup 11)
16412 (unspec:XF [(match_dup 9) (match_dup 8)]
16413 UNSPEC_FSCALE_EXP))])
16414 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16415 (set (match_operand:XF 0 "register_operand" "")
16416 (plus:XF (match_dup 12) (match_dup 7)))]
16417 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16418 && flag_unsafe_math_optimizations"
16423 for (i=2; i<13; i++)
16424 operands[i] = gen_reg_rtx (XFmode);
16425 temp = standard_80387_constant_rtx (5); /* fldl2e */
16426 emit_move_insn (operands[2], temp);
16427 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16431 (define_insn "frndintxf2"
16432 [(set (match_operand:XF 0 "register_operand" "=f")
16433 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16435 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16436 && flag_unsafe_math_optimizations"
16438 [(set_attr "type" "fpspc")
16439 (set_attr "mode" "XF")])
16441 (define_expand "rintdf2"
16442 [(use (match_operand:DF 0 "register_operand" ""))
16443 (use (match_operand:DF 1 "register_operand" ""))]
16444 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16445 && flag_unsafe_math_optimizations"
16447 rtx op0 = gen_reg_rtx (XFmode);
16448 rtx op1 = gen_reg_rtx (XFmode);
16450 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16451 emit_insn (gen_frndintxf2 (op0, op1));
16453 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16457 (define_expand "rintsf2"
16458 [(use (match_operand:SF 0 "register_operand" ""))
16459 (use (match_operand:SF 1 "register_operand" ""))]
16460 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16461 && flag_unsafe_math_optimizations"
16463 rtx op0 = gen_reg_rtx (XFmode);
16464 rtx op1 = gen_reg_rtx (XFmode);
16466 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16467 emit_insn (gen_frndintxf2 (op0, op1));
16469 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16473 (define_expand "rintxf2"
16474 [(use (match_operand:XF 0 "register_operand" ""))
16475 (use (match_operand:XF 1 "register_operand" ""))]
16476 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16477 && flag_unsafe_math_optimizations"
16479 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16483 (define_insn "frndintxf2_floor"
16484 [(set (match_operand:XF 0 "register_operand" "=f")
16485 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16486 UNSPEC_FRNDINT_FLOOR))
16487 (use (match_operand:HI 2 "memory_operand" "m"))
16488 (use (match_operand:HI 3 "memory_operand" "m"))]
16489 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16490 && flag_unsafe_math_optimizations"
16491 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16492 [(set_attr "type" "frndint")
16493 (set_attr "i387_cw" "floor")
16494 (set_attr "mode" "XF")])
16496 (define_expand "floordf2"
16497 [(use (match_operand:DF 0 "register_operand" ""))
16498 (use (match_operand:DF 1 "register_operand" ""))]
16499 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16500 && flag_unsafe_math_optimizations"
16502 rtx op0 = gen_reg_rtx (XFmode);
16503 rtx op1 = gen_reg_rtx (XFmode);
16504 rtx op2 = assign_386_stack_local (HImode, 1);
16505 rtx op3 = assign_386_stack_local (HImode, 2);
16507 ix86_optimize_mode_switching = 1;
16509 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16510 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16512 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16516 (define_expand "floorsf2"
16517 [(use (match_operand:SF 0 "register_operand" ""))
16518 (use (match_operand:SF 1 "register_operand" ""))]
16519 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16520 && flag_unsafe_math_optimizations"
16522 rtx op0 = gen_reg_rtx (XFmode);
16523 rtx op1 = gen_reg_rtx (XFmode);
16524 rtx op2 = assign_386_stack_local (HImode, 1);
16525 rtx op3 = assign_386_stack_local (HImode, 2);
16527 ix86_optimize_mode_switching = 1;
16529 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16530 emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
16532 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16536 (define_expand "floorxf2"
16537 [(use (match_operand:XF 0 "register_operand" ""))
16538 (use (match_operand:XF 1 "register_operand" ""))]
16539 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16540 && flag_unsafe_math_optimizations"
16542 rtx op2 = assign_386_stack_local (HImode, 1);
16543 rtx op3 = assign_386_stack_local (HImode, 2);
16545 ix86_optimize_mode_switching = 1;
16547 emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
16551 (define_insn "frndintxf2_ceil"
16552 [(set (match_operand:XF 0 "register_operand" "=f")
16553 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16554 UNSPEC_FRNDINT_CEIL))
16555 (use (match_operand:HI 2 "memory_operand" "m"))
16556 (use (match_operand:HI 3 "memory_operand" "m"))]
16557 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16558 && flag_unsafe_math_optimizations"
16559 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16560 [(set_attr "type" "frndint")
16561 (set_attr "i387_cw" "ceil")
16562 (set_attr "mode" "XF")])
16564 (define_expand "ceildf2"
16565 [(use (match_operand:DF 0 "register_operand" ""))
16566 (use (match_operand:DF 1 "register_operand" ""))]
16567 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16568 && flag_unsafe_math_optimizations"
16570 rtx op0 = gen_reg_rtx (XFmode);
16571 rtx op1 = gen_reg_rtx (XFmode);
16572 rtx op2 = assign_386_stack_local (HImode, 1);
16573 rtx op3 = assign_386_stack_local (HImode, 2);
16575 ix86_optimize_mode_switching = 1;
16577 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16578 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16580 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16584 (define_expand "ceilsf2"
16585 [(use (match_operand:SF 0 "register_operand" ""))
16586 (use (match_operand:SF 1 "register_operand" ""))]
16587 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16588 && flag_unsafe_math_optimizations"
16590 rtx op0 = gen_reg_rtx (XFmode);
16591 rtx op1 = gen_reg_rtx (XFmode);
16592 rtx op2 = assign_386_stack_local (HImode, 1);
16593 rtx op3 = assign_386_stack_local (HImode, 2);
16595 ix86_optimize_mode_switching = 1;
16597 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16598 emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
16600 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16604 (define_expand "ceilxf2"
16605 [(use (match_operand:XF 0 "register_operand" ""))
16606 (use (match_operand:XF 1 "register_operand" ""))]
16607 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16608 && flag_unsafe_math_optimizations"
16610 rtx op2 = assign_386_stack_local (HImode, 1);
16611 rtx op3 = assign_386_stack_local (HImode, 2);
16613 ix86_optimize_mode_switching = 1;
16615 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
16619 (define_insn "frndintxf2_trunc"
16620 [(set (match_operand:XF 0 "register_operand" "=f")
16621 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16622 UNSPEC_FRNDINT_TRUNC))
16623 (use (match_operand:HI 2 "memory_operand" "m"))
16624 (use (match_operand:HI 3 "memory_operand" "m"))]
16625 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16626 && flag_unsafe_math_optimizations"
16627 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16628 [(set_attr "type" "frndint")
16629 (set_attr "i387_cw" "trunc")
16630 (set_attr "mode" "XF")])
16632 (define_expand "btruncdf2"
16633 [(use (match_operand:DF 0 "register_operand" ""))
16634 (use (match_operand:DF 1 "register_operand" ""))]
16635 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16636 && flag_unsafe_math_optimizations"
16638 rtx op0 = gen_reg_rtx (XFmode);
16639 rtx op1 = gen_reg_rtx (XFmode);
16640 rtx op2 = assign_386_stack_local (HImode, 1);
16641 rtx op3 = assign_386_stack_local (HImode, 2);
16643 ix86_optimize_mode_switching = 1;
16645 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16646 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16648 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16652 (define_expand "btruncsf2"
16653 [(use (match_operand:SF 0 "register_operand" ""))
16654 (use (match_operand:SF 1 "register_operand" ""))]
16655 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16656 && flag_unsafe_math_optimizations"
16658 rtx op0 = gen_reg_rtx (XFmode);
16659 rtx op1 = gen_reg_rtx (XFmode);
16660 rtx op2 = assign_386_stack_local (HImode, 1);
16661 rtx op3 = assign_386_stack_local (HImode, 2);
16663 ix86_optimize_mode_switching = 1;
16665 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16666 emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
16668 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16672 (define_expand "btruncxf2"
16673 [(use (match_operand:XF 0 "register_operand" ""))
16674 (use (match_operand:XF 1 "register_operand" ""))]
16675 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16676 && flag_unsafe_math_optimizations"
16678 rtx op2 = assign_386_stack_local (HImode, 1);
16679 rtx op3 = assign_386_stack_local (HImode, 2);
16681 ix86_optimize_mode_switching = 1;
16683 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
16687 (define_insn "frndintxf2_mask_pm"
16688 [(set (match_operand:XF 0 "register_operand" "=f")
16689 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16690 UNSPEC_FRNDINT_MASK_PM))
16691 (use (match_operand:HI 2 "memory_operand" "m"))
16692 (use (match_operand:HI 3 "memory_operand" "m"))]
16693 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16694 && flag_unsafe_math_optimizations"
16695 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16696 [(set_attr "type" "frndint")
16697 (set_attr "i387_cw" "mask_pm")
16698 (set_attr "mode" "XF")])
16700 (define_expand "nearbyintdf2"
16701 [(use (match_operand:DF 0 "register_operand" ""))
16702 (use (match_operand:DF 1 "register_operand" ""))]
16703 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16704 && flag_unsafe_math_optimizations"
16706 rtx op0 = gen_reg_rtx (XFmode);
16707 rtx op1 = gen_reg_rtx (XFmode);
16708 rtx op2 = assign_386_stack_local (HImode, 1);
16709 rtx op3 = assign_386_stack_local (HImode, 2);
16711 ix86_optimize_mode_switching = 1;
16713 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16714 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16716 emit_insn (gen_truncxfdf2_noop (operands[0], op0));
16720 (define_expand "nearbyintsf2"
16721 [(use (match_operand:SF 0 "register_operand" ""))
16722 (use (match_operand:SF 1 "register_operand" ""))]
16723 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16724 && flag_unsafe_math_optimizations"
16726 rtx op0 = gen_reg_rtx (XFmode);
16727 rtx op1 = gen_reg_rtx (XFmode);
16728 rtx op2 = assign_386_stack_local (HImode, 1);
16729 rtx op3 = assign_386_stack_local (HImode, 2);
16731 ix86_optimize_mode_switching = 1;
16733 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16734 emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
16736 emit_insn (gen_truncxfsf2_noop (operands[0], op0));
16740 (define_expand "nearbyintxf2"
16741 [(use (match_operand:XF 0 "register_operand" ""))
16742 (use (match_operand:XF 1 "register_operand" ""))]
16743 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
16744 && flag_unsafe_math_optimizations"
16746 rtx op2 = assign_386_stack_local (HImode, 1);
16747 rtx op3 = assign_386_stack_local (HImode, 2);
16749 ix86_optimize_mode_switching = 1;
16751 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
16757 ;; Block operation instructions
16760 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
16763 [(set_attr "type" "cld")])
16765 (define_expand "movmemsi"
16766 [(use (match_operand:BLK 0 "memory_operand" ""))
16767 (use (match_operand:BLK 1 "memory_operand" ""))
16768 (use (match_operand:SI 2 "nonmemory_operand" ""))
16769 (use (match_operand:SI 3 "const_int_operand" ""))]
16772 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16778 (define_expand "movmemdi"
16779 [(use (match_operand:BLK 0 "memory_operand" ""))
16780 (use (match_operand:BLK 1 "memory_operand" ""))
16781 (use (match_operand:DI 2 "nonmemory_operand" ""))
16782 (use (match_operand:DI 3 "const_int_operand" ""))]
16785 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
16791 ;; Most CPUs don't like single string operations
16792 ;; Handle this case here to simplify previous expander.
16794 (define_expand "strmov"
16795 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
16796 (set (match_operand 1 "memory_operand" "") (match_dup 4))
16797 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
16798 (clobber (reg:CC FLAGS_REG))])
16799 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
16800 (clobber (reg:CC FLAGS_REG))])]
16803 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16805 /* If .md ever supports :P for Pmode, these can be directly
16806 in the pattern above. */
16807 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16808 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16810 if (TARGET_SINGLE_STRINGOP || optimize_size)
16812 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16813 operands[2], operands[3],
16814 operands[5], operands[6]));
16818 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16821 (define_expand "strmov_singleop"
16822 [(parallel [(set (match_operand 1 "memory_operand" "")
16823 (match_operand 3 "memory_operand" ""))
16824 (set (match_operand 0 "register_operand" "")
16825 (match_operand 4 "" ""))
16826 (set (match_operand 2 "register_operand" "")
16827 (match_operand 5 "" ""))
16828 (use (reg:SI DIRFLAG_REG))])]
16829 "TARGET_SINGLE_STRINGOP || optimize_size"
16832 (define_insn "*strmovdi_rex_1"
16833 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
16834 (mem:DI (match_operand:DI 3 "register_operand" "1")))
16835 (set (match_operand:DI 0 "register_operand" "=D")
16836 (plus:DI (match_dup 2)
16838 (set (match_operand:DI 1 "register_operand" "=S")
16839 (plus:DI (match_dup 3)
16841 (use (reg:SI DIRFLAG_REG))]
16842 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16844 [(set_attr "type" "str")
16845 (set_attr "mode" "DI")
16846 (set_attr "memory" "both")])
16848 (define_insn "*strmovsi_1"
16849 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
16850 (mem:SI (match_operand:SI 3 "register_operand" "1")))
16851 (set (match_operand:SI 0 "register_operand" "=D")
16852 (plus:SI (match_dup 2)
16854 (set (match_operand:SI 1 "register_operand" "=S")
16855 (plus:SI (match_dup 3)
16857 (use (reg:SI DIRFLAG_REG))]
16858 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16860 [(set_attr "type" "str")
16861 (set_attr "mode" "SI")
16862 (set_attr "memory" "both")])
16864 (define_insn "*strmovsi_rex_1"
16865 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
16866 (mem:SI (match_operand:DI 3 "register_operand" "1")))
16867 (set (match_operand:DI 0 "register_operand" "=D")
16868 (plus:DI (match_dup 2)
16870 (set (match_operand:DI 1 "register_operand" "=S")
16871 (plus:DI (match_dup 3)
16873 (use (reg:SI DIRFLAG_REG))]
16874 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16876 [(set_attr "type" "str")
16877 (set_attr "mode" "SI")
16878 (set_attr "memory" "both")])
16880 (define_insn "*strmovhi_1"
16881 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
16882 (mem:HI (match_operand:SI 3 "register_operand" "1")))
16883 (set (match_operand:SI 0 "register_operand" "=D")
16884 (plus:SI (match_dup 2)
16886 (set (match_operand:SI 1 "register_operand" "=S")
16887 (plus:SI (match_dup 3)
16889 (use (reg:SI DIRFLAG_REG))]
16890 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16892 [(set_attr "type" "str")
16893 (set_attr "memory" "both")
16894 (set_attr "mode" "HI")])
16896 (define_insn "*strmovhi_rex_1"
16897 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
16898 (mem:HI (match_operand:DI 3 "register_operand" "1")))
16899 (set (match_operand:DI 0 "register_operand" "=D")
16900 (plus:DI (match_dup 2)
16902 (set (match_operand:DI 1 "register_operand" "=S")
16903 (plus:DI (match_dup 3)
16905 (use (reg:SI DIRFLAG_REG))]
16906 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16908 [(set_attr "type" "str")
16909 (set_attr "memory" "both")
16910 (set_attr "mode" "HI")])
16912 (define_insn "*strmovqi_1"
16913 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16914 (mem:QI (match_operand:SI 3 "register_operand" "1")))
16915 (set (match_operand:SI 0 "register_operand" "=D")
16916 (plus:SI (match_dup 2)
16918 (set (match_operand:SI 1 "register_operand" "=S")
16919 (plus:SI (match_dup 3)
16921 (use (reg:SI DIRFLAG_REG))]
16922 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16924 [(set_attr "type" "str")
16925 (set_attr "memory" "both")
16926 (set_attr "mode" "QI")])
16928 (define_insn "*strmovqi_rex_1"
16929 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16930 (mem:QI (match_operand:DI 3 "register_operand" "1")))
16931 (set (match_operand:DI 0 "register_operand" "=D")
16932 (plus:DI (match_dup 2)
16934 (set (match_operand:DI 1 "register_operand" "=S")
16935 (plus:DI (match_dup 3)
16937 (use (reg:SI DIRFLAG_REG))]
16938 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16940 [(set_attr "type" "str")
16941 (set_attr "memory" "both")
16942 (set_attr "mode" "QI")])
16944 (define_expand "rep_mov"
16945 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16946 (set (match_operand 0 "register_operand" "")
16947 (match_operand 5 "" ""))
16948 (set (match_operand 2 "register_operand" "")
16949 (match_operand 6 "" ""))
16950 (set (match_operand 1 "memory_operand" "")
16951 (match_operand 3 "memory_operand" ""))
16952 (use (match_dup 4))
16953 (use (reg:SI DIRFLAG_REG))])]
16957 (define_insn "*rep_movdi_rex64"
16958 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16959 (set (match_operand:DI 0 "register_operand" "=D")
16960 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16962 (match_operand:DI 3 "register_operand" "0")))
16963 (set (match_operand:DI 1 "register_operand" "=S")
16964 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16965 (match_operand:DI 4 "register_operand" "1")))
16966 (set (mem:BLK (match_dup 3))
16967 (mem:BLK (match_dup 4)))
16968 (use (match_dup 5))
16969 (use (reg:SI DIRFLAG_REG))]
16971 "{rep\;movsq|rep movsq}"
16972 [(set_attr "type" "str")
16973 (set_attr "prefix_rep" "1")
16974 (set_attr "memory" "both")
16975 (set_attr "mode" "DI")])
16977 (define_insn "*rep_movsi"
16978 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16979 (set (match_operand:SI 0 "register_operand" "=D")
16980 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16982 (match_operand:SI 3 "register_operand" "0")))
16983 (set (match_operand:SI 1 "register_operand" "=S")
16984 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16985 (match_operand:SI 4 "register_operand" "1")))
16986 (set (mem:BLK (match_dup 3))
16987 (mem:BLK (match_dup 4)))
16988 (use (match_dup 5))
16989 (use (reg:SI DIRFLAG_REG))]
16991 "{rep\;movsl|rep movsd}"
16992 [(set_attr "type" "str")
16993 (set_attr "prefix_rep" "1")
16994 (set_attr "memory" "both")
16995 (set_attr "mode" "SI")])
16997 (define_insn "*rep_movsi_rex64"
16998 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16999 (set (match_operand:DI 0 "register_operand" "=D")
17000 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17002 (match_operand:DI 3 "register_operand" "0")))
17003 (set (match_operand:DI 1 "register_operand" "=S")
17004 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17005 (match_operand:DI 4 "register_operand" "1")))
17006 (set (mem:BLK (match_dup 3))
17007 (mem:BLK (match_dup 4)))
17008 (use (match_dup 5))
17009 (use (reg:SI DIRFLAG_REG))]
17011 "{rep\;movsl|rep movsd}"
17012 [(set_attr "type" "str")
17013 (set_attr "prefix_rep" "1")
17014 (set_attr "memory" "both")
17015 (set_attr "mode" "SI")])
17017 (define_insn "*rep_movqi"
17018 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17019 (set (match_operand:SI 0 "register_operand" "=D")
17020 (plus:SI (match_operand:SI 3 "register_operand" "0")
17021 (match_operand:SI 5 "register_operand" "2")))
17022 (set (match_operand:SI 1 "register_operand" "=S")
17023 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17024 (set (mem:BLK (match_dup 3))
17025 (mem:BLK (match_dup 4)))
17026 (use (match_dup 5))
17027 (use (reg:SI DIRFLAG_REG))]
17029 "{rep\;movsb|rep movsb}"
17030 [(set_attr "type" "str")
17031 (set_attr "prefix_rep" "1")
17032 (set_attr "memory" "both")
17033 (set_attr "mode" "SI")])
17035 (define_insn "*rep_movqi_rex64"
17036 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17037 (set (match_operand:DI 0 "register_operand" "=D")
17038 (plus:DI (match_operand:DI 3 "register_operand" "0")
17039 (match_operand:DI 5 "register_operand" "2")))
17040 (set (match_operand:DI 1 "register_operand" "=S")
17041 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17042 (set (mem:BLK (match_dup 3))
17043 (mem:BLK (match_dup 4)))
17044 (use (match_dup 5))
17045 (use (reg:SI DIRFLAG_REG))]
17047 "{rep\;movsb|rep movsb}"
17048 [(set_attr "type" "str")
17049 (set_attr "prefix_rep" "1")
17050 (set_attr "memory" "both")
17051 (set_attr "mode" "SI")])
17053 (define_expand "clrmemsi"
17054 [(use (match_operand:BLK 0 "memory_operand" ""))
17055 (use (match_operand:SI 1 "nonmemory_operand" ""))
17056 (use (match_operand 2 "const_int_operand" ""))]
17059 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17065 (define_expand "clrmemdi"
17066 [(use (match_operand:BLK 0 "memory_operand" ""))
17067 (use (match_operand:DI 1 "nonmemory_operand" ""))
17068 (use (match_operand 2 "const_int_operand" ""))]
17071 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17077 ;; Most CPUs don't like single string operations
17078 ;; Handle this case here to simplify previous expander.
17080 (define_expand "strset"
17081 [(set (match_operand 1 "memory_operand" "")
17082 (match_operand 2 "register_operand" ""))
17083 (parallel [(set (match_operand 0 "register_operand" "")
17085 (clobber (reg:CC FLAGS_REG))])]
17088 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17089 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17091 /* If .md ever supports :P for Pmode, this can be directly
17092 in the pattern above. */
17093 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17094 GEN_INT (GET_MODE_SIZE (GET_MODE
17096 if (TARGET_SINGLE_STRINGOP || optimize_size)
17098 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17104 (define_expand "strset_singleop"
17105 [(parallel [(set (match_operand 1 "memory_operand" "")
17106 (match_operand 2 "register_operand" ""))
17107 (set (match_operand 0 "register_operand" "")
17108 (match_operand 3 "" ""))
17109 (use (reg:SI DIRFLAG_REG))])]
17110 "TARGET_SINGLE_STRINGOP || optimize_size"
17113 (define_insn "*strsetdi_rex_1"
17114 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17115 (match_operand:DI 2 "register_operand" "a"))
17116 (set (match_operand:DI 0 "register_operand" "=D")
17117 (plus:DI (match_dup 1)
17119 (use (reg:SI DIRFLAG_REG))]
17120 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17122 [(set_attr "type" "str")
17123 (set_attr "memory" "store")
17124 (set_attr "mode" "DI")])
17126 (define_insn "*strsetsi_1"
17127 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17128 (match_operand:SI 2 "register_operand" "a"))
17129 (set (match_operand:SI 0 "register_operand" "=D")
17130 (plus:SI (match_dup 1)
17132 (use (reg:SI DIRFLAG_REG))]
17133 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17135 [(set_attr "type" "str")
17136 (set_attr "memory" "store")
17137 (set_attr "mode" "SI")])
17139 (define_insn "*strsetsi_rex_1"
17140 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17141 (match_operand:SI 2 "register_operand" "a"))
17142 (set (match_operand:DI 0 "register_operand" "=D")
17143 (plus:DI (match_dup 1)
17145 (use (reg:SI DIRFLAG_REG))]
17146 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17148 [(set_attr "type" "str")
17149 (set_attr "memory" "store")
17150 (set_attr "mode" "SI")])
17152 (define_insn "*strsethi_1"
17153 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17154 (match_operand:HI 2 "register_operand" "a"))
17155 (set (match_operand:SI 0 "register_operand" "=D")
17156 (plus:SI (match_dup 1)
17158 (use (reg:SI DIRFLAG_REG))]
17159 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17161 [(set_attr "type" "str")
17162 (set_attr "memory" "store")
17163 (set_attr "mode" "HI")])
17165 (define_insn "*strsethi_rex_1"
17166 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17167 (match_operand:HI 2 "register_operand" "a"))
17168 (set (match_operand:DI 0 "register_operand" "=D")
17169 (plus:DI (match_dup 1)
17171 (use (reg:SI DIRFLAG_REG))]
17172 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17174 [(set_attr "type" "str")
17175 (set_attr "memory" "store")
17176 (set_attr "mode" "HI")])
17178 (define_insn "*strsetqi_1"
17179 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17180 (match_operand:QI 2 "register_operand" "a"))
17181 (set (match_operand:SI 0 "register_operand" "=D")
17182 (plus:SI (match_dup 1)
17184 (use (reg:SI DIRFLAG_REG))]
17185 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17187 [(set_attr "type" "str")
17188 (set_attr "memory" "store")
17189 (set_attr "mode" "QI")])
17191 (define_insn "*strsetqi_rex_1"
17192 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17193 (match_operand:QI 2 "register_operand" "a"))
17194 (set (match_operand:DI 0 "register_operand" "=D")
17195 (plus:DI (match_dup 1)
17197 (use (reg:SI DIRFLAG_REG))]
17198 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17200 [(set_attr "type" "str")
17201 (set_attr "memory" "store")
17202 (set_attr "mode" "QI")])
17204 (define_expand "rep_stos"
17205 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17206 (set (match_operand 0 "register_operand" "")
17207 (match_operand 4 "" ""))
17208 (set (match_operand 2 "memory_operand" "") (const_int 0))
17209 (use (match_operand 3 "register_operand" ""))
17210 (use (match_dup 1))
17211 (use (reg:SI DIRFLAG_REG))])]
17215 (define_insn "*rep_stosdi_rex64"
17216 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17217 (set (match_operand:DI 0 "register_operand" "=D")
17218 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17220 (match_operand:DI 3 "register_operand" "0")))
17221 (set (mem:BLK (match_dup 3))
17223 (use (match_operand:DI 2 "register_operand" "a"))
17224 (use (match_dup 4))
17225 (use (reg:SI DIRFLAG_REG))]
17227 "{rep\;stosq|rep stosq}"
17228 [(set_attr "type" "str")
17229 (set_attr "prefix_rep" "1")
17230 (set_attr "memory" "store")
17231 (set_attr "mode" "DI")])
17233 (define_insn "*rep_stossi"
17234 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17235 (set (match_operand:SI 0 "register_operand" "=D")
17236 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17238 (match_operand:SI 3 "register_operand" "0")))
17239 (set (mem:BLK (match_dup 3))
17241 (use (match_operand:SI 2 "register_operand" "a"))
17242 (use (match_dup 4))
17243 (use (reg:SI DIRFLAG_REG))]
17245 "{rep\;stosl|rep stosd}"
17246 [(set_attr "type" "str")
17247 (set_attr "prefix_rep" "1")
17248 (set_attr "memory" "store")
17249 (set_attr "mode" "SI")])
17251 (define_insn "*rep_stossi_rex64"
17252 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17253 (set (match_operand:DI 0 "register_operand" "=D")
17254 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17256 (match_operand:DI 3 "register_operand" "0")))
17257 (set (mem:BLK (match_dup 3))
17259 (use (match_operand:SI 2 "register_operand" "a"))
17260 (use (match_dup 4))
17261 (use (reg:SI DIRFLAG_REG))]
17263 "{rep\;stosl|rep stosd}"
17264 [(set_attr "type" "str")
17265 (set_attr "prefix_rep" "1")
17266 (set_attr "memory" "store")
17267 (set_attr "mode" "SI")])
17269 (define_insn "*rep_stosqi"
17270 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17271 (set (match_operand:SI 0 "register_operand" "=D")
17272 (plus:SI (match_operand:SI 3 "register_operand" "0")
17273 (match_operand:SI 4 "register_operand" "1")))
17274 (set (mem:BLK (match_dup 3))
17276 (use (match_operand:QI 2 "register_operand" "a"))
17277 (use (match_dup 4))
17278 (use (reg:SI DIRFLAG_REG))]
17280 "{rep\;stosb|rep stosb}"
17281 [(set_attr "type" "str")
17282 (set_attr "prefix_rep" "1")
17283 (set_attr "memory" "store")
17284 (set_attr "mode" "QI")])
17286 (define_insn "*rep_stosqi_rex64"
17287 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17288 (set (match_operand:DI 0 "register_operand" "=D")
17289 (plus:DI (match_operand:DI 3 "register_operand" "0")
17290 (match_operand:DI 4 "register_operand" "1")))
17291 (set (mem:BLK (match_dup 3))
17293 (use (match_operand:QI 2 "register_operand" "a"))
17294 (use (match_dup 4))
17295 (use (reg:SI DIRFLAG_REG))]
17297 "{rep\;stosb|rep stosb}"
17298 [(set_attr "type" "str")
17299 (set_attr "prefix_rep" "1")
17300 (set_attr "memory" "store")
17301 (set_attr "mode" "QI")])
17303 (define_expand "cmpstrsi"
17304 [(set (match_operand:SI 0 "register_operand" "")
17305 (compare:SI (match_operand:BLK 1 "general_operand" "")
17306 (match_operand:BLK 2 "general_operand" "")))
17307 (use (match_operand 3 "general_operand" ""))
17308 (use (match_operand 4 "immediate_operand" ""))]
17309 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17311 rtx addr1, addr2, out, outlow, count, countreg, align;
17313 /* Can't use this if the user has appropriated esi or edi. */
17314 if (global_regs[4] || global_regs[5])
17318 if (GET_CODE (out) != REG)
17319 out = gen_reg_rtx (SImode);
17321 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17322 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17323 if (addr1 != XEXP (operands[1], 0))
17324 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17325 if (addr2 != XEXP (operands[2], 0))
17326 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17328 count = operands[3];
17329 countreg = ix86_zero_extend_to_Pmode (count);
17331 /* %%% Iff we are testing strict equality, we can use known alignment
17332 to good advantage. This may be possible with combine, particularly
17333 once cc0 is dead. */
17334 align = operands[4];
17336 emit_insn (gen_cld ());
17337 if (GET_CODE (count) == CONST_INT)
17339 if (INTVAL (count) == 0)
17341 emit_move_insn (operands[0], const0_rtx);
17344 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17345 operands[1], operands[2]));
17350 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17352 emit_insn (gen_cmpsi_1 (countreg, countreg));
17353 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17354 operands[1], operands[2]));
17357 outlow = gen_lowpart (QImode, out);
17358 emit_insn (gen_cmpintqi (outlow));
17359 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17361 if (operands[0] != out)
17362 emit_move_insn (operands[0], out);
17367 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17369 (define_expand "cmpintqi"
17370 [(set (match_dup 1)
17371 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17373 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17374 (parallel [(set (match_operand:QI 0 "register_operand" "")
17375 (minus:QI (match_dup 1)
17377 (clobber (reg:CC FLAGS_REG))])]
17379 "operands[1] = gen_reg_rtx (QImode);
17380 operands[2] = gen_reg_rtx (QImode);")
17382 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17383 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17385 (define_expand "cmpstrqi_nz_1"
17386 [(parallel [(set (reg:CC FLAGS_REG)
17387 (compare:CC (match_operand 4 "memory_operand" "")
17388 (match_operand 5 "memory_operand" "")))
17389 (use (match_operand 2 "register_operand" ""))
17390 (use (match_operand:SI 3 "immediate_operand" ""))
17391 (use (reg:SI DIRFLAG_REG))
17392 (clobber (match_operand 0 "register_operand" ""))
17393 (clobber (match_operand 1 "register_operand" ""))
17394 (clobber (match_dup 2))])]
17398 (define_insn "*cmpstrqi_nz_1"
17399 [(set (reg:CC FLAGS_REG)
17400 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17401 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17402 (use (match_operand:SI 6 "register_operand" "2"))
17403 (use (match_operand:SI 3 "immediate_operand" "i"))
17404 (use (reg:SI DIRFLAG_REG))
17405 (clobber (match_operand:SI 0 "register_operand" "=S"))
17406 (clobber (match_operand:SI 1 "register_operand" "=D"))
17407 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17410 [(set_attr "type" "str")
17411 (set_attr "mode" "QI")
17412 (set_attr "prefix_rep" "1")])
17414 (define_insn "*cmpstrqi_nz_rex_1"
17415 [(set (reg:CC FLAGS_REG)
17416 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17417 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17418 (use (match_operand:DI 6 "register_operand" "2"))
17419 (use (match_operand:SI 3 "immediate_operand" "i"))
17420 (use (reg:SI DIRFLAG_REG))
17421 (clobber (match_operand:DI 0 "register_operand" "=S"))
17422 (clobber (match_operand:DI 1 "register_operand" "=D"))
17423 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17426 [(set_attr "type" "str")
17427 (set_attr "mode" "QI")
17428 (set_attr "prefix_rep" "1")])
17430 ;; The same, but the count is not known to not be zero.
17432 (define_expand "cmpstrqi_1"
17433 [(parallel [(set (reg:CC FLAGS_REG)
17434 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17436 (compare:CC (match_operand 4 "memory_operand" "")
17437 (match_operand 5 "memory_operand" ""))
17439 (use (match_operand:SI 3 "immediate_operand" ""))
17440 (use (reg:CC FLAGS_REG))
17441 (use (reg:SI DIRFLAG_REG))
17442 (clobber (match_operand 0 "register_operand" ""))
17443 (clobber (match_operand 1 "register_operand" ""))
17444 (clobber (match_dup 2))])]
17448 (define_insn "*cmpstrqi_1"
17449 [(set (reg:CC FLAGS_REG)
17450 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17452 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17453 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17455 (use (match_operand:SI 3 "immediate_operand" "i"))
17456 (use (reg:CC FLAGS_REG))
17457 (use (reg:SI DIRFLAG_REG))
17458 (clobber (match_operand:SI 0 "register_operand" "=S"))
17459 (clobber (match_operand:SI 1 "register_operand" "=D"))
17460 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17463 [(set_attr "type" "str")
17464 (set_attr "mode" "QI")
17465 (set_attr "prefix_rep" "1")])
17467 (define_insn "*cmpstrqi_rex_1"
17468 [(set (reg:CC FLAGS_REG)
17469 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17471 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17472 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17474 (use (match_operand:SI 3 "immediate_operand" "i"))
17475 (use (reg:CC FLAGS_REG))
17476 (use (reg:SI DIRFLAG_REG))
17477 (clobber (match_operand:DI 0 "register_operand" "=S"))
17478 (clobber (match_operand:DI 1 "register_operand" "=D"))
17479 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17482 [(set_attr "type" "str")
17483 (set_attr "mode" "QI")
17484 (set_attr "prefix_rep" "1")])
17486 (define_expand "strlensi"
17487 [(set (match_operand:SI 0 "register_operand" "")
17488 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17489 (match_operand:QI 2 "immediate_operand" "")
17490 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17493 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17499 (define_expand "strlendi"
17500 [(set (match_operand:DI 0 "register_operand" "")
17501 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17502 (match_operand:QI 2 "immediate_operand" "")
17503 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17506 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17512 (define_expand "strlenqi_1"
17513 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17514 (use (reg:SI DIRFLAG_REG))
17515 (clobber (match_operand 1 "register_operand" ""))
17516 (clobber (reg:CC FLAGS_REG))])]
17520 (define_insn "*strlenqi_1"
17521 [(set (match_operand:SI 0 "register_operand" "=&c")
17522 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17523 (match_operand:QI 2 "register_operand" "a")
17524 (match_operand:SI 3 "immediate_operand" "i")
17525 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17526 (use (reg:SI DIRFLAG_REG))
17527 (clobber (match_operand:SI 1 "register_operand" "=D"))
17528 (clobber (reg:CC FLAGS_REG))]
17531 [(set_attr "type" "str")
17532 (set_attr "mode" "QI")
17533 (set_attr "prefix_rep" "1")])
17535 (define_insn "*strlenqi_rex_1"
17536 [(set (match_operand:DI 0 "register_operand" "=&c")
17537 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17538 (match_operand:QI 2 "register_operand" "a")
17539 (match_operand:DI 3 "immediate_operand" "i")
17540 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17541 (use (reg:SI DIRFLAG_REG))
17542 (clobber (match_operand:DI 1 "register_operand" "=D"))
17543 (clobber (reg:CC FLAGS_REG))]
17546 [(set_attr "type" "str")
17547 (set_attr "mode" "QI")
17548 (set_attr "prefix_rep" "1")])
17550 ;; Peephole optimizations to clean up after cmpstr*. This should be
17551 ;; handled in combine, but it is not currently up to the task.
17552 ;; When used for their truth value, the cmpstr* expanders generate
17561 ;; The intermediate three instructions are unnecessary.
17563 ;; This one handles cmpstr*_nz_1...
17566 (set (reg:CC FLAGS_REG)
17567 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17568 (mem:BLK (match_operand 5 "register_operand" ""))))
17569 (use (match_operand 6 "register_operand" ""))
17570 (use (match_operand:SI 3 "immediate_operand" ""))
17571 (use (reg:SI DIRFLAG_REG))
17572 (clobber (match_operand 0 "register_operand" ""))
17573 (clobber (match_operand 1 "register_operand" ""))
17574 (clobber (match_operand 2 "register_operand" ""))])
17575 (set (match_operand:QI 7 "register_operand" "")
17576 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17577 (set (match_operand:QI 8 "register_operand" "")
17578 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17580 (compare (match_dup 7) (match_dup 8)))
17582 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17584 (set (reg:CC FLAGS_REG)
17585 (compare:CC (mem:BLK (match_dup 4))
17586 (mem:BLK (match_dup 5))))
17587 (use (match_dup 6))
17588 (use (match_dup 3))
17589 (use (reg:SI DIRFLAG_REG))
17590 (clobber (match_dup 0))
17591 (clobber (match_dup 1))
17592 (clobber (match_dup 2))])]
17595 ;; ...and this one handles cmpstr*_1.
17598 (set (reg:CC FLAGS_REG)
17599 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17601 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17602 (mem:BLK (match_operand 5 "register_operand" "")))
17604 (use (match_operand:SI 3 "immediate_operand" ""))
17605 (use (reg:CC FLAGS_REG))
17606 (use (reg:SI DIRFLAG_REG))
17607 (clobber (match_operand 0 "register_operand" ""))
17608 (clobber (match_operand 1 "register_operand" ""))
17609 (clobber (match_operand 2 "register_operand" ""))])
17610 (set (match_operand:QI 7 "register_operand" "")
17611 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17612 (set (match_operand:QI 8 "register_operand" "")
17613 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17615 (compare (match_dup 7) (match_dup 8)))
17617 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17619 (set (reg:CC FLAGS_REG)
17620 (if_then_else:CC (ne (match_dup 6)
17622 (compare:CC (mem:BLK (match_dup 4))
17623 (mem:BLK (match_dup 5)))
17625 (use (match_dup 3))
17626 (use (reg:CC FLAGS_REG))
17627 (use (reg:SI DIRFLAG_REG))
17628 (clobber (match_dup 0))
17629 (clobber (match_dup 1))
17630 (clobber (match_dup 2))])]
17635 ;; Conditional move instructions.
17637 (define_expand "movdicc"
17638 [(set (match_operand:DI 0 "register_operand" "")
17639 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17640 (match_operand:DI 2 "general_operand" "")
17641 (match_operand:DI 3 "general_operand" "")))]
17643 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17645 (define_insn "x86_movdicc_0_m1_rex64"
17646 [(set (match_operand:DI 0 "register_operand" "=r")
17647 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17650 (clobber (reg:CC FLAGS_REG))]
17653 ; Since we don't have the proper number of operands for an alu insn,
17654 ; fill in all the blanks.
17655 [(set_attr "type" "alu")
17656 (set_attr "pent_pair" "pu")
17657 (set_attr "memory" "none")
17658 (set_attr "imm_disp" "false")
17659 (set_attr "mode" "DI")
17660 (set_attr "length_immediate" "0")])
17662 (define_insn "movdicc_c_rex64"
17663 [(set (match_operand:DI 0 "register_operand" "=r,r")
17664 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17665 [(reg 17) (const_int 0)])
17666 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17667 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17668 "TARGET_64BIT && TARGET_CMOVE
17669 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17671 cmov%O2%C1\t{%2, %0|%0, %2}
17672 cmov%O2%c1\t{%3, %0|%0, %3}"
17673 [(set_attr "type" "icmov")
17674 (set_attr "mode" "DI")])
17676 (define_expand "movsicc"
17677 [(set (match_operand:SI 0 "register_operand" "")
17678 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17679 (match_operand:SI 2 "general_operand" "")
17680 (match_operand:SI 3 "general_operand" "")))]
17682 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17684 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17685 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17686 ;; So just document what we're doing explicitly.
17688 (define_insn "x86_movsicc_0_m1"
17689 [(set (match_operand:SI 0 "register_operand" "=r")
17690 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17693 (clobber (reg:CC FLAGS_REG))]
17696 ; Since we don't have the proper number of operands for an alu insn,
17697 ; fill in all the blanks.
17698 [(set_attr "type" "alu")
17699 (set_attr "pent_pair" "pu")
17700 (set_attr "memory" "none")
17701 (set_attr "imm_disp" "false")
17702 (set_attr "mode" "SI")
17703 (set_attr "length_immediate" "0")])
17705 (define_insn "*movsicc_noc"
17706 [(set (match_operand:SI 0 "register_operand" "=r,r")
17707 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17708 [(reg 17) (const_int 0)])
17709 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17710 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17712 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17714 cmov%O2%C1\t{%2, %0|%0, %2}
17715 cmov%O2%c1\t{%3, %0|%0, %3}"
17716 [(set_attr "type" "icmov")
17717 (set_attr "mode" "SI")])
17719 (define_expand "movhicc"
17720 [(set (match_operand:HI 0 "register_operand" "")
17721 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17722 (match_operand:HI 2 "general_operand" "")
17723 (match_operand:HI 3 "general_operand" "")))]
17724 "TARGET_HIMODE_MATH"
17725 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17727 (define_insn "*movhicc_noc"
17728 [(set (match_operand:HI 0 "register_operand" "=r,r")
17729 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17730 [(reg 17) (const_int 0)])
17731 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17732 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17734 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17736 cmov%O2%C1\t{%2, %0|%0, %2}
17737 cmov%O2%c1\t{%3, %0|%0, %3}"
17738 [(set_attr "type" "icmov")
17739 (set_attr "mode" "HI")])
17741 (define_expand "movqicc"
17742 [(set (match_operand:QI 0 "register_operand" "")
17743 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17744 (match_operand:QI 2 "general_operand" "")
17745 (match_operand:QI 3 "general_operand" "")))]
17746 "TARGET_QIMODE_MATH"
17747 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17749 (define_insn_and_split "*movqicc_noc"
17750 [(set (match_operand:QI 0 "register_operand" "=r,r")
17751 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17752 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17753 (match_operand:QI 2 "register_operand" "r,0")
17754 (match_operand:QI 3 "register_operand" "0,r")))]
17755 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17757 "&& reload_completed"
17758 [(set (match_dup 0)
17759 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17762 "operands[0] = gen_lowpart (SImode, operands[0]);
17763 operands[2] = gen_lowpart (SImode, operands[2]);
17764 operands[3] = gen_lowpart (SImode, operands[3]);"
17765 [(set_attr "type" "icmov")
17766 (set_attr "mode" "SI")])
17768 (define_expand "movsfcc"
17769 [(set (match_operand:SF 0 "register_operand" "")
17770 (if_then_else:SF (match_operand 1 "comparison_operator" "")
17771 (match_operand:SF 2 "register_operand" "")
17772 (match_operand:SF 3 "register_operand" "")))]
17774 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17776 (define_insn "*movsfcc_1"
17777 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17778 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17779 [(reg 17) (const_int 0)])
17780 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17781 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17783 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17785 fcmov%F1\t{%2, %0|%0, %2}
17786 fcmov%f1\t{%3, %0|%0, %3}
17787 cmov%O2%C1\t{%2, %0|%0, %2}
17788 cmov%O2%c1\t{%3, %0|%0, %3}"
17789 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17790 (set_attr "mode" "SF,SF,SI,SI")])
17792 (define_expand "movdfcc"
17793 [(set (match_operand:DF 0 "register_operand" "")
17794 (if_then_else:DF (match_operand 1 "comparison_operator" "")
17795 (match_operand:DF 2 "register_operand" "")
17796 (match_operand:DF 3 "register_operand" "")))]
17798 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17800 (define_insn "*movdfcc_1"
17801 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
17802 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17803 [(reg 17) (const_int 0)])
17804 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
17805 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
17806 "!TARGET_64BIT && TARGET_CMOVE
17807 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17809 fcmov%F1\t{%2, %0|%0, %2}
17810 fcmov%f1\t{%3, %0|%0, %3}
17813 [(set_attr "type" "fcmov,fcmov,multi,multi")
17814 (set_attr "mode" "DF")])
17816 (define_insn "*movdfcc_1_rex64"
17817 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
17818 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17819 [(reg 17) (const_int 0)])
17820 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
17821 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
17822 "TARGET_64BIT && TARGET_CMOVE
17823 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17825 fcmov%F1\t{%2, %0|%0, %2}
17826 fcmov%f1\t{%3, %0|%0, %3}
17827 cmov%O2%C1\t{%2, %0|%0, %2}
17828 cmov%O2%c1\t{%3, %0|%0, %3}"
17829 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17830 (set_attr "mode" "DF")])
17833 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
17834 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17835 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
17836 (match_operand:DF 2 "nonimmediate_operand" "")
17837 (match_operand:DF 3 "nonimmediate_operand" "")))]
17838 "!TARGET_64BIT && reload_completed"
17839 [(set (match_dup 2)
17840 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17844 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
17847 "split_di (operands+2, 1, operands+5, operands+6);
17848 split_di (operands+3, 1, operands+7, operands+8);
17849 split_di (operands, 1, operands+2, operands+3);")
17851 (define_expand "movxfcc"
17852 [(set (match_operand:XF 0 "register_operand" "")
17853 (if_then_else:XF (match_operand 1 "comparison_operator" "")
17854 (match_operand:XF 2 "register_operand" "")
17855 (match_operand:XF 3 "register_operand" "")))]
17857 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
17859 (define_insn "*movxfcc_1"
17860 [(set (match_operand:XF 0 "register_operand" "=f,f")
17861 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17862 [(reg 17) (const_int 0)])
17863 (match_operand:XF 2 "register_operand" "f,0")
17864 (match_operand:XF 3 "register_operand" "0,f")))]
17867 fcmov%F1\t{%2, %0|%0, %2}
17868 fcmov%f1\t{%3, %0|%0, %3}"
17869 [(set_attr "type" "fcmov")
17870 (set_attr "mode" "XF")])
17872 (define_expand "minsf3"
17874 (set (match_operand:SF 0 "register_operand" "")
17875 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17876 (match_operand:SF 2 "nonimmediate_operand" ""))
17879 (clobber (reg:CC FLAGS_REG))])]
17883 (define_insn "*minsf"
17884 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17885 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17886 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17889 (clobber (reg:CC FLAGS_REG))]
17890 "TARGET_SSE && TARGET_IEEE_FP"
17893 (define_insn "*minsf_nonieee"
17894 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17895 (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17896 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17899 (clobber (reg:CC FLAGS_REG))]
17900 "TARGET_SSE && !TARGET_IEEE_FP
17901 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17905 [(set (match_operand:SF 0 "register_operand" "")
17906 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17907 (match_operand:SF 2 "nonimmediate_operand" ""))
17908 (match_operand:SF 3 "register_operand" "")
17909 (match_operand:SF 4 "nonimmediate_operand" "")))
17910 (clobber (reg:CC FLAGS_REG))]
17911 "SSE_REG_P (operands[0]) && reload_completed
17912 && ((operands_match_p (operands[1], operands[3])
17913 && operands_match_p (operands[2], operands[4]))
17914 || (operands_match_p (operands[1], operands[4])
17915 && operands_match_p (operands[2], operands[3])))"
17916 [(set (match_dup 0)
17917 (if_then_else:SF (lt (match_dup 1)
17922 ;; Conditional addition patterns
17923 (define_expand "addqicc"
17924 [(match_operand:QI 0 "register_operand" "")
17925 (match_operand 1 "comparison_operator" "")
17926 (match_operand:QI 2 "register_operand" "")
17927 (match_operand:QI 3 "const_int_operand" "")]
17929 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17931 (define_expand "addhicc"
17932 [(match_operand:HI 0 "register_operand" "")
17933 (match_operand 1 "comparison_operator" "")
17934 (match_operand:HI 2 "register_operand" "")
17935 (match_operand:HI 3 "const_int_operand" "")]
17937 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17939 (define_expand "addsicc"
17940 [(match_operand:SI 0 "register_operand" "")
17941 (match_operand 1 "comparison_operator" "")
17942 (match_operand:SI 2 "register_operand" "")
17943 (match_operand:SI 3 "const_int_operand" "")]
17945 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17947 (define_expand "adddicc"
17948 [(match_operand:DI 0 "register_operand" "")
17949 (match_operand 1 "comparison_operator" "")
17950 (match_operand:DI 2 "register_operand" "")
17951 (match_operand:DI 3 "const_int_operand" "")]
17953 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17955 ;; We can't represent the LT test directly. Do this by swapping the operands.
17958 [(set (match_operand:SF 0 "fp_register_operand" "")
17959 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17960 (match_operand:SF 2 "register_operand" ""))
17961 (match_operand:SF 3 "register_operand" "")
17962 (match_operand:SF 4 "register_operand" "")))
17963 (clobber (reg:CC FLAGS_REG))]
17965 && ((operands_match_p (operands[1], operands[3])
17966 && operands_match_p (operands[2], operands[4]))
17967 || (operands_match_p (operands[1], operands[4])
17968 && operands_match_p (operands[2], operands[3])))"
17969 [(set (reg:CCFP FLAGS_REG)
17970 (compare:CCFP (match_dup 2)
17973 (if_then_else:SF (ge (reg:CCFP FLAGS_REG) (const_int 0))
17977 (define_insn "*minsf_sse"
17978 [(set (match_operand:SF 0 "register_operand" "=x")
17979 (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17980 (match_operand:SF 2 "nonimmediate_operand" "xm"))
17983 "TARGET_SSE && reload_completed"
17984 "minss\t{%2, %0|%0, %2}"
17985 [(set_attr "type" "sse")
17986 (set_attr "mode" "SF")])
17988 (define_expand "mindf3"
17990 (set (match_operand:DF 0 "register_operand" "")
17991 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17992 (match_operand:DF 2 "nonimmediate_operand" ""))
17995 (clobber (reg:CC FLAGS_REG))])]
17996 "TARGET_SSE2 && TARGET_SSE_MATH"
17999 (define_insn "*mindf"
18000 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18001 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18002 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18005 (clobber (reg:CC FLAGS_REG))]
18006 "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
18009 (define_insn "*mindf_nonieee"
18010 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18011 (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18012 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18015 (clobber (reg:CC FLAGS_REG))]
18016 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18017 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18021 [(set (match_operand:DF 0 "register_operand" "")
18022 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18023 (match_operand:DF 2 "nonimmediate_operand" ""))
18024 (match_operand:DF 3 "register_operand" "")
18025 (match_operand:DF 4 "nonimmediate_operand" "")))
18026 (clobber (reg:CC FLAGS_REG))]
18027 "SSE_REG_P (operands[0]) && reload_completed
18028 && ((operands_match_p (operands[1], operands[3])
18029 && operands_match_p (operands[2], operands[4]))
18030 || (operands_match_p (operands[1], operands[4])
18031 && operands_match_p (operands[2], operands[3])))"
18032 [(set (match_dup 0)
18033 (if_then_else:DF (lt (match_dup 1)
18038 ;; We can't represent the LT test directly. Do this by swapping the operands.
18040 [(set (match_operand:DF 0 "fp_register_operand" "")
18041 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
18042 (match_operand:DF 2 "register_operand" ""))
18043 (match_operand:DF 3 "register_operand" "")
18044 (match_operand:DF 4 "register_operand" "")))
18045 (clobber (reg:CC FLAGS_REG))]
18047 && ((operands_match_p (operands[1], operands[3])
18048 && operands_match_p (operands[2], operands[4]))
18049 || (operands_match_p (operands[1], operands[4])
18050 && operands_match_p (operands[2], operands[3])))"
18051 [(set (reg:CCFP FLAGS_REG)
18052 (compare:CCFP (match_dup 2)
18055 (if_then_else:DF (ge (reg:CCFP FLAGS_REG) (const_int 0))
18059 (define_insn "*mindf_sse"
18060 [(set (match_operand:DF 0 "register_operand" "=Y")
18061 (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
18062 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18065 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18066 "minsd\t{%2, %0|%0, %2}"
18067 [(set_attr "type" "sse")
18068 (set_attr "mode" "DF")])
18070 (define_expand "maxsf3"
18072 (set (match_operand:SF 0 "register_operand" "")
18073 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18074 (match_operand:SF 2 "nonimmediate_operand" ""))
18077 (clobber (reg:CC FLAGS_REG))])]
18081 (define_insn "*maxsf"
18082 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
18083 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
18084 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
18087 (clobber (reg:CC FLAGS_REG))]
18088 "TARGET_SSE && TARGET_IEEE_FP"
18091 (define_insn "*maxsf_nonieee"
18092 [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
18093 (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
18094 (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
18097 (clobber (reg:CC FLAGS_REG))]
18098 "TARGET_SSE && !TARGET_IEEE_FP
18099 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18103 [(set (match_operand:SF 0 "register_operand" "")
18104 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18105 (match_operand:SF 2 "nonimmediate_operand" ""))
18106 (match_operand:SF 3 "register_operand" "")
18107 (match_operand:SF 4 "nonimmediate_operand" "")))
18108 (clobber (reg:CC FLAGS_REG))]
18109 "SSE_REG_P (operands[0]) && reload_completed
18110 && ((operands_match_p (operands[1], operands[3])
18111 && operands_match_p (operands[2], operands[4]))
18112 || (operands_match_p (operands[1], operands[4])
18113 && operands_match_p (operands[2], operands[3])))"
18114 [(set (match_dup 0)
18115 (if_then_else:SF (gt (match_dup 1)
18121 [(set (match_operand:SF 0 "fp_register_operand" "")
18122 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
18123 (match_operand:SF 2 "register_operand" ""))
18124 (match_operand:SF 3 "register_operand" "")
18125 (match_operand:SF 4 "register_operand" "")))
18126 (clobber (reg:CC FLAGS_REG))]
18128 && ((operands_match_p (operands[1], operands[3])
18129 && operands_match_p (operands[2], operands[4]))
18130 || (operands_match_p (operands[1], operands[4])
18131 && operands_match_p (operands[2], operands[3])))"
18132 [(set (reg:CCFP FLAGS_REG)
18133 (compare:CCFP (match_dup 1)
18136 (if_then_else:SF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18140 (define_insn "*maxsf_sse"
18141 [(set (match_operand:SF 0 "register_operand" "=x")
18142 (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
18143 (match_operand:SF 2 "nonimmediate_operand" "xm"))
18146 "TARGET_SSE && reload_completed"
18147 "maxss\t{%2, %0|%0, %2}"
18148 [(set_attr "type" "sse")
18149 (set_attr "mode" "SF")])
18151 (define_expand "maxdf3"
18153 (set (match_operand:DF 0 "register_operand" "")
18154 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18155 (match_operand:DF 2 "nonimmediate_operand" ""))
18158 (clobber (reg:CC FLAGS_REG))])]
18159 "TARGET_SSE2 && TARGET_SSE_MATH"
18162 (define_insn "*maxdf"
18163 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
18164 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
18165 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
18168 (clobber (reg:CC FLAGS_REG))]
18169 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
18172 (define_insn "*maxdf_nonieee"
18173 [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
18174 (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
18175 (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
18178 (clobber (reg:CC FLAGS_REG))]
18179 "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
18180 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
18184 [(set (match_operand:DF 0 "register_operand" "")
18185 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18186 (match_operand:DF 2 "nonimmediate_operand" ""))
18187 (match_operand:DF 3 "register_operand" "")
18188 (match_operand:DF 4 "nonimmediate_operand" "")))
18189 (clobber (reg:CC FLAGS_REG))]
18190 "SSE_REG_P (operands[0]) && reload_completed
18191 && ((operands_match_p (operands[1], operands[3])
18192 && operands_match_p (operands[2], operands[4]))
18193 || (operands_match_p (operands[1], operands[4])
18194 && operands_match_p (operands[2], operands[3])))"
18195 [(set (match_dup 0)
18196 (if_then_else:DF (gt (match_dup 1)
18202 [(set (match_operand:DF 0 "fp_register_operand" "")
18203 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
18204 (match_operand:DF 2 "register_operand" ""))
18205 (match_operand:DF 3 "register_operand" "")
18206 (match_operand:DF 4 "register_operand" "")))
18207 (clobber (reg:CC FLAGS_REG))]
18209 && ((operands_match_p (operands[1], operands[3])
18210 && operands_match_p (operands[2], operands[4]))
18211 || (operands_match_p (operands[1], operands[4])
18212 && operands_match_p (operands[2], operands[3])))"
18213 [(set (reg:CCFP FLAGS_REG)
18214 (compare:CCFP (match_dup 1)
18217 (if_then_else:DF (gt (reg:CCFP FLAGS_REG) (const_int 0))
18221 (define_insn "*maxdf_sse"
18222 [(set (match_operand:DF 0 "register_operand" "=Y")
18223 (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
18224 (match_operand:DF 2 "nonimmediate_operand" "Ym"))
18227 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
18228 "maxsd\t{%2, %0|%0, %2}"
18229 [(set_attr "type" "sse")
18230 (set_attr "mode" "DF")])
18232 ;; Misc patterns (?)
18234 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18235 ;; Otherwise there will be nothing to keep
18237 ;; [(set (reg ebp) (reg esp))]
18238 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18239 ;; (clobber (eflags)]
18240 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18242 ;; in proper program order.
18243 (define_insn "pro_epilogue_adjust_stack_1"
18244 [(set (match_operand:SI 0 "register_operand" "=r,r")
18245 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18246 (match_operand:SI 2 "immediate_operand" "i,i")))
18247 (clobber (reg:CC FLAGS_REG))
18248 (clobber (mem:BLK (scratch)))]
18251 switch (get_attr_type (insn))
18254 return "mov{l}\t{%1, %0|%0, %1}";
18257 if (GET_CODE (operands[2]) == CONST_INT
18258 && (INTVAL (operands[2]) == 128
18259 || (INTVAL (operands[2]) < 0
18260 && INTVAL (operands[2]) != -128)))
18262 operands[2] = GEN_INT (-INTVAL (operands[2]));
18263 return "sub{l}\t{%2, %0|%0, %2}";
18265 return "add{l}\t{%2, %0|%0, %2}";
18268 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18269 return "lea{l}\t{%a2, %0|%0, %a2}";
18275 [(set (attr "type")
18276 (cond [(eq_attr "alternative" "0")
18277 (const_string "alu")
18278 (match_operand:SI 2 "const0_operand" "")
18279 (const_string "imov")
18281 (const_string "lea")))
18282 (set_attr "mode" "SI")])
18284 (define_insn "pro_epilogue_adjust_stack_rex64"
18285 [(set (match_operand:DI 0 "register_operand" "=r,r")
18286 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18287 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18288 (clobber (reg:CC FLAGS_REG))
18289 (clobber (mem:BLK (scratch)))]
18292 switch (get_attr_type (insn))
18295 return "mov{q}\t{%1, %0|%0, %1}";
18298 if (GET_CODE (operands[2]) == CONST_INT
18299 /* Avoid overflows. */
18300 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18301 && (INTVAL (operands[2]) == 128
18302 || (INTVAL (operands[2]) < 0
18303 && INTVAL (operands[2]) != -128)))
18305 operands[2] = GEN_INT (-INTVAL (operands[2]));
18306 return "sub{q}\t{%2, %0|%0, %2}";
18308 return "add{q}\t{%2, %0|%0, %2}";
18311 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18312 return "lea{q}\t{%a2, %0|%0, %a2}";
18318 [(set (attr "type")
18319 (cond [(eq_attr "alternative" "0")
18320 (const_string "alu")
18321 (match_operand:DI 2 "const0_operand" "")
18322 (const_string "imov")
18324 (const_string "lea")))
18325 (set_attr "mode" "DI")])
18327 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18328 [(set (match_operand:DI 0 "register_operand" "=r,r")
18329 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18330 (match_operand:DI 3 "immediate_operand" "i,i")))
18331 (use (match_operand:DI 2 "register_operand" "r,r"))
18332 (clobber (reg:CC FLAGS_REG))
18333 (clobber (mem:BLK (scratch)))]
18336 switch (get_attr_type (insn))
18339 return "add{q}\t{%2, %0|%0, %2}";
18342 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18343 return "lea{q}\t{%a2, %0|%0, %a2}";
18349 [(set_attr "type" "alu,lea")
18350 (set_attr "mode" "DI")])
18352 ;; Placeholder for the conditional moves. This one is split either to SSE
18353 ;; based moves emulation or to usual cmove sequence. Little bit unfortunate
18354 ;; fact is that compares supported by the cmp??ss instructions are exactly
18355 ;; swapped of those supported by cmove sequence.
18356 ;; The EQ/NE comparisons also needs bit care, since they are not directly
18357 ;; supported by i387 comparisons and we do need to emit two conditional moves
18360 (define_insn "sse_movsfcc"
18361 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
18362 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18363 [(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
18364 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
18365 (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
18366 (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
18367 (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18368 (clobber (reg:CC FLAGS_REG))]
18370 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18371 /* Avoid combine from being smart and converting min/max
18372 instruction patterns into conditional moves. */
18373 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18374 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18375 || !rtx_equal_p (operands[4], operands[2])
18376 || !rtx_equal_p (operands[5], operands[3]))
18377 && (!TARGET_IEEE_FP
18378 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18381 (define_insn "sse_movsfcc_eq"
18382 [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
18383 (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
18384 (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
18385 (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
18386 (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
18387 (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
18388 (clobber (reg:CC FLAGS_REG))]
18390 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18393 (define_insn "sse_movdfcc"
18394 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf")
18395 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18396 [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f")
18397 (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")])
18398 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY")
18399 (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY")))
18400 (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
18401 (clobber (reg:CC FLAGS_REG))]
18403 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
18404 /* Avoid combine from being smart and converting min/max
18405 instruction patterns into conditional moves. */
18406 && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
18407 && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
18408 || !rtx_equal_p (operands[4], operands[2])
18409 || !rtx_equal_p (operands[5], operands[3]))
18410 && (!TARGET_IEEE_FP
18411 || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
18414 (define_insn "sse_movdfcc_eq"
18415 [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
18416 (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
18417 (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
18418 (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
18419 (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
18420 (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
18421 (clobber (reg:CC FLAGS_REG))]
18423 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18426 ;; For non-sse moves just expand the usual cmove sequence.
18428 [(set (match_operand 0 "register_operand" "")
18429 (if_then_else (match_operator 1 "comparison_operator"
18430 [(match_operand 4 "nonimmediate_operand" "")
18431 (match_operand 5 "register_operand" "")])
18432 (match_operand 2 "nonimmediate_operand" "")
18433 (match_operand 3 "nonimmediate_operand" "")))
18434 (clobber (match_operand 6 "" ""))
18435 (clobber (reg:CC FLAGS_REG))]
18436 "!SSE_REG_P (operands[0]) && reload_completed
18437 && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
18440 ix86_compare_op0 = operands[5];
18441 ix86_compare_op1 = operands[4];
18442 operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
18443 VOIDmode, operands[5], operands[4]);
18444 ix86_expand_fp_movcc (operands);
18448 ;; Split SSE based conditional move into sequence:
18449 ;; cmpCC op0, op4 - set op0 to 0 or ffffffff depending on the comparison
18450 ;; and op2, op0 - zero op2 if comparison was false
18451 ;; nand op0, op3 - load op3 to op0 if comparison was false
18452 ;; or op2, op0 - get the nonzero one into the result.
18454 [(set (match_operand:SF 0 "register_operand" "")
18455 (if_then_else (match_operator:SF 1 "sse_comparison_operator"
18456 [(match_operand:SF 4 "register_operand" "")
18457 (match_operand:SF 5 "nonimmediate_operand" "")])
18458 (match_operand:SF 2 "register_operand" "")
18459 (match_operand:SF 3 "register_operand" "")))
18460 (clobber (match_operand 6 "" ""))
18461 (clobber (reg:CC FLAGS_REG))]
18462 "SSE_REG_P (operands[0]) && reload_completed"
18463 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18464 (set (match_dup 2) (and:V4SF (match_dup 2)
18466 (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
18468 (set (match_dup 0) (ior:V4SF (match_dup 6)
18471 /* If op2 == op3, op3 would be clobbered before it is used. */
18472 if (operands_match_p (operands[2], operands[3]))
18474 emit_move_insn (operands[0], operands[2]);
18478 PUT_MODE (operands[1], GET_MODE (operands[0]));
18479 if (operands_match_p (operands[0], operands[4]))
18480 operands[6] = operands[4], operands[7] = operands[2];
18482 operands[6] = operands[2], operands[7] = operands[4];
18483 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18484 operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
18485 operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
18486 operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
18487 operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
18488 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18492 [(set (match_operand:DF 0 "register_operand" "")
18493 (if_then_else (match_operator:DF 1 "sse_comparison_operator"
18494 [(match_operand:DF 4 "register_operand" "")
18495 (match_operand:DF 5 "nonimmediate_operand" "")])
18496 (match_operand:DF 2 "register_operand" "")
18497 (match_operand:DF 3 "register_operand" "")))
18498 (clobber (match_operand 6 "" ""))
18499 (clobber (reg:CC FLAGS_REG))]
18500 "SSE_REG_P (operands[0]) && reload_completed"
18501 [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
18502 (set (match_dup 2) (and:V2DF (match_dup 2)
18504 (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
18506 (set (match_dup 0) (ior:V2DF (match_dup 6)
18509 if (GET_MODE (operands[2]) == DFmode
18510 && TARGET_SSE_PARTIAL_REGS && !optimize_size)
18512 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18513 emit_insn (gen_sse2_unpcklpd (op, op, op));
18514 op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18515 emit_insn (gen_sse2_unpcklpd (op, op, op));
18518 /* If op2 == op3, op3 would be clobbered before it is used. */
18519 if (operands_match_p (operands[2], operands[3]))
18521 emit_move_insn (operands[0], operands[2]);
18525 PUT_MODE (operands[1], GET_MODE (operands[0]));
18526 if (operands_match_p (operands[0], operands[4]))
18527 operands[6] = operands[4], operands[7] = operands[2];
18529 operands[6] = operands[2], operands[7] = operands[4];
18530 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18531 operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18532 operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18533 operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
18534 operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
18535 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18538 ;; Special case of conditional move we can handle effectively.
18539 ;; Do not brother with the integer/floating point case, since these are
18540 ;; bot considerably slower, unlike in the generic case.
18541 (define_insn "*sse_movsfcc_const0_1"
18542 [(set (match_operand:SF 0 "register_operand" "=&x")
18543 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18544 [(match_operand:SF 4 "register_operand" "0")
18545 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18546 (match_operand:SF 2 "register_operand" "x")
18547 (match_operand:SF 3 "const0_operand" "X")))]
18551 (define_insn "*sse_movsfcc_const0_2"
18552 [(set (match_operand:SF 0 "register_operand" "=&x")
18553 (if_then_else:SF (match_operator 1 "sse_comparison_operator"
18554 [(match_operand:SF 4 "register_operand" "0")
18555 (match_operand:SF 5 "nonimmediate_operand" "xm")])
18556 (match_operand:SF 2 "const0_operand" "X")
18557 (match_operand:SF 3 "register_operand" "x")))]
18561 (define_insn "*sse_movsfcc_const0_3"
18562 [(set (match_operand:SF 0 "register_operand" "=&x")
18563 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18564 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18565 (match_operand:SF 5 "register_operand" "0")])
18566 (match_operand:SF 2 "register_operand" "x")
18567 (match_operand:SF 3 "const0_operand" "X")))]
18571 (define_insn "*sse_movsfcc_const0_4"
18572 [(set (match_operand:SF 0 "register_operand" "=&x")
18573 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18574 [(match_operand:SF 4 "nonimmediate_operand" "xm")
18575 (match_operand:SF 5 "register_operand" "0")])
18576 (match_operand:SF 2 "const0_operand" "X")
18577 (match_operand:SF 3 "register_operand" "x")))]
18581 (define_insn "*sse_movdfcc_const0_1"
18582 [(set (match_operand:DF 0 "register_operand" "=&Y")
18583 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18584 [(match_operand:DF 4 "register_operand" "0")
18585 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18586 (match_operand:DF 2 "register_operand" "Y")
18587 (match_operand:DF 3 "const0_operand" "X")))]
18591 (define_insn "*sse_movdfcc_const0_2"
18592 [(set (match_operand:DF 0 "register_operand" "=&Y")
18593 (if_then_else:DF (match_operator 1 "sse_comparison_operator"
18594 [(match_operand:DF 4 "register_operand" "0")
18595 (match_operand:DF 5 "nonimmediate_operand" "Ym")])
18596 (match_operand:DF 2 "const0_operand" "X")
18597 (match_operand:DF 3 "register_operand" "Y")))]
18601 (define_insn "*sse_movdfcc_const0_3"
18602 [(set (match_operand:DF 0 "register_operand" "=&Y")
18603 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18604 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18605 (match_operand:DF 5 "register_operand" "0")])
18606 (match_operand:DF 2 "register_operand" "Y")
18607 (match_operand:DF 3 "const0_operand" "X")))]
18611 (define_insn "*sse_movdfcc_const0_4"
18612 [(set (match_operand:DF 0 "register_operand" "=&Y")
18613 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18614 [(match_operand:DF 4 "nonimmediate_operand" "Ym")
18615 (match_operand:DF 5 "register_operand" "0")])
18616 (match_operand:DF 2 "const0_operand" "X")
18617 (match_operand:DF 3 "register_operand" "Y")))]
18622 [(set (match_operand:SF 0 "register_operand" "")
18623 (if_then_else (match_operator 1 "comparison_operator"
18624 [(match_operand:SF 4 "nonimmediate_operand" "")
18625 (match_operand:SF 5 "nonimmediate_operand" "")])
18626 (match_operand:SF 2 "nonmemory_operand" "")
18627 (match_operand:SF 3 "nonmemory_operand" "")))]
18628 "SSE_REG_P (operands[0]) && reload_completed
18629 && (const0_operand (operands[2], GET_MODE (operands[0]))
18630 || const0_operand (operands[3], GET_MODE (operands[0])))"
18631 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18632 (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
18634 PUT_MODE (operands[1], GET_MODE (operands[0]));
18635 if (!sse_comparison_operator (operands[1], VOIDmode)
18636 || !rtx_equal_p (operands[0], operands[4]))
18638 rtx tmp = operands[5];
18639 operands[5] = operands[4];
18641 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18643 if (!rtx_equal_p (operands[0], operands[4]))
18645 operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
18646 if (const0_operand (operands[2], GET_MODE (operands[2])))
18648 operands[7] = operands[3];
18649 operands[6] = gen_rtx_NOT (V4SFmode, operands[8]);
18653 operands[7] = operands[2];
18654 operands[6] = operands[8];
18656 operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
18660 [(set (match_operand:DF 0 "register_operand" "")
18661 (if_then_else (match_operator 1 "comparison_operator"
18662 [(match_operand:DF 4 "nonimmediate_operand" "")
18663 (match_operand:DF 5 "nonimmediate_operand" "")])
18664 (match_operand:DF 2 "nonmemory_operand" "")
18665 (match_operand:DF 3 "nonmemory_operand" "")))]
18666 "SSE_REG_P (operands[0]) && reload_completed
18667 && (const0_operand (operands[2], GET_MODE (operands[0]))
18668 || const0_operand (operands[3], GET_MODE (operands[0])))"
18669 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
18670 (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
18672 if (TARGET_SSE_PARTIAL_REGS && !optimize_size
18673 && GET_MODE (operands[2]) == DFmode)
18675 if (REG_P (operands[2]))
18677 rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
18678 emit_insn (gen_sse2_unpcklpd (op, op, op));
18680 if (REG_P (operands[3]))
18682 rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
18683 emit_insn (gen_sse2_unpcklpd (op, op, op));
18686 PUT_MODE (operands[1], GET_MODE (operands[0]));
18687 if (!sse_comparison_operator (operands[1], VOIDmode)
18688 || !rtx_equal_p (operands[0], operands[4]))
18690 rtx tmp = operands[5];
18691 operands[5] = operands[4];
18693 PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
18695 if (!rtx_equal_p (operands[0], operands[4]))
18697 operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
18698 if (const0_operand (operands[2], GET_MODE (operands[2])))
18700 operands[7] = operands[3];
18701 operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
18705 operands[7] = operands[2];
18706 operands[6] = operands[8];
18708 operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
18711 (define_expand "allocate_stack_worker"
18712 [(match_operand:SI 0 "register_operand" "")]
18713 "TARGET_STACK_PROBE"
18715 if (reload_completed)
18718 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18720 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18725 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18727 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18732 (define_insn "allocate_stack_worker_1"
18733 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18734 UNSPECV_STACK_PROBE)
18735 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18736 (clobber (match_scratch:SI 1 "=0"))
18737 (clobber (reg:CC FLAGS_REG))]
18738 "!TARGET_64BIT && TARGET_STACK_PROBE"
18740 [(set_attr "type" "multi")
18741 (set_attr "length" "5")])
18743 (define_expand "allocate_stack_worker_postreload"
18744 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18745 UNSPECV_STACK_PROBE)
18746 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18747 (clobber (match_dup 0))
18748 (clobber (reg:CC FLAGS_REG))])]
18752 (define_insn "allocate_stack_worker_rex64"
18753 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18754 UNSPECV_STACK_PROBE)
18755 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18756 (clobber (match_scratch:DI 1 "=0"))
18757 (clobber (reg:CC FLAGS_REG))]
18758 "TARGET_64BIT && TARGET_STACK_PROBE"
18760 [(set_attr "type" "multi")
18761 (set_attr "length" "5")])
18763 (define_expand "allocate_stack_worker_rex64_postreload"
18764 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18765 UNSPECV_STACK_PROBE)
18766 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18767 (clobber (match_dup 0))
18768 (clobber (reg:CC FLAGS_REG))])]
18772 (define_expand "allocate_stack"
18773 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18774 (minus:SI (reg:SI SP_REG)
18775 (match_operand:SI 1 "general_operand" "")))
18776 (clobber (reg:CC FLAGS_REG))])
18777 (parallel [(set (reg:SI SP_REG)
18778 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18779 (clobber (reg:CC FLAGS_REG))])]
18780 "TARGET_STACK_PROBE"
18782 #ifdef CHECK_STACK_LIMIT
18783 if (GET_CODE (operands[1]) == CONST_INT
18784 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18785 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18789 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18792 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18796 (define_expand "builtin_setjmp_receiver"
18797 [(label_ref (match_operand 0 "" ""))]
18798 "!TARGET_64BIT && flag_pic"
18800 emit_insn (gen_set_got (pic_offset_table_rtx));
18804 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18807 [(set (match_operand 0 "register_operand" "")
18808 (match_operator 3 "promotable_binary_operator"
18809 [(match_operand 1 "register_operand" "")
18810 (match_operand 2 "aligned_operand" "")]))
18811 (clobber (reg:CC FLAGS_REG))]
18812 "! TARGET_PARTIAL_REG_STALL && reload_completed
18813 && ((GET_MODE (operands[0]) == HImode
18814 && ((!optimize_size && !TARGET_FAST_PREFIX)
18815 || GET_CODE (operands[2]) != CONST_INT
18816 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18817 || (GET_MODE (operands[0]) == QImode
18818 && (TARGET_PROMOTE_QImode || optimize_size)))"
18819 [(parallel [(set (match_dup 0)
18820 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18821 (clobber (reg:CC FLAGS_REG))])]
18822 "operands[0] = gen_lowpart (SImode, operands[0]);
18823 operands[1] = gen_lowpart (SImode, operands[1]);
18824 if (GET_CODE (operands[3]) != ASHIFT)
18825 operands[2] = gen_lowpart (SImode, operands[2]);
18826 PUT_MODE (operands[3], SImode);")
18828 ; Promote the QImode tests, as i386 has encoding of the AND
18829 ; instruction with 32-bit sign-extended immediate and thus the
18830 ; instruction size is unchanged, except in the %eax case for
18831 ; which it is increased by one byte, hence the ! optimize_size.
18834 (compare (and (match_operand 1 "aligned_operand" "")
18835 (match_operand 2 "const_int_operand" ""))
18837 (set (match_operand 0 "register_operand" "")
18838 (and (match_dup 1) (match_dup 2)))]
18839 "! TARGET_PARTIAL_REG_STALL && reload_completed
18840 /* Ensure that the operand will remain sign-extended immediate. */
18841 && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
18843 && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
18844 || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
18845 [(parallel [(set (reg:CCNO FLAGS_REG)
18846 (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
18849 (and:SI (match_dup 1) (match_dup 2)))])]
18851 = gen_int_mode (INTVAL (operands[2])
18852 & GET_MODE_MASK (GET_MODE (operands[0])),
18854 operands[0] = gen_lowpart (SImode, operands[0]);
18855 operands[1] = gen_lowpart (SImode, operands[1]);")
18857 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18858 ; the TEST instruction with 32-bit sign-extended immediate and thus
18859 ; the instruction size would at least double, which is not what we
18860 ; want even with ! optimize_size.
18863 (compare (and (match_operand:HI 0 "aligned_operand" "")
18864 (match_operand:HI 1 "const_int_operand" ""))
18866 "! TARGET_PARTIAL_REG_STALL && reload_completed
18867 /* Ensure that the operand will remain sign-extended immediate. */
18868 && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
18869 && ! TARGET_FAST_PREFIX
18870 && ! optimize_size"
18871 [(set (reg:CCNO FLAGS_REG)
18872 (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
18875 = gen_int_mode (INTVAL (operands[1])
18876 & GET_MODE_MASK (GET_MODE (operands[0])),
18878 operands[0] = gen_lowpart (SImode, operands[0]);")
18881 [(set (match_operand 0 "register_operand" "")
18882 (neg (match_operand 1 "register_operand" "")))
18883 (clobber (reg:CC FLAGS_REG))]
18884 "! TARGET_PARTIAL_REG_STALL && reload_completed
18885 && (GET_MODE (operands[0]) == HImode
18886 || (GET_MODE (operands[0]) == QImode
18887 && (TARGET_PROMOTE_QImode || optimize_size)))"
18888 [(parallel [(set (match_dup 0)
18889 (neg:SI (match_dup 1)))
18890 (clobber (reg:CC FLAGS_REG))])]
18891 "operands[0] = gen_lowpart (SImode, operands[0]);
18892 operands[1] = gen_lowpart (SImode, operands[1]);")
18895 [(set (match_operand 0 "register_operand" "")
18896 (not (match_operand 1 "register_operand" "")))]
18897 "! TARGET_PARTIAL_REG_STALL && reload_completed
18898 && (GET_MODE (operands[0]) == HImode
18899 || (GET_MODE (operands[0]) == QImode
18900 && (TARGET_PROMOTE_QImode || optimize_size)))"
18901 [(set (match_dup 0)
18902 (not:SI (match_dup 1)))]
18903 "operands[0] = gen_lowpart (SImode, operands[0]);
18904 operands[1] = gen_lowpart (SImode, operands[1]);")
18907 [(set (match_operand 0 "register_operand" "")
18908 (if_then_else (match_operator 1 "comparison_operator"
18909 [(reg 17) (const_int 0)])
18910 (match_operand 2 "register_operand" "")
18911 (match_operand 3 "register_operand" "")))]
18912 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18913 && (GET_MODE (operands[0]) == HImode
18914 || (GET_MODE (operands[0]) == QImode
18915 && (TARGET_PROMOTE_QImode || optimize_size)))"
18916 [(set (match_dup 0)
18917 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18918 "operands[0] = gen_lowpart (SImode, operands[0]);
18919 operands[2] = gen_lowpart (SImode, operands[2]);
18920 operands[3] = gen_lowpart (SImode, operands[3]);")
18923 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18924 ;; transform a complex memory operation into two memory to register operations.
18926 ;; Don't push memory operands
18928 [(set (match_operand:SI 0 "push_operand" "")
18929 (match_operand:SI 1 "memory_operand" ""))
18930 (match_scratch:SI 2 "r")]
18931 "! optimize_size && ! TARGET_PUSH_MEMORY"
18932 [(set (match_dup 2) (match_dup 1))
18933 (set (match_dup 0) (match_dup 2))]
18937 [(set (match_operand:DI 0 "push_operand" "")
18938 (match_operand:DI 1 "memory_operand" ""))
18939 (match_scratch:DI 2 "r")]
18940 "! optimize_size && ! TARGET_PUSH_MEMORY"
18941 [(set (match_dup 2) (match_dup 1))
18942 (set (match_dup 0) (match_dup 2))]
18945 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18948 [(set (match_operand:SF 0 "push_operand" "")
18949 (match_operand:SF 1 "memory_operand" ""))
18950 (match_scratch:SF 2 "r")]
18951 "! optimize_size && ! TARGET_PUSH_MEMORY"
18952 [(set (match_dup 2) (match_dup 1))
18953 (set (match_dup 0) (match_dup 2))]
18957 [(set (match_operand:HI 0 "push_operand" "")
18958 (match_operand:HI 1 "memory_operand" ""))
18959 (match_scratch:HI 2 "r")]
18960 "! optimize_size && ! TARGET_PUSH_MEMORY"
18961 [(set (match_dup 2) (match_dup 1))
18962 (set (match_dup 0) (match_dup 2))]
18966 [(set (match_operand:QI 0 "push_operand" "")
18967 (match_operand:QI 1 "memory_operand" ""))
18968 (match_scratch:QI 2 "q")]
18969 "! optimize_size && ! TARGET_PUSH_MEMORY"
18970 [(set (match_dup 2) (match_dup 1))
18971 (set (match_dup 0) (match_dup 2))]
18974 ;; Don't move an immediate directly to memory when the instruction
18977 [(match_scratch:SI 1 "r")
18978 (set (match_operand:SI 0 "memory_operand" "")
18981 && ! TARGET_USE_MOV0
18982 && TARGET_SPLIT_LONG_MOVES
18983 && get_attr_length (insn) >= ix86_cost->large_insn
18984 && peep2_regno_dead_p (0, FLAGS_REG)"
18985 [(parallel [(set (match_dup 1) (const_int 0))
18986 (clobber (reg:CC FLAGS_REG))])
18987 (set (match_dup 0) (match_dup 1))]
18991 [(match_scratch:HI 1 "r")
18992 (set (match_operand:HI 0 "memory_operand" "")
18995 && ! TARGET_USE_MOV0
18996 && TARGET_SPLIT_LONG_MOVES
18997 && get_attr_length (insn) >= ix86_cost->large_insn
18998 && peep2_regno_dead_p (0, FLAGS_REG)"
18999 [(parallel [(set (match_dup 2) (const_int 0))
19000 (clobber (reg:CC FLAGS_REG))])
19001 (set (match_dup 0) (match_dup 1))]
19002 "operands[2] = gen_lowpart (SImode, operands[1]);")
19005 [(match_scratch:QI 1 "q")
19006 (set (match_operand:QI 0 "memory_operand" "")
19009 && ! TARGET_USE_MOV0
19010 && TARGET_SPLIT_LONG_MOVES
19011 && get_attr_length (insn) >= ix86_cost->large_insn
19012 && peep2_regno_dead_p (0, FLAGS_REG)"
19013 [(parallel [(set (match_dup 2) (const_int 0))
19014 (clobber (reg:CC FLAGS_REG))])
19015 (set (match_dup 0) (match_dup 1))]
19016 "operands[2] = gen_lowpart (SImode, operands[1]);")
19019 [(match_scratch:SI 2 "r")
19020 (set (match_operand:SI 0 "memory_operand" "")
19021 (match_operand:SI 1 "immediate_operand" ""))]
19023 && get_attr_length (insn) >= ix86_cost->large_insn
19024 && TARGET_SPLIT_LONG_MOVES"
19025 [(set (match_dup 2) (match_dup 1))
19026 (set (match_dup 0) (match_dup 2))]
19030 [(match_scratch:HI 2 "r")
19031 (set (match_operand:HI 0 "memory_operand" "")
19032 (match_operand:HI 1 "immediate_operand" ""))]
19033 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19034 && TARGET_SPLIT_LONG_MOVES"
19035 [(set (match_dup 2) (match_dup 1))
19036 (set (match_dup 0) (match_dup 2))]
19040 [(match_scratch:QI 2 "q")
19041 (set (match_operand:QI 0 "memory_operand" "")
19042 (match_operand:QI 1 "immediate_operand" ""))]
19043 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19044 && TARGET_SPLIT_LONG_MOVES"
19045 [(set (match_dup 2) (match_dup 1))
19046 (set (match_dup 0) (match_dup 2))]
19049 ;; Don't compare memory with zero, load and use a test instead.
19052 (compare (match_operand:SI 0 "memory_operand" "")
19054 (match_scratch:SI 3 "r")]
19055 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19056 [(set (match_dup 3) (match_dup 0))
19057 (set (reg:CCNO FLAGS_REG) (compare:CCNO (match_dup 3) (const_int 0)))]
19060 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19061 ;; Don't split NOTs with a displacement operand, because resulting XOR
19062 ;; will not be pairable anyway.
19064 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19065 ;; represented using a modRM byte. The XOR replacement is long decoded,
19066 ;; so this split helps here as well.
19068 ;; Note: Can't do this as a regular split because we can't get proper
19069 ;; lifetime information then.
19072 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19073 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19075 && peep2_regno_dead_p (0, FLAGS_REG)
19076 && ((TARGET_PENTIUM
19077 && (GET_CODE (operands[0]) != MEM
19078 || !memory_displacement_operand (operands[0], SImode)))
19079 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19080 [(parallel [(set (match_dup 0)
19081 (xor:SI (match_dup 1) (const_int -1)))
19082 (clobber (reg:CC FLAGS_REG))])]
19086 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19087 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19089 && peep2_regno_dead_p (0, FLAGS_REG)
19090 && ((TARGET_PENTIUM
19091 && (GET_CODE (operands[0]) != MEM
19092 || !memory_displacement_operand (operands[0], HImode)))
19093 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19094 [(parallel [(set (match_dup 0)
19095 (xor:HI (match_dup 1) (const_int -1)))
19096 (clobber (reg:CC FLAGS_REG))])]
19100 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19101 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19103 && peep2_regno_dead_p (0, FLAGS_REG)
19104 && ((TARGET_PENTIUM
19105 && (GET_CODE (operands[0]) != MEM
19106 || !memory_displacement_operand (operands[0], QImode)))
19107 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19108 [(parallel [(set (match_dup 0)
19109 (xor:QI (match_dup 1) (const_int -1)))
19110 (clobber (reg:CC FLAGS_REG))])]
19113 ;; Non pairable "test imm, reg" instructions can be translated to
19114 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19115 ;; byte opcode instead of two, have a short form for byte operands),
19116 ;; so do it for other CPUs as well. Given that the value was dead,
19117 ;; this should not create any new dependencies. Pass on the sub-word
19118 ;; versions if we're concerned about partial register stalls.
19122 (compare (and:SI (match_operand:SI 0 "register_operand" "")
19123 (match_operand:SI 1 "immediate_operand" ""))
19125 "ix86_match_ccmode (insn, CCNOmode)
19126 && (true_regnum (operands[0]) != 0
19127 || (GET_CODE (operands[1]) == CONST_INT
19128 && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
19129 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19131 [(set (reg:CCNO FLAGS_REG)
19132 (compare:CCNO (and:SI (match_dup 0)
19136 (and:SI (match_dup 0) (match_dup 1)))])]
19139 ;; We don't need to handle HImode case, because it will be promoted to SImode
19140 ;; on ! TARGET_PARTIAL_REG_STALL
19144 (compare (and:QI (match_operand:QI 0 "register_operand" "")
19145 (match_operand:QI 1 "immediate_operand" ""))
19147 "! TARGET_PARTIAL_REG_STALL
19148 && ix86_match_ccmode (insn, CCNOmode)
19149 && true_regnum (operands[0]) != 0
19150 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19152 [(set (reg:CCNO FLAGS_REG)
19153 (compare:CCNO (and:QI (match_dup 0)
19157 (and:QI (match_dup 0) (match_dup 1)))])]
19165 (match_operand 0 "ext_register_operand" "")
19168 (match_operand 1 "const_int_operand" ""))
19170 "! TARGET_PARTIAL_REG_STALL
19171 && ix86_match_ccmode (insn, CCNOmode)
19172 && true_regnum (operands[0]) != 0
19173 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19174 [(parallel [(set (reg:CCNO FLAGS_REG)
19183 (set (zero_extract:SI (match_dup 0)
19194 ;; Don't do logical operations with memory inputs.
19196 [(match_scratch:SI 2 "r")
19197 (parallel [(set (match_operand:SI 0 "register_operand" "")
19198 (match_operator:SI 3 "arith_or_logical_operator"
19200 (match_operand:SI 1 "memory_operand" "")]))
19201 (clobber (reg:CC FLAGS_REG))])]
19202 "! optimize_size && ! TARGET_READ_MODIFY"
19203 [(set (match_dup 2) (match_dup 1))
19204 (parallel [(set (match_dup 0)
19205 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19206 (clobber (reg:CC FLAGS_REG))])]
19210 [(match_scratch:SI 2 "r")
19211 (parallel [(set (match_operand:SI 0 "register_operand" "")
19212 (match_operator:SI 3 "arith_or_logical_operator"
19213 [(match_operand:SI 1 "memory_operand" "")
19215 (clobber (reg:CC FLAGS_REG))])]
19216 "! optimize_size && ! TARGET_READ_MODIFY"
19217 [(set (match_dup 2) (match_dup 1))
19218 (parallel [(set (match_dup 0)
19219 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19220 (clobber (reg:CC FLAGS_REG))])]
19223 ; Don't do logical operations with memory outputs
19225 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19226 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19227 ; the same decoder scheduling characteristics as the original.
19230 [(match_scratch:SI 2 "r")
19231 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19232 (match_operator:SI 3 "arith_or_logical_operator"
19234 (match_operand:SI 1 "nonmemory_operand" "")]))
19235 (clobber (reg:CC FLAGS_REG))])]
19236 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19237 [(set (match_dup 2) (match_dup 0))
19238 (parallel [(set (match_dup 2)
19239 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19240 (clobber (reg:CC FLAGS_REG))])
19241 (set (match_dup 0) (match_dup 2))]
19245 [(match_scratch:SI 2 "r")
19246 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19247 (match_operator:SI 3 "arith_or_logical_operator"
19248 [(match_operand:SI 1 "nonmemory_operand" "")
19250 (clobber (reg:CC FLAGS_REG))])]
19251 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19252 [(set (match_dup 2) (match_dup 0))
19253 (parallel [(set (match_dup 2)
19254 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19255 (clobber (reg:CC FLAGS_REG))])
19256 (set (match_dup 0) (match_dup 2))]
19259 ;; Attempt to always use XOR for zeroing registers.
19261 [(set (match_operand 0 "register_operand" "")
19263 "(GET_MODE (operands[0]) == QImode
19264 || GET_MODE (operands[0]) == HImode
19265 || GET_MODE (operands[0]) == SImode
19266 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19267 && (! TARGET_USE_MOV0 || optimize_size)
19268 && peep2_regno_dead_p (0, FLAGS_REG)"
19269 [(parallel [(set (match_dup 0) (const_int 0))
19270 (clobber (reg:CC FLAGS_REG))])]
19271 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19275 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19277 "(GET_MODE (operands[0]) == QImode
19278 || GET_MODE (operands[0]) == HImode)
19279 && (! TARGET_USE_MOV0 || optimize_size)
19280 && peep2_regno_dead_p (0, FLAGS_REG)"
19281 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19282 (clobber (reg:CC FLAGS_REG))])])
19284 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19286 [(set (match_operand 0 "register_operand" "")
19288 "(GET_MODE (operands[0]) == HImode
19289 || GET_MODE (operands[0]) == SImode
19290 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19291 && (optimize_size || TARGET_PENTIUM)
19292 && peep2_regno_dead_p (0, FLAGS_REG)"
19293 [(parallel [(set (match_dup 0) (const_int -1))
19294 (clobber (reg:CC FLAGS_REG))])]
19295 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19298 ;; Attempt to convert simple leas to adds. These can be created by
19301 [(set (match_operand:SI 0 "register_operand" "")
19302 (plus:SI (match_dup 0)
19303 (match_operand:SI 1 "nonmemory_operand" "")))]
19304 "peep2_regno_dead_p (0, FLAGS_REG)"
19305 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19306 (clobber (reg:CC FLAGS_REG))])]
19310 [(set (match_operand:SI 0 "register_operand" "")
19311 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19312 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19313 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19314 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19315 (clobber (reg:CC FLAGS_REG))])]
19316 "operands[2] = gen_lowpart (SImode, operands[2]);")
19319 [(set (match_operand:DI 0 "register_operand" "")
19320 (plus:DI (match_dup 0)
19321 (match_operand:DI 1 "x86_64_general_operand" "")))]
19322 "peep2_regno_dead_p (0, FLAGS_REG)"
19323 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19324 (clobber (reg:CC FLAGS_REG))])]
19328 [(set (match_operand:SI 0 "register_operand" "")
19329 (mult:SI (match_dup 0)
19330 (match_operand:SI 1 "const_int_operand" "")))]
19331 "exact_log2 (INTVAL (operands[1])) >= 0
19332 && peep2_regno_dead_p (0, FLAGS_REG)"
19333 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19334 (clobber (reg:CC FLAGS_REG))])]
19335 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19338 [(set (match_operand:DI 0 "register_operand" "")
19339 (mult:DI (match_dup 0)
19340 (match_operand:DI 1 "const_int_operand" "")))]
19341 "exact_log2 (INTVAL (operands[1])) >= 0
19342 && peep2_regno_dead_p (0, FLAGS_REG)"
19343 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19344 (clobber (reg:CC FLAGS_REG))])]
19345 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19348 [(set (match_operand:SI 0 "register_operand" "")
19349 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19350 (match_operand:DI 2 "const_int_operand" "")) 0))]
19351 "exact_log2 (INTVAL (operands[2])) >= 0
19352 && REGNO (operands[0]) == REGNO (operands[1])
19353 && peep2_regno_dead_p (0, FLAGS_REG)"
19354 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19355 (clobber (reg:CC FLAGS_REG))])]
19356 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19358 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19359 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19360 ;; many CPUs it is also faster, since special hardware to avoid esp
19361 ;; dependencies is present.
19363 ;; While some of these conversions may be done using splitters, we use peepholes
19364 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19366 ;; Convert prologue esp subtractions to push.
19367 ;; We need register to push. In order to keep verify_flow_info happy we have
19369 ;; - use scratch and clobber it in order to avoid dependencies
19370 ;; - use already live register
19371 ;; We can't use the second way right now, since there is no reliable way how to
19372 ;; verify that given register is live. First choice will also most likely in
19373 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19374 ;; call clobbered registers are dead. We may want to use base pointer as an
19375 ;; alternative when no register is available later.
19378 [(match_scratch:SI 0 "r")
19379 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19380 (clobber (reg:CC FLAGS_REG))
19381 (clobber (mem:BLK (scratch)))])]
19382 "optimize_size || !TARGET_SUB_ESP_4"
19383 [(clobber (match_dup 0))
19384 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19385 (clobber (mem:BLK (scratch)))])])
19388 [(match_scratch:SI 0 "r")
19389 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19390 (clobber (reg:CC FLAGS_REG))
19391 (clobber (mem:BLK (scratch)))])]
19392 "optimize_size || !TARGET_SUB_ESP_8"
19393 [(clobber (match_dup 0))
19394 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19395 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19396 (clobber (mem:BLK (scratch)))])])
19398 ;; Convert esp subtractions to push.
19400 [(match_scratch:SI 0 "r")
19401 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19402 (clobber (reg:CC FLAGS_REG))])]
19403 "optimize_size || !TARGET_SUB_ESP_4"
19404 [(clobber (match_dup 0))
19405 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19408 [(match_scratch:SI 0 "r")
19409 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19410 (clobber (reg:CC FLAGS_REG))])]
19411 "optimize_size || !TARGET_SUB_ESP_8"
19412 [(clobber (match_dup 0))
19413 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19414 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19416 ;; Convert epilogue deallocator to pop.
19418 [(match_scratch:SI 0 "r")
19419 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19420 (clobber (reg:CC FLAGS_REG))
19421 (clobber (mem:BLK (scratch)))])]
19422 "optimize_size || !TARGET_ADD_ESP_4"
19423 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19424 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19425 (clobber (mem:BLK (scratch)))])]
19428 ;; Two pops case is tricky, since pop causes dependency on destination register.
19429 ;; We use two registers if available.
19431 [(match_scratch:SI 0 "r")
19432 (match_scratch:SI 1 "r")
19433 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19434 (clobber (reg:CC FLAGS_REG))
19435 (clobber (mem:BLK (scratch)))])]
19436 "optimize_size || !TARGET_ADD_ESP_8"
19437 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19438 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19439 (clobber (mem:BLK (scratch)))])
19440 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19441 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19445 [(match_scratch:SI 0 "r")
19446 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19447 (clobber (reg:CC FLAGS_REG))
19448 (clobber (mem:BLK (scratch)))])]
19450 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19451 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19452 (clobber (mem:BLK (scratch)))])
19453 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19454 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19457 ;; Convert esp additions to pop.
19459 [(match_scratch:SI 0 "r")
19460 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19461 (clobber (reg:CC FLAGS_REG))])]
19463 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19464 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19467 ;; Two pops case is tricky, since pop causes dependency on destination register.
19468 ;; We use two registers if available.
19470 [(match_scratch:SI 0 "r")
19471 (match_scratch:SI 1 "r")
19472 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19473 (clobber (reg:CC FLAGS_REG))])]
19475 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19476 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19477 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19478 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19482 [(match_scratch:SI 0 "r")
19483 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19484 (clobber (reg:CC FLAGS_REG))])]
19486 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19487 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19488 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19489 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19492 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19493 ;; required and register dies.
19496 (compare (match_operand:SI 0 "register_operand" "")
19497 (match_operand:SI 1 "incdec_operand" "")))]
19498 "ix86_match_ccmode (insn, CCGCmode)
19499 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19500 [(parallel [(set (reg:CCGC FLAGS_REG)
19501 (compare:CCGC (match_dup 0)
19503 (clobber (match_dup 0))])]
19508 (compare (match_operand:HI 0 "register_operand" "")
19509 (match_operand:HI 1 "incdec_operand" "")))]
19510 "ix86_match_ccmode (insn, CCGCmode)
19511 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19512 [(parallel [(set (reg:CCGC FLAGS_REG)
19513 (compare:CCGC (match_dup 0)
19515 (clobber (match_dup 0))])]
19520 (compare (match_operand:QI 0 "register_operand" "")
19521 (match_operand:QI 1 "incdec_operand" "")))]
19522 "ix86_match_ccmode (insn, CCGCmode)
19523 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19524 [(parallel [(set (reg:CCGC FLAGS_REG)
19525 (compare:CCGC (match_dup 0)
19527 (clobber (match_dup 0))])]
19530 ;; Convert compares with 128 to shorter add -128
19533 (compare (match_operand:SI 0 "register_operand" "")
19535 "ix86_match_ccmode (insn, CCGCmode)
19536 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19537 [(parallel [(set (reg:CCGC FLAGS_REG)
19538 (compare:CCGC (match_dup 0)
19540 (clobber (match_dup 0))])]
19545 (compare (match_operand:HI 0 "register_operand" "")
19547 "ix86_match_ccmode (insn, CCGCmode)
19548 && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
19549 [(parallel [(set (reg:CCGC FLAGS_REG)
19550 (compare:CCGC (match_dup 0)
19552 (clobber (match_dup 0))])]
19556 [(match_scratch:DI 0 "r")
19557 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19558 (clobber (reg:CC FLAGS_REG))
19559 (clobber (mem:BLK (scratch)))])]
19560 "optimize_size || !TARGET_SUB_ESP_4"
19561 [(clobber (match_dup 0))
19562 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19563 (clobber (mem:BLK (scratch)))])])
19566 [(match_scratch:DI 0 "r")
19567 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19568 (clobber (reg:CC FLAGS_REG))
19569 (clobber (mem:BLK (scratch)))])]
19570 "optimize_size || !TARGET_SUB_ESP_8"
19571 [(clobber (match_dup 0))
19572 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19573 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19574 (clobber (mem:BLK (scratch)))])])
19576 ;; Convert esp subtractions to push.
19578 [(match_scratch:DI 0 "r")
19579 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19580 (clobber (reg:CC FLAGS_REG))])]
19581 "optimize_size || !TARGET_SUB_ESP_4"
19582 [(clobber (match_dup 0))
19583 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19586 [(match_scratch:DI 0 "r")
19587 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19588 (clobber (reg:CC FLAGS_REG))])]
19589 "optimize_size || !TARGET_SUB_ESP_8"
19590 [(clobber (match_dup 0))
19591 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19592 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19594 ;; Convert epilogue deallocator to pop.
19596 [(match_scratch:DI 0 "r")
19597 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19598 (clobber (reg:CC FLAGS_REG))
19599 (clobber (mem:BLK (scratch)))])]
19600 "optimize_size || !TARGET_ADD_ESP_4"
19601 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19602 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19603 (clobber (mem:BLK (scratch)))])]
19606 ;; Two pops case is tricky, since pop causes dependency on destination register.
19607 ;; We use two registers if available.
19609 [(match_scratch:DI 0 "r")
19610 (match_scratch:DI 1 "r")
19611 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19612 (clobber (reg:CC FLAGS_REG))
19613 (clobber (mem:BLK (scratch)))])]
19614 "optimize_size || !TARGET_ADD_ESP_8"
19615 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19616 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19617 (clobber (mem:BLK (scratch)))])
19618 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19619 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19623 [(match_scratch:DI 0 "r")
19624 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19625 (clobber (reg:CC FLAGS_REG))
19626 (clobber (mem:BLK (scratch)))])]
19628 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19629 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19630 (clobber (mem:BLK (scratch)))])
19631 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19632 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19635 ;; Convert esp additions to pop.
19637 [(match_scratch:DI 0 "r")
19638 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19639 (clobber (reg:CC FLAGS_REG))])]
19641 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19642 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19645 ;; Two pops case is tricky, since pop causes dependency on destination register.
19646 ;; We use two registers if available.
19648 [(match_scratch:DI 0 "r")
19649 (match_scratch:DI 1 "r")
19650 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19651 (clobber (reg:CC FLAGS_REG))])]
19653 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19654 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19655 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19656 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19660 [(match_scratch:DI 0 "r")
19661 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19662 (clobber (reg:CC FLAGS_REG))])]
19664 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19665 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19666 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19667 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19670 ;; Convert imul by three, five and nine into lea
19673 [(set (match_operand:SI 0 "register_operand" "")
19674 (mult:SI (match_operand:SI 1 "register_operand" "")
19675 (match_operand:SI 2 "const_int_operand" "")))
19676 (clobber (reg:CC FLAGS_REG))])]
19677 "INTVAL (operands[2]) == 3
19678 || INTVAL (operands[2]) == 5
19679 || INTVAL (operands[2]) == 9"
19680 [(set (match_dup 0)
19681 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19683 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19687 [(set (match_operand:SI 0 "register_operand" "")
19688 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19689 (match_operand:SI 2 "const_int_operand" "")))
19690 (clobber (reg:CC FLAGS_REG))])]
19692 && (INTVAL (operands[2]) == 3
19693 || INTVAL (operands[2]) == 5
19694 || INTVAL (operands[2]) == 9)"
19695 [(set (match_dup 0) (match_dup 1))
19697 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19699 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19703 [(set (match_operand:DI 0 "register_operand" "")
19704 (mult:DI (match_operand:DI 1 "register_operand" "")
19705 (match_operand:DI 2 "const_int_operand" "")))
19706 (clobber (reg:CC FLAGS_REG))])]
19708 && (INTVAL (operands[2]) == 3
19709 || INTVAL (operands[2]) == 5
19710 || INTVAL (operands[2]) == 9)"
19711 [(set (match_dup 0)
19712 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19714 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19718 [(set (match_operand:DI 0 "register_operand" "")
19719 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19720 (match_operand:DI 2 "const_int_operand" "")))
19721 (clobber (reg:CC FLAGS_REG))])]
19724 && (INTVAL (operands[2]) == 3
19725 || INTVAL (operands[2]) == 5
19726 || INTVAL (operands[2]) == 9)"
19727 [(set (match_dup 0) (match_dup 1))
19729 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19731 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19733 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19734 ;; imul $32bit_imm, reg, reg is direct decoded.
19736 [(match_scratch:DI 3 "r")
19737 (parallel [(set (match_operand:DI 0 "register_operand" "")
19738 (mult:DI (match_operand:DI 1 "memory_operand" "")
19739 (match_operand:DI 2 "immediate_operand" "")))
19740 (clobber (reg:CC FLAGS_REG))])]
19741 "TARGET_K8 && !optimize_size
19742 && (GET_CODE (operands[2]) != CONST_INT
19743 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19744 [(set (match_dup 3) (match_dup 1))
19745 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19746 (clobber (reg:CC FLAGS_REG))])]
19750 [(match_scratch:SI 3 "r")
19751 (parallel [(set (match_operand:SI 0 "register_operand" "")
19752 (mult:SI (match_operand:SI 1 "memory_operand" "")
19753 (match_operand:SI 2 "immediate_operand" "")))
19754 (clobber (reg:CC FLAGS_REG))])]
19755 "TARGET_K8 && !optimize_size
19756 && (GET_CODE (operands[2]) != CONST_INT
19757 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19758 [(set (match_dup 3) (match_dup 1))
19759 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19760 (clobber (reg:CC FLAGS_REG))])]
19764 [(match_scratch:SI 3 "r")
19765 (parallel [(set (match_operand:DI 0 "register_operand" "")
19767 (mult:SI (match_operand:SI 1 "memory_operand" "")
19768 (match_operand:SI 2 "immediate_operand" ""))))
19769 (clobber (reg:CC FLAGS_REG))])]
19770 "TARGET_K8 && !optimize_size
19771 && (GET_CODE (operands[2]) != CONST_INT
19772 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19773 [(set (match_dup 3) (match_dup 1))
19774 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19775 (clobber (reg:CC FLAGS_REG))])]
19778 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19779 ;; Convert it into imul reg, reg
19780 ;; It would be better to force assembler to encode instruction using long
19781 ;; immediate, but there is apparently no way to do so.
19783 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19784 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19785 (match_operand:DI 2 "const_int_operand" "")))
19786 (clobber (reg:CC FLAGS_REG))])
19787 (match_scratch:DI 3 "r")]
19788 "TARGET_K8 && !optimize_size
19789 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19790 [(set (match_dup 3) (match_dup 2))
19791 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19792 (clobber (reg:CC FLAGS_REG))])]
19794 if (!rtx_equal_p (operands[0], operands[1]))
19795 emit_move_insn (operands[0], operands[1]);
19799 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19800 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19801 (match_operand:SI 2 "const_int_operand" "")))
19802 (clobber (reg:CC FLAGS_REG))])
19803 (match_scratch:SI 3 "r")]
19804 "TARGET_K8 && !optimize_size
19805 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19806 [(set (match_dup 3) (match_dup 2))
19807 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19808 (clobber (reg:CC FLAGS_REG))])]
19810 if (!rtx_equal_p (operands[0], operands[1]))
19811 emit_move_insn (operands[0], operands[1]);
19815 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19816 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19817 (match_operand:HI 2 "immediate_operand" "")))
19818 (clobber (reg:CC FLAGS_REG))])
19819 (match_scratch:HI 3 "r")]
19820 "TARGET_K8 && !optimize_size"
19821 [(set (match_dup 3) (match_dup 2))
19822 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19823 (clobber (reg:CC FLAGS_REG))])]
19825 if (!rtx_equal_p (operands[0], operands[1]))
19826 emit_move_insn (operands[0], operands[1]);
19829 ;; Call-value patterns last so that the wildcard operand does not
19830 ;; disrupt insn-recog's switch tables.
19832 (define_insn "*call_value_pop_0"
19833 [(set (match_operand 0 "" "")
19834 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19835 (match_operand:SI 2 "" "")))
19836 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19837 (match_operand:SI 3 "immediate_operand" "")))]
19840 if (SIBLING_CALL_P (insn))
19843 return "call\t%P1";
19845 [(set_attr "type" "callv")])
19847 (define_insn "*call_value_pop_1"
19848 [(set (match_operand 0 "" "")
19849 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19850 (match_operand:SI 2 "" "")))
19851 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19852 (match_operand:SI 3 "immediate_operand" "i")))]
19855 if (constant_call_address_operand (operands[1], Pmode))
19857 if (SIBLING_CALL_P (insn))
19860 return "call\t%P1";
19862 if (SIBLING_CALL_P (insn))
19865 return "call\t%A1";
19867 [(set_attr "type" "callv")])
19869 (define_insn "*call_value_0"
19870 [(set (match_operand 0 "" "")
19871 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19872 (match_operand:SI 2 "" "")))]
19875 if (SIBLING_CALL_P (insn))
19878 return "call\t%P1";
19880 [(set_attr "type" "callv")])
19882 (define_insn "*call_value_0_rex64"
19883 [(set (match_operand 0 "" "")
19884 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19885 (match_operand:DI 2 "const_int_operand" "")))]
19888 if (SIBLING_CALL_P (insn))
19891 return "call\t%P1";
19893 [(set_attr "type" "callv")])
19895 (define_insn "*call_value_1"
19896 [(set (match_operand 0 "" "")
19897 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19898 (match_operand:SI 2 "" "")))]
19899 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19901 if (constant_call_address_operand (operands[1], Pmode))
19902 return "call\t%P1";
19903 return "call\t%*%1";
19905 [(set_attr "type" "callv")])
19907 (define_insn "*sibcall_value_1"
19908 [(set (match_operand 0 "" "")
19909 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19910 (match_operand:SI 2 "" "")))]
19911 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19913 if (constant_call_address_operand (operands[1], Pmode))
19915 return "jmp\t%*%1";
19917 [(set_attr "type" "callv")])
19919 (define_insn "*call_value_1_rex64"
19920 [(set (match_operand 0 "" "")
19921 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19922 (match_operand:DI 2 "" "")))]
19923 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19925 if (constant_call_address_operand (operands[1], Pmode))
19926 return "call\t%P1";
19927 return "call\t%A1";
19929 [(set_attr "type" "callv")])
19931 (define_insn "*sibcall_value_1_rex64"
19932 [(set (match_operand 0 "" "")
19933 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19934 (match_operand:DI 2 "" "")))]
19935 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19937 [(set_attr "type" "callv")])
19939 (define_insn "*sibcall_value_1_rex64_v"
19940 [(set (match_operand 0 "" "")
19941 (call (mem:QI (reg:DI 40))
19942 (match_operand:DI 1 "" "")))]
19943 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19945 [(set_attr "type" "callv")])
19947 (define_insn "trap"
19948 [(trap_if (const_int 1) (const_int 5))]
19952 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19953 ;;; for the sake of bounds checking. By emitting bounds checks as
19954 ;;; conditional traps rather than as conditional jumps around
19955 ;;; unconditional traps we avoid introducing spurious basic-block
19956 ;;; boundaries and facilitate elimination of redundant checks. In
19957 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19960 ;;; FIXME: Static branch prediction rules for ix86 are such that
19961 ;;; forward conditional branches predict as untaken. As implemented
19962 ;;; below, pseudo conditional traps violate that rule. We should use
19963 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19964 ;;; section loaded at the end of the text segment and branch forward
19965 ;;; there on bounds-failure, and then jump back immediately (in case
19966 ;;; the system chooses to ignore bounds violations, or to report
19967 ;;; violations and continue execution).
19969 (define_expand "conditional_trap"
19970 [(trap_if (match_operator 0 "comparison_operator"
19971 [(match_dup 2) (const_int 0)])
19972 (match_operand 1 "const_int_operand" ""))]
19975 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19976 ix86_expand_compare (GET_CODE (operands[0]),
19982 (define_insn "*conditional_trap_1"
19983 [(trap_if (match_operator 0 "comparison_operator"
19984 [(reg 17) (const_int 0)])
19985 (match_operand 1 "const_int_operand" ""))]
19988 operands[2] = gen_label_rtx ();
19989 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19990 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19991 CODE_LABEL_NUMBER (operands[2]));
19995 ;; Pentium III SIMD instructions.
19997 ;; Moves for SSE/MMX regs.
19999 (define_insn "movv4sf_internal"
20000 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
20001 (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
20005 movaps\t{%1, %0|%0, %1}
20006 movaps\t{%1, %0|%0, %1}"
20007 [(set_attr "type" "ssemov")
20008 (set_attr "mode" "V4SF")])
20011 [(set (match_operand:V4SF 0 "register_operand" "")
20012 (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
20014 [(set (match_dup 0)
20016 (vec_duplicate:V4SF (match_dup 1))
20020 operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
20021 operands[2] = CONST0_RTX (V4SFmode);
20024 (define_insn "movv4si_internal"
20025 [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
20026 (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
20029 switch (which_alternative)
20032 if (get_attr_mode (insn) == MODE_V4SF)
20033 return "xorps\t%0, %0";
20035 return "pxor\t%0, %0";
20038 if (get_attr_mode (insn) == MODE_V4SF)
20039 return "movaps\t{%1, %0|%0, %1}";
20041 return "movdqa\t{%1, %0|%0, %1}";
20046 [(set_attr "type" "ssemov")
20048 (cond [(eq_attr "alternative" "0,1")
20050 (ne (symbol_ref "optimize_size")
20052 (const_string "V4SF")
20053 (const_string "TI"))
20054 (eq_attr "alternative" "2")
20056 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20058 (ne (symbol_ref "optimize_size")
20060 (const_string "V4SF")
20061 (const_string "TI"))]
20062 (const_string "TI")))])
20064 (define_insn "movv2di_internal"
20065 [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
20066 (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
20069 switch (which_alternative)
20072 if (get_attr_mode (insn) == MODE_V4SF)
20073 return "xorps\t%0, %0";
20075 return "pxor\t%0, %0";
20078 if (get_attr_mode (insn) == MODE_V4SF)
20079 return "movaps\t{%1, %0|%0, %1}";
20081 return "movdqa\t{%1, %0|%0, %1}";
20086 [(set_attr "type" "ssemov")
20088 (cond [(eq_attr "alternative" "0,1")
20090 (ne (symbol_ref "optimize_size")
20092 (const_string "V4SF")
20093 (const_string "TI"))
20094 (eq_attr "alternative" "2")
20096 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20098 (ne (symbol_ref "optimize_size")
20100 (const_string "V4SF")
20101 (const_string "TI"))]
20102 (const_string "TI")))])
20105 [(set (match_operand:V2DF 0 "register_operand" "")
20106 (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
20108 [(set (match_dup 0)
20110 (vec_duplicate:V2DF (match_dup 1))
20114 operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
20115 operands[2] = CONST0_RTX (V2DFmode);
20118 (define_insn "movv8qi_internal"
20119 [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20120 (match_operand:V8QI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20122 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20125 movq\t{%1, %0|%0, %1}
20126 movq\t{%1, %0|%0, %1}
20127 movdq2q\t{%1, %0|%0, %1}
20128 movq2dq\t{%1, %0|%0, %1}
20129 movq\t{%1, %0|%0, %1}
20130 movq\t{%1, %0|%0, %1}"
20131 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20132 (set_attr "mode" "DI")])
20134 (define_insn "movv4hi_internal"
20135 [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20136 (match_operand:V4HI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20138 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20141 movq\t{%1, %0|%0, %1}
20142 movq\t{%1, %0|%0, %1}
20143 movdq2q\t{%1, %0|%0, %1}
20144 movq2dq\t{%1, %0|%0, %1}
20145 movq\t{%1, %0|%0, %1}
20146 movq\t{%1, %0|%0, %1}"
20147 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20148 (set_attr "mode" "DI")])
20150 (define_insn "*movv2si_internal"
20151 [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*Y,?m")
20152 (match_operand:V2SI 1 "vector_move_operand" "C,ym,y,*Y,y,*Ym,*Y"))]
20154 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20157 movq\t{%1, %0|%0, %1}
20158 movq\t{%1, %0|%0, %1}
20159 movdq2q\t{%1, %0|%0, %1}
20160 movq2dq\t{%1, %0|%0, %1}
20161 movq\t{%1, %0|%0, %1}
20162 movq\t{%1, %0|%0, %1}"
20163 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20164 (set_attr "mode" "DI")])
20166 (define_insn "movv2sf_internal"
20167 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m,!y,!*Y,?*x,?m")
20168 (match_operand:V2SF 1 "vector_move_operand" "C,ym,y,*Y,y,*xm,*x"))]
20170 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20173 movq\t{%1, %0|%0, %1}
20174 movq\t{%1, %0|%0, %1}
20175 movdq2q\t{%1, %0|%0, %1}
20176 movq2dq\t{%1, %0|%0, %1}
20177 movlps\t{%1, %0|%0, %1}
20178 movlps\t{%1, %0|%0, %1}"
20179 [(set_attr "type" "mmxmov,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,ssemov")
20180 (set_attr "mode" "DI,DI,DI,DI,DI,V2SF,V2SF")])
20182 (define_expand "movti"
20183 [(set (match_operand:TI 0 "nonimmediate_operand" "")
20184 (match_operand:TI 1 "nonimmediate_operand" ""))]
20185 "TARGET_SSE || TARGET_64BIT"
20188 ix86_expand_move (TImode, operands);
20190 ix86_expand_vector_move (TImode, operands);
20194 (define_expand "movtf"
20195 [(set (match_operand:TF 0 "nonimmediate_operand" "")
20196 (match_operand:TF 1 "nonimmediate_operand" ""))]
20200 ix86_expand_move (TFmode, operands);
20202 ix86_expand_vector_move (TFmode, operands);
20206 (define_insn "movv2df_internal"
20207 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
20208 (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
20210 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20212 switch (which_alternative)
20215 if (get_attr_mode (insn) == MODE_V4SF)
20216 return "xorps\t%0, %0";
20218 return "xorpd\t%0, %0";
20221 if (get_attr_mode (insn) == MODE_V4SF)
20222 return "movaps\t{%1, %0|%0, %1}";
20224 return "movapd\t{%1, %0|%0, %1}";
20229 [(set_attr "type" "ssemov")
20231 (cond [(eq_attr "alternative" "0,1")
20233 (ne (symbol_ref "optimize_size")
20235 (const_string "V4SF")
20236 (const_string "V2DF"))
20237 (eq_attr "alternative" "2")
20239 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20241 (ne (symbol_ref "optimize_size")
20243 (const_string "V4SF")
20244 (const_string "V2DF"))]
20245 (const_string "V2DF")))])
20247 (define_insn "movv8hi_internal"
20248 [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
20249 (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
20251 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20253 switch (which_alternative)
20256 if (get_attr_mode (insn) == MODE_V4SF)
20257 return "xorps\t%0, %0";
20259 return "pxor\t%0, %0";
20262 if (get_attr_mode (insn) == MODE_V4SF)
20263 return "movaps\t{%1, %0|%0, %1}";
20265 return "movdqa\t{%1, %0|%0, %1}";
20270 [(set_attr "type" "ssemov")
20272 (cond [(eq_attr "alternative" "0,1")
20274 (ne (symbol_ref "optimize_size")
20276 (const_string "V4SF")
20277 (const_string "TI"))
20278 (eq_attr "alternative" "2")
20280 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20282 (ne (symbol_ref "optimize_size")
20284 (const_string "V4SF")
20285 (const_string "TI"))]
20286 (const_string "TI")))])
20288 (define_insn "movv16qi_internal"
20289 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
20290 (match_operand:V16QI 1 "vector_move_operand" "C,xm,x"))]
20292 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20294 switch (which_alternative)
20297 if (get_attr_mode (insn) == MODE_V4SF)
20298 return "xorps\t%0, %0";
20300 return "pxor\t%0, %0";
20303 if (get_attr_mode (insn) == MODE_V4SF)
20304 return "movaps\t{%1, %0|%0, %1}";
20306 return "movdqa\t{%1, %0|%0, %1}";
20311 [(set_attr "type" "ssemov")
20313 (cond [(eq_attr "alternative" "0,1")
20315 (ne (symbol_ref "optimize_size")
20317 (const_string "V4SF")
20318 (const_string "TI"))
20319 (eq_attr "alternative" "2")
20321 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20323 (ne (symbol_ref "optimize_size")
20325 (const_string "V4SF")
20326 (const_string "TI"))]
20327 (const_string "TI")))])
20329 (define_expand "movv2df"
20330 [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
20331 (match_operand:V2DF 1 "nonimmediate_operand" ""))]
20334 ix86_expand_vector_move (V2DFmode, operands);
20338 (define_expand "movv8hi"
20339 [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
20340 (match_operand:V8HI 1 "nonimmediate_operand" ""))]
20343 ix86_expand_vector_move (V8HImode, operands);
20347 (define_expand "movv16qi"
20348 [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
20349 (match_operand:V16QI 1 "nonimmediate_operand" ""))]
20352 ix86_expand_vector_move (V16QImode, operands);
20356 (define_expand "movv4sf"
20357 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20358 (match_operand:V4SF 1 "nonimmediate_operand" ""))]
20361 ix86_expand_vector_move (V4SFmode, operands);
20365 (define_expand "movv4si"
20366 [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
20367 (match_operand:V4SI 1 "nonimmediate_operand" ""))]
20370 ix86_expand_vector_move (V4SImode, operands);
20374 (define_expand "movv2di"
20375 [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
20376 (match_operand:V2DI 1 "nonimmediate_operand" ""))]
20379 ix86_expand_vector_move (V2DImode, operands);
20383 (define_expand "movv2si"
20384 [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
20385 (match_operand:V2SI 1 "nonimmediate_operand" ""))]
20388 ix86_expand_vector_move (V2SImode, operands);
20392 (define_expand "movv4hi"
20393 [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
20394 (match_operand:V4HI 1 "nonimmediate_operand" ""))]
20397 ix86_expand_vector_move (V4HImode, operands);
20401 (define_expand "movv8qi"
20402 [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
20403 (match_operand:V8QI 1 "nonimmediate_operand" ""))]
20406 ix86_expand_vector_move (V8QImode, operands);
20410 (define_expand "movv2sf"
20411 [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
20412 (match_operand:V2SF 1 "nonimmediate_operand" ""))]
20415 ix86_expand_vector_move (V2SFmode, operands);
20419 (define_insn "*pushti"
20420 [(set (match_operand:TI 0 "push_operand" "=<")
20421 (match_operand:TI 1 "register_operand" "x"))]
20425 (define_insn "*pushv2df"
20426 [(set (match_operand:V2DF 0 "push_operand" "=<")
20427 (match_operand:V2DF 1 "register_operand" "x"))]
20431 (define_insn "*pushv2di"
20432 [(set (match_operand:V2DI 0 "push_operand" "=<")
20433 (match_operand:V2DI 1 "register_operand" "x"))]
20437 (define_insn "*pushv8hi"
20438 [(set (match_operand:V8HI 0 "push_operand" "=<")
20439 (match_operand:V8HI 1 "register_operand" "x"))]
20443 (define_insn "*pushv16qi"
20444 [(set (match_operand:V16QI 0 "push_operand" "=<")
20445 (match_operand:V16QI 1 "register_operand" "x"))]
20449 (define_insn "*pushv4sf"
20450 [(set (match_operand:V4SF 0 "push_operand" "=<")
20451 (match_operand:V4SF 1 "register_operand" "x"))]
20455 (define_insn "*pushv4si"
20456 [(set (match_operand:V4SI 0 "push_operand" "=<")
20457 (match_operand:V4SI 1 "register_operand" "x"))]
20461 (define_insn "*pushv2si"
20462 [(set (match_operand:V2SI 0 "push_operand" "=<")
20463 (match_operand:V2SI 1 "register_operand" "y"))]
20467 (define_insn "*pushv4hi"
20468 [(set (match_operand:V4HI 0 "push_operand" "=<")
20469 (match_operand:V4HI 1 "register_operand" "y"))]
20473 (define_insn "*pushv8qi"
20474 [(set (match_operand:V8QI 0 "push_operand" "=<")
20475 (match_operand:V8QI 1 "register_operand" "y"))]
20479 (define_insn "*pushv2sf"
20480 [(set (match_operand:V2SF 0 "push_operand" "=<")
20481 (match_operand:V2SF 1 "register_operand" "y"))]
20486 [(set (match_operand 0 "push_operand" "")
20487 (match_operand 1 "register_operand" ""))]
20488 "!TARGET_64BIT && reload_completed
20489 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20490 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 3)))
20491 (set (match_dup 2) (match_dup 1))]
20492 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20493 stack_pointer_rtx);
20494 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20497 [(set (match_operand 0 "push_operand" "")
20498 (match_operand 1 "register_operand" ""))]
20499 "TARGET_64BIT && reload_completed
20500 && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
20501 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 3)))
20502 (set (match_dup 2) (match_dup 1))]
20503 "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
20504 stack_pointer_rtx);
20505 operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
20508 (define_insn "movti_internal"
20509 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
20510 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
20511 "TARGET_SSE && !TARGET_64BIT
20512 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20514 switch (which_alternative)
20517 if (get_attr_mode (insn) == MODE_V4SF)
20518 return "xorps\t%0, %0";
20520 return "pxor\t%0, %0";
20523 if (get_attr_mode (insn) == MODE_V4SF)
20524 return "movaps\t{%1, %0|%0, %1}";
20526 return "movdqa\t{%1, %0|%0, %1}";
20531 [(set_attr "type" "ssemov,ssemov,ssemov")
20533 (cond [(eq_attr "alternative" "0,1")
20535 (ne (symbol_ref "optimize_size")
20537 (const_string "V4SF")
20538 (const_string "TI"))
20539 (eq_attr "alternative" "2")
20541 (ne (symbol_ref "optimize_size")
20543 (const_string "V4SF")
20544 (const_string "TI"))]
20545 (const_string "TI")))])
20547 (define_insn "*movti_rex64"
20548 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
20549 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
20551 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20553 switch (which_alternative)
20559 if (get_attr_mode (insn) == MODE_V4SF)
20560 return "xorps\t%0, %0";
20562 return "pxor\t%0, %0";
20565 if (get_attr_mode (insn) == MODE_V4SF)
20566 return "movaps\t{%1, %0|%0, %1}";
20568 return "movdqa\t{%1, %0|%0, %1}";
20573 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20575 (cond [(eq_attr "alternative" "2,3")
20577 (ne (symbol_ref "optimize_size")
20579 (const_string "V4SF")
20580 (const_string "TI"))
20581 (eq_attr "alternative" "4")
20583 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20585 (ne (symbol_ref "optimize_size")
20587 (const_string "V4SF")
20588 (const_string "TI"))]
20589 (const_string "DI")))])
20591 (define_insn "*movtf_rex64"
20592 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
20593 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
20595 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20597 switch (which_alternative)
20603 if (get_attr_mode (insn) == MODE_V4SF)
20604 return "xorps\t%0, %0";
20606 return "pxor\t%0, %0";
20609 if (get_attr_mode (insn) == MODE_V4SF)
20610 return "movaps\t{%1, %0|%0, %1}";
20612 return "movdqa\t{%1, %0|%0, %1}";
20617 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
20619 (cond [(eq_attr "alternative" "2,3")
20621 (ne (symbol_ref "optimize_size")
20623 (const_string "V4SF")
20624 (const_string "TI"))
20625 (eq_attr "alternative" "4")
20627 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
20629 (ne (symbol_ref "optimize_size")
20631 (const_string "V4SF")
20632 (const_string "TI"))]
20633 (const_string "DI")))])
20636 [(set (match_operand:TI 0 "nonimmediate_operand" "")
20637 (match_operand:TI 1 "general_operand" ""))]
20638 "reload_completed && !SSE_REG_P (operands[0])
20639 && !SSE_REG_P (operands[1])"
20641 "ix86_split_long_move (operands); DONE;")
20644 [(set (match_operand:TF 0 "nonimmediate_operand" "")
20645 (match_operand:TF 1 "general_operand" ""))]
20646 "reload_completed && !SSE_REG_P (operands[0])
20647 && !SSE_REG_P (operands[1])"
20649 "ix86_split_long_move (operands); DONE;")
20651 ;; These two patterns are useful for specifying exactly whether to use
20652 ;; movaps or movups
20653 (define_expand "sse_movaps"
20654 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20655 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20659 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20661 rtx tmp = gen_reg_rtx (V4SFmode);
20662 emit_insn (gen_sse_movaps (tmp, operands[1]));
20663 emit_move_insn (operands[0], tmp);
20668 (define_insn "*sse_movaps_1"
20669 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20670 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20673 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20674 "movaps\t{%1, %0|%0, %1}"
20675 [(set_attr "type" "ssemov,ssemov")
20676 (set_attr "mode" "V4SF")])
20678 (define_expand "sse_movups"
20679 [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
20680 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
20684 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
20686 rtx tmp = gen_reg_rtx (V4SFmode);
20687 emit_insn (gen_sse_movups (tmp, operands[1]));
20688 emit_move_insn (operands[0], tmp);
20693 (define_insn "*sse_movups_1"
20694 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20695 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
20698 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
20699 "movups\t{%1, %0|%0, %1}"
20700 [(set_attr "type" "ssecvt,ssecvt")
20701 (set_attr "mode" "V4SF")])
20703 ;; SSE Strange Moves.
20705 (define_insn "sse_movmskps"
20706 [(set (match_operand:SI 0 "register_operand" "=r")
20707 (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
20710 "movmskps\t{%1, %0|%0, %1}"
20711 [(set_attr "type" "ssecvt")
20712 (set_attr "mode" "V4SF")])
20714 (define_insn "mmx_pmovmskb"
20715 [(set (match_operand:SI 0 "register_operand" "=r")
20716 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
20718 "TARGET_SSE || TARGET_3DNOW_A"
20719 "pmovmskb\t{%1, %0|%0, %1}"
20720 [(set_attr "type" "ssecvt")
20721 (set_attr "mode" "V4SF")])
20724 (define_insn "mmx_maskmovq"
20725 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
20726 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20727 (match_operand:V8QI 2 "register_operand" "y")]
20729 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
20730 ;; @@@ check ordering of operands in intel/nonintel syntax
20731 "maskmovq\t{%2, %1|%1, %2}"
20732 [(set_attr "type" "mmxcvt")
20733 (set_attr "mode" "DI")])
20735 (define_insn "mmx_maskmovq_rex"
20736 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
20737 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
20738 (match_operand:V8QI 2 "register_operand" "y")]
20740 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
20741 ;; @@@ check ordering of operands in intel/nonintel syntax
20742 "maskmovq\t{%2, %1|%1, %2}"
20743 [(set_attr "type" "mmxcvt")
20744 (set_attr "mode" "DI")])
20746 (define_insn "sse_movntv4sf"
20747 [(set (match_operand:V4SF 0 "memory_operand" "=m")
20748 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
20751 "movntps\t{%1, %0|%0, %1}"
20752 [(set_attr "type" "ssemov")
20753 (set_attr "mode" "V4SF")])
20755 (define_insn "sse_movntdi"
20756 [(set (match_operand:DI 0 "memory_operand" "=m")
20757 (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
20759 "TARGET_SSE || TARGET_3DNOW_A"
20760 "movntq\t{%1, %0|%0, %1}"
20761 [(set_attr "type" "mmxmov")
20762 (set_attr "mode" "DI")])
20764 (define_insn "sse_movhlps"
20765 [(set (match_operand:V4SF 0 "register_operand" "=x")
20767 (match_operand:V4SF 1 "register_operand" "0")
20768 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20769 (parallel [(const_int 2)
20775 "movhlps\t{%2, %0|%0, %2}"
20776 [(set_attr "type" "ssecvt")
20777 (set_attr "mode" "V4SF")])
20779 (define_insn "sse_movlhps"
20780 [(set (match_operand:V4SF 0 "register_operand" "=x")
20782 (match_operand:V4SF 1 "register_operand" "0")
20783 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20784 (parallel [(const_int 2)
20790 "movlhps\t{%2, %0|%0, %2}"
20791 [(set_attr "type" "ssecvt")
20792 (set_attr "mode" "V4SF")])
20794 (define_insn "sse_movhps"
20795 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20797 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20798 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20801 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20802 "movhps\t{%2, %0|%0, %2}"
20803 [(set_attr "type" "ssecvt")
20804 (set_attr "mode" "V4SF")])
20806 (define_insn "sse_movlps"
20807 [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
20809 (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
20810 (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
20813 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
20814 "movlps\t{%2, %0|%0, %2}"
20815 [(set_attr "type" "ssecvt")
20816 (set_attr "mode" "V4SF")])
20818 (define_expand "sse_loadss"
20819 [(match_operand:V4SF 0 "register_operand" "")
20820 (match_operand:SF 1 "memory_operand" "")]
20823 emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
20824 CONST0_RTX (V4SFmode)));
20828 (define_insn "sse_loadss_1"
20829 [(set (match_operand:V4SF 0 "register_operand" "=x")
20831 (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
20832 (match_operand:V4SF 2 "const0_operand" "X")
20835 "movss\t{%1, %0|%0, %1}"
20836 [(set_attr "type" "ssemov")
20837 (set_attr "mode" "SF")])
20839 (define_insn "sse_movss"
20840 [(set (match_operand:V4SF 0 "register_operand" "=x")
20842 (match_operand:V4SF 1 "register_operand" "0")
20843 (match_operand:V4SF 2 "register_operand" "x")
20846 "movss\t{%2, %0|%0, %2}"
20847 [(set_attr "type" "ssemov")
20848 (set_attr "mode" "SF")])
20850 (define_insn "sse_storess"
20851 [(set (match_operand:SF 0 "memory_operand" "=m")
20853 (match_operand:V4SF 1 "register_operand" "x")
20854 (parallel [(const_int 0)])))]
20856 "movss\t{%1, %0|%0, %1}"
20857 [(set_attr "type" "ssemov")
20858 (set_attr "mode" "SF")])
20860 (define_insn "sse_shufps"
20861 [(set (match_operand:V4SF 0 "register_operand" "=x")
20862 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
20863 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
20864 (match_operand:SI 3 "immediate_operand" "i")]
20867 ;; @@@ check operand order for intel/nonintel syntax
20868 "shufps\t{%3, %2, %0|%0, %2, %3}"
20869 [(set_attr "type" "ssecvt")
20870 (set_attr "mode" "V4SF")])
20875 (define_insn "addv4sf3"
20876 [(set (match_operand:V4SF 0 "register_operand" "=x")
20877 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20878 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20880 "addps\t{%2, %0|%0, %2}"
20881 [(set_attr "type" "sseadd")
20882 (set_attr "mode" "V4SF")])
20884 (define_insn "vmaddv4sf3"
20885 [(set (match_operand:V4SF 0 "register_operand" "=x")
20887 (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20888 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20892 "addss\t{%2, %0|%0, %2}"
20893 [(set_attr "type" "sseadd")
20894 (set_attr "mode" "SF")])
20896 (define_insn "subv4sf3"
20897 [(set (match_operand:V4SF 0 "register_operand" "=x")
20898 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20899 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20901 "subps\t{%2, %0|%0, %2}"
20902 [(set_attr "type" "sseadd")
20903 (set_attr "mode" "V4SF")])
20905 (define_insn "vmsubv4sf3"
20906 [(set (match_operand:V4SF 0 "register_operand" "=x")
20908 (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
20909 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20913 "subss\t{%2, %0|%0, %2}"
20914 [(set_attr "type" "sseadd")
20915 (set_attr "mode" "SF")])
20917 ;; ??? Should probably be done by generic code instead.
20918 (define_expand "negv4sf2"
20919 [(set (match_operand:V4SF 0 "register_operand" "")
20920 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "")
20924 rtx m0 = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
20925 rtx vm0 = gen_rtx_CONST_VECTOR (V4SFmode, gen_rtvec (4, m0, m0, m0, m0));
20926 operands[2] = force_reg (V4SFmode, vm0);
20929 (define_insn "mulv4sf3"
20930 [(set (match_operand:V4SF 0 "register_operand" "=x")
20931 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20932 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20934 "mulps\t{%2, %0|%0, %2}"
20935 [(set_attr "type" "ssemul")
20936 (set_attr "mode" "V4SF")])
20938 (define_insn "vmmulv4sf3"
20939 [(set (match_operand:V4SF 0 "register_operand" "=x")
20941 (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
20942 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20946 "mulss\t{%2, %0|%0, %2}"
20947 [(set_attr "type" "ssemul")
20948 (set_attr "mode" "SF")])
20950 (define_insn "divv4sf3"
20951 [(set (match_operand:V4SF 0 "register_operand" "=x")
20952 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20953 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20955 "divps\t{%2, %0|%0, %2}"
20956 [(set_attr "type" "ssediv")
20957 (set_attr "mode" "V4SF")])
20959 (define_insn "vmdivv4sf3"
20960 [(set (match_operand:V4SF 0 "register_operand" "=x")
20962 (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
20963 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20967 "divss\t{%2, %0|%0, %2}"
20968 [(set_attr "type" "ssediv")
20969 (set_attr "mode" "SF")])
20972 ;; SSE square root/reciprocal
20974 (define_insn "rcpv4sf2"
20975 [(set (match_operand:V4SF 0 "register_operand" "=x")
20977 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
20979 "rcpps\t{%1, %0|%0, %1}"
20980 [(set_attr "type" "sse")
20981 (set_attr "mode" "V4SF")])
20983 (define_insn "vmrcpv4sf2"
20984 [(set (match_operand:V4SF 0 "register_operand" "=x")
20986 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20988 (match_operand:V4SF 2 "register_operand" "0")
20991 "rcpss\t{%1, %0|%0, %1}"
20992 [(set_attr "type" "sse")
20993 (set_attr "mode" "SF")])
20995 (define_insn "rsqrtv4sf2"
20996 [(set (match_operand:V4SF 0 "register_operand" "=x")
20998 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
21000 "rsqrtps\t{%1, %0|%0, %1}"
21001 [(set_attr "type" "sse")
21002 (set_attr "mode" "V4SF")])
21004 (define_insn "vmrsqrtv4sf2"
21005 [(set (match_operand:V4SF 0 "register_operand" "=x")
21007 (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21009 (match_operand:V4SF 2 "register_operand" "0")
21012 "rsqrtss\t{%1, %0|%0, %1}"
21013 [(set_attr "type" "sse")
21014 (set_attr "mode" "SF")])
21016 (define_insn "sqrtv4sf2"
21017 [(set (match_operand:V4SF 0 "register_operand" "=x")
21018 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
21020 "sqrtps\t{%1, %0|%0, %1}"
21021 [(set_attr "type" "sse")
21022 (set_attr "mode" "V4SF")])
21024 (define_insn "vmsqrtv4sf2"
21025 [(set (match_operand:V4SF 0 "register_operand" "=x")
21027 (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21028 (match_operand:V4SF 2 "register_operand" "0")
21031 "sqrtss\t{%1, %0|%0, %1}"
21032 [(set_attr "type" "sse")
21033 (set_attr "mode" "SF")])
21035 ;; SSE logical operations.
21037 ;; SSE defines logical operations on floating point values. This brings
21038 ;; interesting challenge to RTL representation where logicals are only valid
21039 ;; on integral types. We deal with this by representing the floating point
21040 ;; logical as logical on arguments casted to TImode as this is what hardware
21041 ;; really does. Unfortunately hardware requires the type information to be
21042 ;; present and thus we must avoid subregs from being simplified and eliminated
21043 ;; in later compilation phases.
21045 ;; We have following variants from each instruction:
21046 ;; sse_andsf3 - the operation taking V4SF vector operands
21047 ;; and doing TImode cast on them
21048 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
21049 ;; TImode, since backend insist on eliminating casts
21050 ;; on memory operands
21051 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
21052 ;; We cannot accept memory operand here as instruction reads
21053 ;; whole scalar. This is generated only post reload by GCC
21054 ;; scalar float operations that expands to logicals (fabs)
21055 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
21056 ;; memory operand. Eventually combine can be able
21057 ;; to synthesize these using splitter.
21058 ;; sse2_anddf3, *sse2_anddf3_memory
21061 ;; These are not called andti3 etc. because we really really don't want
21062 ;; the compiler to widen DImode ands to TImode ands and then try to move
21063 ;; into DImode subregs of SSE registers, and them together, and move out
21064 ;; of DImode subregs again!
21065 ;; SSE1 single precision floating point logical operation
21066 (define_expand "sse_andv4sf3"
21067 [(set (match_operand:V4SF 0 "register_operand" "")
21068 (and:V4SF (match_operand:V4SF 1 "register_operand" "")
21069 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21073 (define_insn "*sse_andv4sf3"
21074 [(set (match_operand:V4SF 0 "register_operand" "=x")
21075 (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21076 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21078 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21079 "andps\t{%2, %0|%0, %2}"
21080 [(set_attr "type" "sselog")
21081 (set_attr "mode" "V4SF")])
21083 (define_expand "sse_nandv4sf3"
21084 [(set (match_operand:V4SF 0 "register_operand" "")
21085 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
21086 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21090 (define_insn "*sse_nandv4sf3"
21091 [(set (match_operand:V4SF 0 "register_operand" "=x")
21092 (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
21093 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21095 "andnps\t{%2, %0|%0, %2}"
21096 [(set_attr "type" "sselog")
21097 (set_attr "mode" "V4SF")])
21099 (define_expand "sse_iorv4sf3"
21100 [(set (match_operand:V4SF 0 "register_operand" "")
21101 (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
21102 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21106 (define_insn "*sse_iorv4sf3"
21107 [(set (match_operand:V4SF 0 "register_operand" "=x")
21108 (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21109 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21111 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21112 "orps\t{%2, %0|%0, %2}"
21113 [(set_attr "type" "sselog")
21114 (set_attr "mode" "V4SF")])
21116 (define_expand "sse_xorv4sf3"
21117 [(set (match_operand:V4SF 0 "register_operand" "")
21118 (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
21119 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
21123 (define_insn "*sse_xorv4sf3"
21124 [(set (match_operand:V4SF 0 "register_operand" "=x")
21125 (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
21126 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21128 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21129 "xorps\t{%2, %0|%0, %2}"
21130 [(set_attr "type" "sselog")
21131 (set_attr "mode" "V4SF")])
21133 ;; SSE2 double precision floating point logical operation
21135 (define_expand "sse2_andv2df3"
21136 [(set (match_operand:V2DF 0 "register_operand" "")
21137 (and:V2DF (match_operand:V2DF 1 "register_operand" "")
21138 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21142 (define_insn "*sse2_andv2df3"
21143 [(set (match_operand:V2DF 0 "register_operand" "=x")
21144 (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21145 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21147 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21148 "andpd\t{%2, %0|%0, %2}"
21149 [(set_attr "type" "sselog")
21150 (set_attr "mode" "V2DF")])
21152 (define_expand "sse2_nandv2df3"
21153 [(set (match_operand:V2DF 0 "register_operand" "")
21154 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
21155 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21159 (define_insn "*sse2_nandv2df3"
21160 [(set (match_operand:V2DF 0 "register_operand" "=x")
21161 (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
21162 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21164 "andnpd\t{%2, %0|%0, %2}"
21165 [(set_attr "type" "sselog")
21166 (set_attr "mode" "V2DF")])
21168 (define_expand "sse2_iorv2df3"
21169 [(set (match_operand:V2DF 0 "register_operand" "")
21170 (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
21171 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21175 (define_insn "*sse2_iorv2df3"
21176 [(set (match_operand:V2DF 0 "register_operand" "=x")
21177 (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21178 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21180 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21181 "orpd\t{%2, %0|%0, %2}"
21182 [(set_attr "type" "sselog")
21183 (set_attr "mode" "V2DF")])
21185 (define_expand "sse2_xorv2df3"
21186 [(set (match_operand:V2DF 0 "register_operand" "")
21187 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
21188 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
21192 (define_insn "*sse2_xorv2df3"
21193 [(set (match_operand:V2DF 0 "register_operand" "=x")
21194 (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
21195 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21197 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21198 "xorpd\t{%2, %0|%0, %2}"
21199 [(set_attr "type" "sselog")
21200 (set_attr "mode" "V2DF")])
21202 ;; SSE2 integral logicals. These patterns must always come after floating
21203 ;; point ones since we don't want compiler to use integer opcodes on floating
21204 ;; point SSE values to avoid matching of subregs in the match_operand.
21205 (define_insn "*sse2_andti3"
21206 [(set (match_operand:TI 0 "register_operand" "=x")
21207 (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21208 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21210 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21211 "pand\t{%2, %0|%0, %2}"
21212 [(set_attr "type" "sselog")
21213 (set_attr "mode" "TI")])
21215 (define_insn "sse2_andv2di3"
21216 [(set (match_operand:V2DI 0 "register_operand" "=x")
21217 (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21218 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21220 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21221 "pand\t{%2, %0|%0, %2}"
21222 [(set_attr "type" "sselog")
21223 (set_attr "mode" "TI")])
21225 (define_insn "*sse2_nandti3"
21226 [(set (match_operand:TI 0 "register_operand" "=x")
21227 (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
21228 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21230 "pandn\t{%2, %0|%0, %2}"
21231 [(set_attr "type" "sselog")
21232 (set_attr "mode" "TI")])
21234 (define_insn "sse2_nandv2di3"
21235 [(set (match_operand:V2DI 0 "register_operand" "=x")
21236 (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
21237 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21239 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21240 "pandn\t{%2, %0|%0, %2}"
21241 [(set_attr "type" "sselog")
21242 (set_attr "mode" "TI")])
21244 (define_insn "*sse2_iorti3"
21245 [(set (match_operand:TI 0 "register_operand" "=x")
21246 (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21247 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21249 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21250 "por\t{%2, %0|%0, %2}"
21251 [(set_attr "type" "sselog")
21252 (set_attr "mode" "TI")])
21254 (define_insn "sse2_iorv2di3"
21255 [(set (match_operand:V2DI 0 "register_operand" "=x")
21256 (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21257 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21259 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21260 "por\t{%2, %0|%0, %2}"
21261 [(set_attr "type" "sselog")
21262 (set_attr "mode" "TI")])
21264 (define_insn "*sse2_xorti3"
21265 [(set (match_operand:TI 0 "register_operand" "=x")
21266 (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
21267 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
21269 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21270 "pxor\t{%2, %0|%0, %2}"
21271 [(set_attr "type" "sselog")
21272 (set_attr "mode" "TI")])
21274 (define_insn "sse2_xorv2di3"
21275 [(set (match_operand:V2DI 0 "register_operand" "=x")
21276 (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
21277 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
21279 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
21280 "pxor\t{%2, %0|%0, %2}"
21281 [(set_attr "type" "sselog")
21282 (set_attr "mode" "TI")])
21284 ;; Use xor, but don't show input operands so they aren't live before
21286 (define_insn "sse_clrv4sf"
21287 [(set (match_operand:V4SF 0 "register_operand" "=x")
21288 (match_operand:V4SF 1 "const0_operand" "X"))]
21291 if (get_attr_mode (insn) == MODE_TI)
21292 return "pxor\t{%0, %0|%0, %0}";
21294 return "xorps\t{%0, %0|%0, %0}";
21296 [(set_attr "type" "sselog")
21297 (set_attr "memory" "none")
21300 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
21302 (ne (symbol_ref "TARGET_SSE2")
21304 (eq (symbol_ref "optimize_size")
21306 (const_string "TI")
21307 (const_string "V4SF")))])
21309 ;; Use xor, but don't show input operands so they aren't live before
21311 (define_insn "sse_clrv2df"
21312 [(set (match_operand:V2DF 0 "register_operand" "=x")
21313 (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
21315 "xorpd\t{%0, %0|%0, %0}"
21316 [(set_attr "type" "sselog")
21317 (set_attr "memory" "none")
21318 (set_attr "mode" "V4SF")])
21320 ;; SSE mask-generating compares
21322 (define_insn "maskcmpv4sf3"
21323 [(set (match_operand:V4SI 0 "register_operand" "=x")
21324 (match_operator:V4SI 3 "sse_comparison_operator"
21325 [(match_operand:V4SF 1 "register_operand" "0")
21326 (match_operand:V4SF 2 "register_operand" "x")]))]
21328 "cmp%D3ps\t{%2, %0|%0, %2}"
21329 [(set_attr "type" "ssecmp")
21330 (set_attr "mode" "V4SF")])
21332 (define_insn "maskncmpv4sf3"
21333 [(set (match_operand:V4SI 0 "register_operand" "=x")
21335 (match_operator:V4SI 3 "sse_comparison_operator"
21336 [(match_operand:V4SF 1 "register_operand" "0")
21337 (match_operand:V4SF 2 "register_operand" "x")])))]
21340 if (GET_CODE (operands[3]) == UNORDERED)
21341 return "cmpordps\t{%2, %0|%0, %2}";
21343 return "cmpn%D3ps\t{%2, %0|%0, %2}";
21345 [(set_attr "type" "ssecmp")
21346 (set_attr "mode" "V4SF")])
21348 (define_insn "vmmaskcmpv4sf3"
21349 [(set (match_operand:V4SI 0 "register_operand" "=x")
21351 (match_operator:V4SI 3 "sse_comparison_operator"
21352 [(match_operand:V4SF 1 "register_operand" "0")
21353 (match_operand:V4SF 2 "register_operand" "x")])
21354 (subreg:V4SI (match_dup 1) 0)
21357 "cmp%D3ss\t{%2, %0|%0, %2}"
21358 [(set_attr "type" "ssecmp")
21359 (set_attr "mode" "SF")])
21361 (define_insn "vmmaskncmpv4sf3"
21362 [(set (match_operand:V4SI 0 "register_operand" "=x")
21365 (match_operator:V4SI 3 "sse_comparison_operator"
21366 [(match_operand:V4SF 1 "register_operand" "0")
21367 (match_operand:V4SF 2 "register_operand" "x")]))
21368 (subreg:V4SI (match_dup 1) 0)
21372 if (GET_CODE (operands[3]) == UNORDERED)
21373 return "cmpordss\t{%2, %0|%0, %2}";
21375 return "cmpn%D3ss\t{%2, %0|%0, %2}";
21377 [(set_attr "type" "ssecmp")
21378 (set_attr "mode" "SF")])
21380 (define_insn "sse_comi"
21381 [(set (reg:CCFP FLAGS_REG)
21382 (compare:CCFP (vec_select:SF
21383 (match_operand:V4SF 0 "register_operand" "x")
21384 (parallel [(const_int 0)]))
21386 (match_operand:V4SF 1 "register_operand" "x")
21387 (parallel [(const_int 0)]))))]
21389 "comiss\t{%1, %0|%0, %1}"
21390 [(set_attr "type" "ssecomi")
21391 (set_attr "mode" "SF")])
21393 (define_insn "sse_ucomi"
21394 [(set (reg:CCFPU FLAGS_REG)
21395 (compare:CCFPU (vec_select:SF
21396 (match_operand:V4SF 0 "register_operand" "x")
21397 (parallel [(const_int 0)]))
21399 (match_operand:V4SF 1 "register_operand" "x")
21400 (parallel [(const_int 0)]))))]
21402 "ucomiss\t{%1, %0|%0, %1}"
21403 [(set_attr "type" "ssecomi")
21404 (set_attr "mode" "SF")])
21409 (define_insn "sse_unpckhps"
21410 [(set (match_operand:V4SF 0 "register_operand" "=x")
21412 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21413 (parallel [(const_int 2)
21417 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21418 (parallel [(const_int 0)
21424 "unpckhps\t{%2, %0|%0, %2}"
21425 [(set_attr "type" "ssecvt")
21426 (set_attr "mode" "V4SF")])
21428 (define_insn "sse_unpcklps"
21429 [(set (match_operand:V4SF 0 "register_operand" "=x")
21431 (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
21432 (parallel [(const_int 0)
21436 (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
21437 (parallel [(const_int 2)
21443 "unpcklps\t{%2, %0|%0, %2}"
21444 [(set_attr "type" "ssecvt")
21445 (set_attr "mode" "V4SF")])
21450 (define_insn "smaxv4sf3"
21451 [(set (match_operand:V4SF 0 "register_operand" "=x")
21452 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21453 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21455 "maxps\t{%2, %0|%0, %2}"
21456 [(set_attr "type" "sse")
21457 (set_attr "mode" "V4SF")])
21459 (define_insn "vmsmaxv4sf3"
21460 [(set (match_operand:V4SF 0 "register_operand" "=x")
21462 (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
21463 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21467 "maxss\t{%2, %0|%0, %2}"
21468 [(set_attr "type" "sse")
21469 (set_attr "mode" "SF")])
21471 (define_insn "sminv4sf3"
21472 [(set (match_operand:V4SF 0 "register_operand" "=x")
21473 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21474 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
21476 "minps\t{%2, %0|%0, %2}"
21477 [(set_attr "type" "sse")
21478 (set_attr "mode" "V4SF")])
21480 (define_insn "vmsminv4sf3"
21481 [(set (match_operand:V4SF 0 "register_operand" "=x")
21483 (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
21484 (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
21488 "minss\t{%2, %0|%0, %2}"
21489 [(set_attr "type" "sse")
21490 (set_attr "mode" "SF")])
21492 ;; SSE <-> integer/MMX conversions
21494 (define_insn "cvtpi2ps"
21495 [(set (match_operand:V4SF 0 "register_operand" "=x")
21497 (match_operand:V4SF 1 "register_operand" "0")
21498 (vec_duplicate:V4SF
21499 (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
21502 "cvtpi2ps\t{%2, %0|%0, %2}"
21503 [(set_attr "type" "ssecvt")
21504 (set_attr "mode" "V4SF")])
21506 (define_insn "cvtps2pi"
21507 [(set (match_operand:V2SI 0 "register_operand" "=y")
21509 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
21510 (parallel [(const_int 0) (const_int 1)])))]
21512 "cvtps2pi\t{%1, %0|%0, %1}"
21513 [(set_attr "type" "ssecvt")
21514 (set_attr "mode" "V4SF")])
21516 (define_insn "cvttps2pi"
21517 [(set (match_operand:V2SI 0 "register_operand" "=y")
21519 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
21521 (parallel [(const_int 0) (const_int 1)])))]
21523 "cvttps2pi\t{%1, %0|%0, %1}"
21524 [(set_attr "type" "ssecvt")
21525 (set_attr "mode" "SF")])
21527 (define_insn "cvtsi2ss"
21528 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21530 (match_operand:V4SF 1 "register_operand" "0,0")
21531 (vec_duplicate:V4SF
21532 (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
21535 "cvtsi2ss\t{%2, %0|%0, %2}"
21536 [(set_attr "type" "sseicvt")
21537 (set_attr "athlon_decode" "vector,double")
21538 (set_attr "mode" "SF")])
21540 (define_insn "cvtsi2ssq"
21541 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
21543 (match_operand:V4SF 1 "register_operand" "0,0")
21544 (vec_duplicate:V4SF
21545 (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
21547 "TARGET_SSE && TARGET_64BIT"
21548 "cvtsi2ssq\t{%2, %0|%0, %2}"
21549 [(set_attr "type" "sseicvt")
21550 (set_attr "athlon_decode" "vector,double")
21551 (set_attr "mode" "SF")])
21553 (define_insn "cvtss2si"
21554 [(set (match_operand:SI 0 "register_operand" "=r,r")
21556 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21557 (parallel [(const_int 0)])))]
21559 "cvtss2si\t{%1, %0|%0, %1}"
21560 [(set_attr "type" "sseicvt")
21561 (set_attr "athlon_decode" "double,vector")
21562 (set_attr "mode" "SI")])
21564 (define_insn "cvtss2siq"
21565 [(set (match_operand:DI 0 "register_operand" "=r,r")
21567 (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
21568 (parallel [(const_int 0)])))]
21570 "cvtss2siq\t{%1, %0|%0, %1}"
21571 [(set_attr "type" "sseicvt")
21572 (set_attr "athlon_decode" "double,vector")
21573 (set_attr "mode" "DI")])
21575 (define_insn "cvttss2si"
21576 [(set (match_operand:SI 0 "register_operand" "=r,r")
21578 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21580 (parallel [(const_int 0)])))]
21582 "cvttss2si\t{%1, %0|%0, %1}"
21583 [(set_attr "type" "sseicvt")
21584 (set_attr "mode" "SF")
21585 (set_attr "athlon_decode" "double,vector")])
21587 (define_insn "cvttss2siq"
21588 [(set (match_operand:DI 0 "register_operand" "=r,r")
21590 (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
21592 (parallel [(const_int 0)])))]
21593 "TARGET_SSE && TARGET_64BIT"
21594 "cvttss2siq\t{%1, %0|%0, %1}"
21595 [(set_attr "type" "sseicvt")
21596 (set_attr "mode" "SF")
21597 (set_attr "athlon_decode" "double,vector")])
21604 (define_insn "addv8qi3"
21605 [(set (match_operand:V8QI 0 "register_operand" "=y")
21606 (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21607 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21609 "paddb\t{%2, %0|%0, %2}"
21610 [(set_attr "type" "mmxadd")
21611 (set_attr "mode" "DI")])
21613 (define_insn "addv4hi3"
21614 [(set (match_operand:V4HI 0 "register_operand" "=y")
21615 (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21616 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21618 "paddw\t{%2, %0|%0, %2}"
21619 [(set_attr "type" "mmxadd")
21620 (set_attr "mode" "DI")])
21622 (define_insn "addv2si3"
21623 [(set (match_operand:V2SI 0 "register_operand" "=y")
21624 (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
21625 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21627 "paddd\t{%2, %0|%0, %2}"
21628 [(set_attr "type" "mmxadd")
21629 (set_attr "mode" "DI")])
21631 (define_insn "mmx_adddi3"
21632 [(set (match_operand:DI 0 "register_operand" "=y")
21634 [(plus:DI (match_operand:DI 1 "register_operand" "%0")
21635 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21638 "paddq\t{%2, %0|%0, %2}"
21639 [(set_attr "type" "mmxadd")
21640 (set_attr "mode" "DI")])
21642 (define_insn "ssaddv8qi3"
21643 [(set (match_operand:V8QI 0 "register_operand" "=y")
21644 (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21645 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21647 "paddsb\t{%2, %0|%0, %2}"
21648 [(set_attr "type" "mmxadd")
21649 (set_attr "mode" "DI")])
21651 (define_insn "ssaddv4hi3"
21652 [(set (match_operand:V4HI 0 "register_operand" "=y")
21653 (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21654 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21656 "paddsw\t{%2, %0|%0, %2}"
21657 [(set_attr "type" "mmxadd")
21658 (set_attr "mode" "DI")])
21660 (define_insn "usaddv8qi3"
21661 [(set (match_operand:V8QI 0 "register_operand" "=y")
21662 (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
21663 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21665 "paddusb\t{%2, %0|%0, %2}"
21666 [(set_attr "type" "mmxadd")
21667 (set_attr "mode" "DI")])
21669 (define_insn "usaddv4hi3"
21670 [(set (match_operand:V4HI 0 "register_operand" "=y")
21671 (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
21672 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21674 "paddusw\t{%2, %0|%0, %2}"
21675 [(set_attr "type" "mmxadd")
21676 (set_attr "mode" "DI")])
21678 (define_insn "subv8qi3"
21679 [(set (match_operand:V8QI 0 "register_operand" "=y")
21680 (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21681 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21683 "psubb\t{%2, %0|%0, %2}"
21684 [(set_attr "type" "mmxadd")
21685 (set_attr "mode" "DI")])
21687 (define_insn "subv4hi3"
21688 [(set (match_operand:V4HI 0 "register_operand" "=y")
21689 (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21690 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21692 "psubw\t{%2, %0|%0, %2}"
21693 [(set_attr "type" "mmxadd")
21694 (set_attr "mode" "DI")])
21696 (define_insn "subv2si3"
21697 [(set (match_operand:V2SI 0 "register_operand" "=y")
21698 (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
21699 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21701 "psubd\t{%2, %0|%0, %2}"
21702 [(set_attr "type" "mmxadd")
21703 (set_attr "mode" "DI")])
21705 (define_insn "mmx_subdi3"
21706 [(set (match_operand:DI 0 "register_operand" "=y")
21708 [(minus:DI (match_operand:DI 1 "register_operand" "0")
21709 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21712 "psubq\t{%2, %0|%0, %2}"
21713 [(set_attr "type" "mmxadd")
21714 (set_attr "mode" "DI")])
21716 (define_insn "sssubv8qi3"
21717 [(set (match_operand:V8QI 0 "register_operand" "=y")
21718 (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21719 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21721 "psubsb\t{%2, %0|%0, %2}"
21722 [(set_attr "type" "mmxadd")
21723 (set_attr "mode" "DI")])
21725 (define_insn "sssubv4hi3"
21726 [(set (match_operand:V4HI 0 "register_operand" "=y")
21727 (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21728 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21730 "psubsw\t{%2, %0|%0, %2}"
21731 [(set_attr "type" "mmxadd")
21732 (set_attr "mode" "DI")])
21734 (define_insn "ussubv8qi3"
21735 [(set (match_operand:V8QI 0 "register_operand" "=y")
21736 (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
21737 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21739 "psubusb\t{%2, %0|%0, %2}"
21740 [(set_attr "type" "mmxadd")
21741 (set_attr "mode" "DI")])
21743 (define_insn "ussubv4hi3"
21744 [(set (match_operand:V4HI 0 "register_operand" "=y")
21745 (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
21746 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21748 "psubusw\t{%2, %0|%0, %2}"
21749 [(set_attr "type" "mmxadd")
21750 (set_attr "mode" "DI")])
21752 (define_insn "mulv4hi3"
21753 [(set (match_operand:V4HI 0 "register_operand" "=y")
21754 (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
21755 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21757 "pmullw\t{%2, %0|%0, %2}"
21758 [(set_attr "type" "mmxmul")
21759 (set_attr "mode" "DI")])
21761 (define_insn "smulv4hi3_highpart"
21762 [(set (match_operand:V4HI 0 "register_operand" "=y")
21765 (mult:V4SI (sign_extend:V4SI
21766 (match_operand:V4HI 1 "register_operand" "0"))
21768 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21771 "pmulhw\t{%2, %0|%0, %2}"
21772 [(set_attr "type" "mmxmul")
21773 (set_attr "mode" "DI")])
21775 (define_insn "umulv4hi3_highpart"
21776 [(set (match_operand:V4HI 0 "register_operand" "=y")
21779 (mult:V4SI (zero_extend:V4SI
21780 (match_operand:V4HI 1 "register_operand" "0"))
21782 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21784 "TARGET_SSE || TARGET_3DNOW_A"
21785 "pmulhuw\t{%2, %0|%0, %2}"
21786 [(set_attr "type" "mmxmul")
21787 (set_attr "mode" "DI")])
21789 (define_insn "mmx_pmaddwd"
21790 [(set (match_operand:V2SI 0 "register_operand" "=y")
21794 (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
21795 (parallel [(const_int 0) (const_int 2)])))
21797 (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
21798 (parallel [(const_int 0) (const_int 2)]))))
21800 (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
21801 (parallel [(const_int 1)
21803 (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
21804 (parallel [(const_int 1)
21805 (const_int 3)]))))))]
21807 "pmaddwd\t{%2, %0|%0, %2}"
21808 [(set_attr "type" "mmxmul")
21809 (set_attr "mode" "DI")])
21812 ;; MMX logical operations
21813 ;; Note we don't want to declare these as regular iordi3 insns to prevent
21814 ;; normal code that also wants to use the FPU from getting broken.
21815 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
21816 (define_insn "mmx_iordi3"
21817 [(set (match_operand:DI 0 "register_operand" "=y")
21819 [(ior:DI (match_operand:DI 1 "register_operand" "%0")
21820 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21823 "por\t{%2, %0|%0, %2}"
21824 [(set_attr "type" "mmxadd")
21825 (set_attr "mode" "DI")])
21827 (define_insn "mmx_xordi3"
21828 [(set (match_operand:DI 0 "register_operand" "=y")
21830 [(xor:DI (match_operand:DI 1 "register_operand" "%0")
21831 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21834 "pxor\t{%2, %0|%0, %2}"
21835 [(set_attr "type" "mmxadd")
21836 (set_attr "mode" "DI")
21837 (set_attr "memory" "none")])
21839 ;; Same as pxor, but don't show input operands so that we don't think
21841 (define_insn "mmx_clrdi"
21842 [(set (match_operand:DI 0 "register_operand" "=y")
21843 (unspec:DI [(const_int 0)] UNSPEC_NOP))]
21845 "pxor\t{%0, %0|%0, %0}"
21846 [(set_attr "type" "mmxadd")
21847 (set_attr "mode" "DI")
21848 (set_attr "memory" "none")])
21850 (define_insn "mmx_anddi3"
21851 [(set (match_operand:DI 0 "register_operand" "=y")
21853 [(and:DI (match_operand:DI 1 "register_operand" "%0")
21854 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21857 "pand\t{%2, %0|%0, %2}"
21858 [(set_attr "type" "mmxadd")
21859 (set_attr "mode" "DI")])
21861 (define_insn "mmx_nanddi3"
21862 [(set (match_operand:DI 0 "register_operand" "=y")
21864 [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
21865 (match_operand:DI 2 "nonimmediate_operand" "ym"))]
21868 "pandn\t{%2, %0|%0, %2}"
21869 [(set_attr "type" "mmxadd")
21870 (set_attr "mode" "DI")])
21873 ;; MMX unsigned averages/sum of absolute differences
21875 (define_insn "mmx_uavgv8qi3"
21876 [(set (match_operand:V8QI 0 "register_operand" "=y")
21878 (plus:V8QI (plus:V8QI
21879 (match_operand:V8QI 1 "register_operand" "0")
21880 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
21881 (const_vector:V8QI [(const_int 1)
21890 "TARGET_SSE || TARGET_3DNOW_A"
21891 "pavgb\t{%2, %0|%0, %2}"
21892 [(set_attr "type" "mmxshft")
21893 (set_attr "mode" "DI")])
21895 (define_insn "mmx_uavgv4hi3"
21896 [(set (match_operand:V4HI 0 "register_operand" "=y")
21898 (plus:V4HI (plus:V4HI
21899 (match_operand:V4HI 1 "register_operand" "0")
21900 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
21901 (const_vector:V4HI [(const_int 1)
21906 "TARGET_SSE || TARGET_3DNOW_A"
21907 "pavgw\t{%2, %0|%0, %2}"
21908 [(set_attr "type" "mmxshft")
21909 (set_attr "mode" "DI")])
21911 (define_insn "mmx_psadbw"
21912 [(set (match_operand:DI 0 "register_operand" "=y")
21913 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
21914 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21916 "TARGET_SSE || TARGET_3DNOW_A"
21917 "psadbw\t{%2, %0|%0, %2}"
21918 [(set_attr "type" "mmxshft")
21919 (set_attr "mode" "DI")])
21922 ;; MMX insert/extract/shuffle
21924 (define_insn "mmx_pinsrw"
21925 [(set (match_operand:V4HI 0 "register_operand" "=y")
21926 (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
21927 (vec_duplicate:V4HI
21928 (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
21929 (match_operand:SI 3 "const_0_to_15_operand" "N")))]
21930 "TARGET_SSE || TARGET_3DNOW_A"
21931 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
21932 [(set_attr "type" "mmxcvt")
21933 (set_attr "mode" "DI")])
21935 (define_insn "mmx_pextrw"
21936 [(set (match_operand:SI 0 "register_operand" "=r")
21937 (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
21939 [(match_operand:SI 2 "const_0_to_3_operand" "N")]))))]
21940 "TARGET_SSE || TARGET_3DNOW_A"
21941 "pextrw\t{%2, %1, %0|%0, %1, %2}"
21942 [(set_attr "type" "mmxcvt")
21943 (set_attr "mode" "DI")])
21945 (define_insn "mmx_pshufw"
21946 [(set (match_operand:V4HI 0 "register_operand" "=y")
21947 (unspec:V4HI [(match_operand:V4HI 1 "nonimmediate_operand" "ym")
21948 (match_operand:SI 2 "immediate_operand" "i")]
21950 "TARGET_SSE || TARGET_3DNOW_A"
21951 "pshufw\t{%2, %1, %0|%0, %1, %2}"
21952 [(set_attr "type" "mmxcvt")
21953 (set_attr "mode" "DI")])
21956 ;; MMX mask-generating comparisons
21958 (define_insn "eqv8qi3"
21959 [(set (match_operand:V8QI 0 "register_operand" "=y")
21960 (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
21961 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21963 "pcmpeqb\t{%2, %0|%0, %2}"
21964 [(set_attr "type" "mmxcmp")
21965 (set_attr "mode" "DI")])
21967 (define_insn "eqv4hi3"
21968 [(set (match_operand:V4HI 0 "register_operand" "=y")
21969 (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
21970 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21972 "pcmpeqw\t{%2, %0|%0, %2}"
21973 [(set_attr "type" "mmxcmp")
21974 (set_attr "mode" "DI")])
21976 (define_insn "eqv2si3"
21977 [(set (match_operand:V2SI 0 "register_operand" "=y")
21978 (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
21979 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
21981 "pcmpeqd\t{%2, %0|%0, %2}"
21982 [(set_attr "type" "mmxcmp")
21983 (set_attr "mode" "DI")])
21985 (define_insn "gtv8qi3"
21986 [(set (match_operand:V8QI 0 "register_operand" "=y")
21987 (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
21988 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
21990 "pcmpgtb\t{%2, %0|%0, %2}"
21991 [(set_attr "type" "mmxcmp")
21992 (set_attr "mode" "DI")])
21994 (define_insn "gtv4hi3"
21995 [(set (match_operand:V4HI 0 "register_operand" "=y")
21996 (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21997 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
21999 "pcmpgtw\t{%2, %0|%0, %2}"
22000 [(set_attr "type" "mmxcmp")
22001 (set_attr "mode" "DI")])
22003 (define_insn "gtv2si3"
22004 [(set (match_operand:V2SI 0 "register_operand" "=y")
22005 (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22006 (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
22008 "pcmpgtd\t{%2, %0|%0, %2}"
22009 [(set_attr "type" "mmxcmp")
22010 (set_attr "mode" "DI")])
22013 ;; MMX max/min insns
22015 (define_insn "umaxv8qi3"
22016 [(set (match_operand:V8QI 0 "register_operand" "=y")
22017 (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
22018 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22019 "TARGET_SSE || TARGET_3DNOW_A"
22020 "pmaxub\t{%2, %0|%0, %2}"
22021 [(set_attr "type" "mmxadd")
22022 (set_attr "mode" "DI")])
22024 (define_insn "smaxv4hi3"
22025 [(set (match_operand:V4HI 0 "register_operand" "=y")
22026 (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
22027 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22028 "TARGET_SSE || TARGET_3DNOW_A"
22029 "pmaxsw\t{%2, %0|%0, %2}"
22030 [(set_attr "type" "mmxadd")
22031 (set_attr "mode" "DI")])
22033 (define_insn "uminv8qi3"
22034 [(set (match_operand:V8QI 0 "register_operand" "=y")
22035 (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
22036 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
22037 "TARGET_SSE || TARGET_3DNOW_A"
22038 "pminub\t{%2, %0|%0, %2}"
22039 [(set_attr "type" "mmxadd")
22040 (set_attr "mode" "DI")])
22042 (define_insn "sminv4hi3"
22043 [(set (match_operand:V4HI 0 "register_operand" "=y")
22044 (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
22045 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
22046 "TARGET_SSE || TARGET_3DNOW_A"
22047 "pminsw\t{%2, %0|%0, %2}"
22048 [(set_attr "type" "mmxadd")
22049 (set_attr "mode" "DI")])
22054 (define_insn "ashrv4hi3"
22055 [(set (match_operand:V4HI 0 "register_operand" "=y")
22056 (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22057 (match_operand:DI 2 "nonmemory_operand" "yi")))]
22059 "psraw\t{%2, %0|%0, %2}"
22060 [(set_attr "type" "mmxshft")
22061 (set_attr "mode" "DI")])
22063 (define_insn "ashrv2si3"
22064 [(set (match_operand:V2SI 0 "register_operand" "=y")
22065 (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22066 (match_operand:DI 2 "nonmemory_operand" "yi")))]
22068 "psrad\t{%2, %0|%0, %2}"
22069 [(set_attr "type" "mmxshft")
22070 (set_attr "mode" "DI")])
22072 (define_insn "lshrv4hi3"
22073 [(set (match_operand:V4HI 0 "register_operand" "=y")
22074 (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
22075 (match_operand:DI 2 "nonmemory_operand" "yi")))]
22077 "psrlw\t{%2, %0|%0, %2}"
22078 [(set_attr "type" "mmxshft")
22079 (set_attr "mode" "DI")])
22081 (define_insn "lshrv2si3"
22082 [(set (match_operand:V2SI 0 "register_operand" "=y")
22083 (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
22084 (match_operand:DI 2 "nonmemory_operand" "yi")))]
22086 "psrld\t{%2, %0|%0, %2}"
22087 [(set_attr "type" "mmxshft")
22088 (set_attr "mode" "DI")])
22090 ;; See logical MMX insns.
22091 (define_insn "mmx_lshrdi3"
22092 [(set (match_operand:DI 0 "register_operand" "=y")
22094 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
22095 (match_operand:DI 2 "nonmemory_operand" "yi"))]
22098 "psrlq\t{%2, %0|%0, %2}"
22099 [(set_attr "type" "mmxshft")
22100 (set_attr "mode" "DI")])
22102 (define_insn "ashlv4hi3"
22103 [(set (match_operand:V4HI 0 "register_operand" "=y")
22104 (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
22105 (match_operand:DI 2 "nonmemory_operand" "yi")))]
22107 "psllw\t{%2, %0|%0, %2}"
22108 [(set_attr "type" "mmxshft")
22109 (set_attr "mode" "DI")])
22111 (define_insn "ashlv2si3"
22112 [(set (match_operand:V2SI 0 "register_operand" "=y")
22113 (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
22114 (match_operand:DI 2 "nonmemory_operand" "yi")))]
22116 "pslld\t{%2, %0|%0, %2}"
22117 [(set_attr "type" "mmxshft")
22118 (set_attr "mode" "DI")])
22120 ;; See logical MMX insns.
22121 (define_insn "mmx_ashldi3"
22122 [(set (match_operand:DI 0 "register_operand" "=y")
22124 [(ashift:DI (match_operand:DI 1 "register_operand" "0")
22125 (match_operand:DI 2 "nonmemory_operand" "yi"))]
22128 "psllq\t{%2, %0|%0, %2}"
22129 [(set_attr "type" "mmxshft")
22130 (set_attr "mode" "DI")])
22133 ;; MMX pack/unpack insns.
22135 (define_insn "mmx_packsswb"
22136 [(set (match_operand:V8QI 0 "register_operand" "=y")
22138 (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22139 (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22141 "packsswb\t{%2, %0|%0, %2}"
22142 [(set_attr "type" "mmxshft")
22143 (set_attr "mode" "DI")])
22145 (define_insn "mmx_packssdw"
22146 [(set (match_operand:V4HI 0 "register_operand" "=y")
22148 (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
22149 (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
22151 "packssdw\t{%2, %0|%0, %2}"
22152 [(set_attr "type" "mmxshft")
22153 (set_attr "mode" "DI")])
22155 (define_insn "mmx_packuswb"
22156 [(set (match_operand:V8QI 0 "register_operand" "=y")
22158 (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
22159 (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
22161 "packuswb\t{%2, %0|%0, %2}"
22162 [(set_attr "type" "mmxshft")
22163 (set_attr "mode" "DI")])
22165 (define_insn "mmx_punpckhbw"
22166 [(set (match_operand:V8QI 0 "register_operand" "=y")
22168 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22169 (parallel [(const_int 4)
22177 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22178 (parallel [(const_int 0)
22188 "punpckhbw\t{%2, %0|%0, %2}"
22189 [(set_attr "type" "mmxcvt")
22190 (set_attr "mode" "DI")])
22192 (define_insn "mmx_punpckhwd"
22193 [(set (match_operand:V4HI 0 "register_operand" "=y")
22195 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22196 (parallel [(const_int 0)
22200 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22201 (parallel [(const_int 2)
22207 "punpckhwd\t{%2, %0|%0, %2}"
22208 [(set_attr "type" "mmxcvt")
22209 (set_attr "mode" "DI")])
22211 (define_insn "mmx_punpckhdq"
22212 [(set (match_operand:V2SI 0 "register_operand" "=y")
22214 (match_operand:V2SI 1 "register_operand" "0")
22215 (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
22216 (parallel [(const_int 1)
22220 "punpckhdq\t{%2, %0|%0, %2}"
22221 [(set_attr "type" "mmxcvt")
22222 (set_attr "mode" "DI")])
22224 (define_insn "mmx_punpcklbw"
22225 [(set (match_operand:V8QI 0 "register_operand" "=y")
22227 (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
22228 (parallel [(const_int 0)
22236 (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
22237 (parallel [(const_int 4)
22247 "punpcklbw\t{%2, %0|%0, %2}"
22248 [(set_attr "type" "mmxcvt")
22249 (set_attr "mode" "DI")])
22251 (define_insn "mmx_punpcklwd"
22252 [(set (match_operand:V4HI 0 "register_operand" "=y")
22254 (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
22255 (parallel [(const_int 2)
22259 (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
22260 (parallel [(const_int 0)
22266 "punpcklwd\t{%2, %0|%0, %2}"
22267 [(set_attr "type" "mmxcvt")
22268 (set_attr "mode" "DI")])
22270 (define_insn "mmx_punpckldq"
22271 [(set (match_operand:V2SI 0 "register_operand" "=y")
22273 (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
22274 (parallel [(const_int 1)
22276 (match_operand:V2SI 2 "register_operand" "y")
22279 "punpckldq\t{%2, %0|%0, %2}"
22280 [(set_attr "type" "mmxcvt")
22281 (set_attr "mode" "DI")])
22284 ;; Miscellaneous stuff
22286 (define_insn "emms"
22287 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
22288 (clobber (reg:XF 8))
22289 (clobber (reg:XF 9))
22290 (clobber (reg:XF 10))
22291 (clobber (reg:XF 11))
22292 (clobber (reg:XF 12))
22293 (clobber (reg:XF 13))
22294 (clobber (reg:XF 14))
22295 (clobber (reg:XF 15))
22296 (clobber (reg:DI 29))
22297 (clobber (reg:DI 30))
22298 (clobber (reg:DI 31))
22299 (clobber (reg:DI 32))
22300 (clobber (reg:DI 33))
22301 (clobber (reg:DI 34))
22302 (clobber (reg:DI 35))
22303 (clobber (reg:DI 36))]
22306 [(set_attr "type" "mmx")
22307 (set_attr "memory" "unknown")])
22309 (define_insn "ldmxcsr"
22310 [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
22314 [(set_attr "type" "sse")
22315 (set_attr "memory" "load")])
22317 (define_insn "stmxcsr"
22318 [(set (match_operand:SI 0 "memory_operand" "=m")
22319 (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
22322 [(set_attr "type" "sse")
22323 (set_attr "memory" "store")])
22325 (define_expand "sfence"
22326 [(set (match_dup 0)
22327 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22328 "TARGET_SSE || TARGET_3DNOW_A"
22330 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
22331 MEM_VOLATILE_P (operands[0]) = 1;
22334 (define_insn "*sfence_insn"
22335 [(set (match_operand:BLK 0 "" "")
22336 (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
22337 "TARGET_SSE || TARGET_3DNOW_A"
22339 [(set_attr "type" "sse")
22340 (set_attr "memory" "unknown")])
22342 (define_expand "sse_prologue_save"
22343 [(parallel [(set (match_operand:BLK 0 "" "")
22344 (unspec:BLK [(reg:DI 21)
22351 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22352 (use (match_operand:DI 1 "register_operand" ""))
22353 (use (match_operand:DI 2 "immediate_operand" ""))
22354 (use (label_ref:DI (match_operand 3 "" "")))])]
22358 (define_insn "*sse_prologue_save_insn"
22359 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22360 (match_operand:DI 4 "const_int_operand" "n")))
22361 (unspec:BLK [(reg:DI 21)
22368 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22369 (use (match_operand:DI 1 "register_operand" "r"))
22370 (use (match_operand:DI 2 "const_int_operand" "i"))
22371 (use (label_ref:DI (match_operand 3 "" "X")))]
22373 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
22374 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22378 operands[0] = gen_rtx_MEM (Pmode,
22379 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22380 output_asm_insn (\"jmp\\t%A1\", operands);
22381 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22383 operands[4] = adjust_address (operands[0], DImode, i*16);
22384 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22385 PUT_MODE (operands[4], TImode);
22386 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22387 output_asm_insn (\"rex\", operands);
22388 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
22390 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
22391 CODE_LABEL_NUMBER (operands[3]));
22395 [(set_attr "type" "other")
22396 (set_attr "length_immediate" "0")
22397 (set_attr "length_address" "0")
22398 (set_attr "length" "135")
22399 (set_attr "memory" "store")
22400 (set_attr "modrm" "0")
22401 (set_attr "mode" "DI")])
22403 ;; 3Dnow! instructions
22405 (define_insn "addv2sf3"
22406 [(set (match_operand:V2SF 0 "register_operand" "=y")
22407 (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22408 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22410 "pfadd\\t{%2, %0|%0, %2}"
22411 [(set_attr "type" "mmxadd")
22412 (set_attr "mode" "V2SF")])
22414 (define_insn "subv2sf3"
22415 [(set (match_operand:V2SF 0 "register_operand" "=y")
22416 (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
22417 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22419 "pfsub\\t{%2, %0|%0, %2}"
22420 [(set_attr "type" "mmxadd")
22421 (set_attr "mode" "V2SF")])
22423 (define_insn "subrv2sf3"
22424 [(set (match_operand:V2SF 0 "register_operand" "=y")
22425 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
22426 (match_operand:V2SF 1 "register_operand" "0")))]
22428 "pfsubr\\t{%2, %0|%0, %2}"
22429 [(set_attr "type" "mmxadd")
22430 (set_attr "mode" "V2SF")])
22432 (define_insn "gtv2sf3"
22433 [(set (match_operand:V2SI 0 "register_operand" "=y")
22434 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
22435 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22437 "pfcmpgt\\t{%2, %0|%0, %2}"
22438 [(set_attr "type" "mmxcmp")
22439 (set_attr "mode" "V2SF")])
22441 (define_insn "gev2sf3"
22442 [(set (match_operand:V2SI 0 "register_operand" "=y")
22443 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
22444 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22446 "pfcmpge\\t{%2, %0|%0, %2}"
22447 [(set_attr "type" "mmxcmp")
22448 (set_attr "mode" "V2SF")])
22450 (define_insn "eqv2sf3"
22451 [(set (match_operand:V2SI 0 "register_operand" "=y")
22452 (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
22453 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22455 "pfcmpeq\\t{%2, %0|%0, %2}"
22456 [(set_attr "type" "mmxcmp")
22457 (set_attr "mode" "V2SF")])
22459 (define_insn "pfmaxv2sf3"
22460 [(set (match_operand:V2SF 0 "register_operand" "=y")
22461 (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
22462 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22464 "pfmax\\t{%2, %0|%0, %2}"
22465 [(set_attr "type" "mmxadd")
22466 (set_attr "mode" "V2SF")])
22468 (define_insn "pfminv2sf3"
22469 [(set (match_operand:V2SF 0 "register_operand" "=y")
22470 (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
22471 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22473 "pfmin\\t{%2, %0|%0, %2}"
22474 [(set_attr "type" "mmxadd")
22475 (set_attr "mode" "V2SF")])
22477 (define_insn "mulv2sf3"
22478 [(set (match_operand:V2SF 0 "register_operand" "=y")
22479 (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
22480 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
22482 "pfmul\\t{%2, %0|%0, %2}"
22483 [(set_attr "type" "mmxmul")
22484 (set_attr "mode" "V2SF")])
22486 (define_insn "femms"
22487 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
22488 (clobber (reg:XF 8))
22489 (clobber (reg:XF 9))
22490 (clobber (reg:XF 10))
22491 (clobber (reg:XF 11))
22492 (clobber (reg:XF 12))
22493 (clobber (reg:XF 13))
22494 (clobber (reg:XF 14))
22495 (clobber (reg:XF 15))
22496 (clobber (reg:DI 29))
22497 (clobber (reg:DI 30))
22498 (clobber (reg:DI 31))
22499 (clobber (reg:DI 32))
22500 (clobber (reg:DI 33))
22501 (clobber (reg:DI 34))
22502 (clobber (reg:DI 35))
22503 (clobber (reg:DI 36))]
22506 [(set_attr "type" "mmx")
22507 (set_attr "memory" "none")])
22509 (define_insn "pf2id"
22510 [(set (match_operand:V2SI 0 "register_operand" "=y")
22511 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
22513 "pf2id\\t{%1, %0|%0, %1}"
22514 [(set_attr "type" "mmxcvt")
22515 (set_attr "mode" "V2SF")])
22517 (define_insn "pf2iw"
22518 [(set (match_operand:V2SI 0 "register_operand" "=y")
22521 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
22523 "pf2iw\\t{%1, %0|%0, %1}"
22524 [(set_attr "type" "mmxcvt")
22525 (set_attr "mode" "V2SF")])
22527 (define_insn "pfacc"
22528 [(set (match_operand:V2SF 0 "register_operand" "=y")
22531 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22532 (parallel [(const_int 0)]))
22533 (vec_select:SF (match_dup 1)
22534 (parallel [(const_int 1)])))
22536 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22537 (parallel [(const_int 0)]))
22538 (vec_select:SF (match_dup 2)
22539 (parallel [(const_int 1)])))))]
22541 "pfacc\\t{%2, %0|%0, %2}"
22542 [(set_attr "type" "mmxadd")
22543 (set_attr "mode" "V2SF")])
22545 (define_insn "pfnacc"
22546 [(set (match_operand:V2SF 0 "register_operand" "=y")
22549 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22550 (parallel [(const_int 0)]))
22551 (vec_select:SF (match_dup 1)
22552 (parallel [(const_int 1)])))
22554 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22555 (parallel [(const_int 0)]))
22556 (vec_select:SF (match_dup 2)
22557 (parallel [(const_int 1)])))))]
22559 "pfnacc\\t{%2, %0|%0, %2}"
22560 [(set_attr "type" "mmxadd")
22561 (set_attr "mode" "V2SF")])
22563 (define_insn "pfpnacc"
22564 [(set (match_operand:V2SF 0 "register_operand" "=y")
22567 (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
22568 (parallel [(const_int 0)]))
22569 (vec_select:SF (match_dup 1)
22570 (parallel [(const_int 1)])))
22572 (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
22573 (parallel [(const_int 0)]))
22574 (vec_select:SF (match_dup 2)
22575 (parallel [(const_int 1)])))))]
22577 "pfpnacc\\t{%2, %0|%0, %2}"
22578 [(set_attr "type" "mmxadd")
22579 (set_attr "mode" "V2SF")])
22581 (define_insn "pi2fw"
22582 [(set (match_operand:V2SF 0 "register_operand" "=y")
22587 (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22588 (parallel [(const_int 0)]))))
22591 (vec_select:SI (match_dup 1)
22592 (parallel [(const_int 1)])))))))]
22594 "pi2fw\\t{%1, %0|%0, %1}"
22595 [(set_attr "type" "mmxcvt")
22596 (set_attr "mode" "V2SF")])
22598 (define_insn "floatv2si2"
22599 [(set (match_operand:V2SF 0 "register_operand" "=y")
22600 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22602 "pi2fd\\t{%1, %0|%0, %1}"
22603 [(set_attr "type" "mmxcvt")
22604 (set_attr "mode" "V2SF")])
22606 ;; This insn is identical to pavgb in operation, but the opcode is
22607 ;; different. To avoid accidentally matching pavgb, use an unspec.
22609 (define_insn "pavgusb"
22610 [(set (match_operand:V8QI 0 "register_operand" "=y")
22612 [(match_operand:V8QI 1 "register_operand" "0")
22613 (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
22616 "pavgusb\\t{%2, %0|%0, %2}"
22617 [(set_attr "type" "mmxshft")
22618 (set_attr "mode" "TI")])
22620 ;; 3DNow reciprocal and sqrt
22622 (define_insn "pfrcpv2sf2"
22623 [(set (match_operand:V2SF 0 "register_operand" "=y")
22624 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22627 "pfrcp\\t{%1, %0|%0, %1}"
22628 [(set_attr "type" "mmx")
22629 (set_attr "mode" "TI")])
22631 (define_insn "pfrcpit1v2sf3"
22632 [(set (match_operand:V2SF 0 "register_operand" "=y")
22633 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22634 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22637 "pfrcpit1\\t{%2, %0|%0, %2}"
22638 [(set_attr "type" "mmx")
22639 (set_attr "mode" "TI")])
22641 (define_insn "pfrcpit2v2sf3"
22642 [(set (match_operand:V2SF 0 "register_operand" "=y")
22643 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22644 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22647 "pfrcpit2\\t{%2, %0|%0, %2}"
22648 [(set_attr "type" "mmx")
22649 (set_attr "mode" "TI")])
22651 (define_insn "pfrsqrtv2sf2"
22652 [(set (match_operand:V2SF 0 "register_operand" "=y")
22653 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
22656 "pfrsqrt\\t{%1, %0|%0, %1}"
22657 [(set_attr "type" "mmx")
22658 (set_attr "mode" "TI")])
22660 (define_insn "pfrsqit1v2sf3"
22661 [(set (match_operand:V2SF 0 "register_operand" "=y")
22662 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
22663 (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
22666 "pfrsqit1\\t{%2, %0|%0, %2}"
22667 [(set_attr "type" "mmx")
22668 (set_attr "mode" "TI")])
22670 (define_insn "pmulhrwv4hi3"
22671 [(set (match_operand:V4HI 0 "register_operand" "=y")
22677 (match_operand:V4HI 1 "register_operand" "0"))
22679 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
22680 (const_vector:V4SI [(const_int 32768)
22683 (const_int 32768)]))
22686 "pmulhrw\\t{%2, %0|%0, %2}"
22687 [(set_attr "type" "mmxmul")
22688 (set_attr "mode" "TI")])
22690 (define_insn "pswapdv2si2"
22691 [(set (match_operand:V2SI 0 "register_operand" "=y")
22692 (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
22693 (parallel [(const_int 1) (const_int 0)])))]
22695 "pswapd\\t{%1, %0|%0, %1}"
22696 [(set_attr "type" "mmxcvt")
22697 (set_attr "mode" "TI")])
22699 (define_insn "pswapdv2sf2"
22700 [(set (match_operand:V2SF 0 "register_operand" "=y")
22701 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
22702 (parallel [(const_int 1) (const_int 0)])))]
22704 "pswapd\\t{%1, %0|%0, %1}"
22705 [(set_attr "type" "mmxcvt")
22706 (set_attr "mode" "TI")])
22708 (define_expand "prefetch"
22709 [(prefetch (match_operand 0 "address_operand" "")
22710 (match_operand:SI 1 "const_int_operand" "")
22711 (match_operand:SI 2 "const_int_operand" ""))]
22712 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22714 int rw = INTVAL (operands[1]);
22715 int locality = INTVAL (operands[2]);
22717 if (rw != 0 && rw != 1)
22719 if (locality < 0 || locality > 3)
22721 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
22724 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22725 suported by SSE counterpart or the SSE prefetch is not available
22726 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22728 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22729 operands[2] = GEN_INT (3);
22731 operands[1] = const0_rtx;
22734 (define_insn "*prefetch_sse"
22735 [(prefetch (match_operand:SI 0 "address_operand" "p")
22737 (match_operand:SI 1 "const_int_operand" ""))]
22738 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22740 static const char * const patterns[4] = {
22741 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22744 int locality = INTVAL (operands[1]);
22745 if (locality < 0 || locality > 3)
22748 return patterns[locality];
22750 [(set_attr "type" "sse")
22751 (set_attr "memory" "none")])
22753 (define_insn "*prefetch_sse_rex"
22754 [(prefetch (match_operand:DI 0 "address_operand" "p")
22756 (match_operand:SI 1 "const_int_operand" ""))]
22757 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22759 static const char * const patterns[4] = {
22760 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22763 int locality = INTVAL (operands[1]);
22764 if (locality < 0 || locality > 3)
22767 return patterns[locality];
22769 [(set_attr "type" "sse")
22770 (set_attr "memory" "none")])
22772 (define_insn "*prefetch_3dnow"
22773 [(prefetch (match_operand:SI 0 "address_operand" "p")
22774 (match_operand:SI 1 "const_int_operand" "n")
22776 "TARGET_3DNOW && !TARGET_64BIT"
22778 if (INTVAL (operands[1]) == 0)
22779 return "prefetch\t%a0";
22781 return "prefetchw\t%a0";
22783 [(set_attr "type" "mmx")
22784 (set_attr "memory" "none")])
22786 (define_insn "*prefetch_3dnow_rex"
22787 [(prefetch (match_operand:DI 0 "address_operand" "p")
22788 (match_operand:SI 1 "const_int_operand" "n")
22790 "TARGET_3DNOW && TARGET_64BIT"
22792 if (INTVAL (operands[1]) == 0)
22793 return "prefetch\t%a0";
22795 return "prefetchw\t%a0";
22797 [(set_attr "type" "mmx")
22798 (set_attr "memory" "none")])
22802 (define_insn "addv2df3"
22803 [(set (match_operand:V2DF 0 "register_operand" "=x")
22804 (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22805 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22807 "addpd\t{%2, %0|%0, %2}"
22808 [(set_attr "type" "sseadd")
22809 (set_attr "mode" "V2DF")])
22811 (define_insn "vmaddv2df3"
22812 [(set (match_operand:V2DF 0 "register_operand" "=x")
22813 (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22814 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22818 "addsd\t{%2, %0|%0, %2}"
22819 [(set_attr "type" "sseadd")
22820 (set_attr "mode" "DF")])
22822 (define_insn "subv2df3"
22823 [(set (match_operand:V2DF 0 "register_operand" "=x")
22824 (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22825 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22827 "subpd\t{%2, %0|%0, %2}"
22828 [(set_attr "type" "sseadd")
22829 (set_attr "mode" "V2DF")])
22831 (define_insn "vmsubv2df3"
22832 [(set (match_operand:V2DF 0 "register_operand" "=x")
22833 (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
22834 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22838 "subsd\t{%2, %0|%0, %2}"
22839 [(set_attr "type" "sseadd")
22840 (set_attr "mode" "DF")])
22842 (define_insn "mulv2df3"
22843 [(set (match_operand:V2DF 0 "register_operand" "=x")
22844 (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22845 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22847 "mulpd\t{%2, %0|%0, %2}"
22848 [(set_attr "type" "ssemul")
22849 (set_attr "mode" "V2DF")])
22851 (define_insn "vmmulv2df3"
22852 [(set (match_operand:V2DF 0 "register_operand" "=x")
22853 (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
22854 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22858 "mulsd\t{%2, %0|%0, %2}"
22859 [(set_attr "type" "ssemul")
22860 (set_attr "mode" "DF")])
22862 (define_insn "divv2df3"
22863 [(set (match_operand:V2DF 0 "register_operand" "=x")
22864 (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22865 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22867 "divpd\t{%2, %0|%0, %2}"
22868 [(set_attr "type" "ssediv")
22869 (set_attr "mode" "V2DF")])
22871 (define_insn "vmdivv2df3"
22872 [(set (match_operand:V2DF 0 "register_operand" "=x")
22873 (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
22874 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22878 "divsd\t{%2, %0|%0, %2}"
22879 [(set_attr "type" "ssediv")
22880 (set_attr "mode" "DF")])
22884 (define_insn "smaxv2df3"
22885 [(set (match_operand:V2DF 0 "register_operand" "=x")
22886 (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22887 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22889 "maxpd\t{%2, %0|%0, %2}"
22890 [(set_attr "type" "sseadd")
22891 (set_attr "mode" "V2DF")])
22893 (define_insn "vmsmaxv2df3"
22894 [(set (match_operand:V2DF 0 "register_operand" "=x")
22895 (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
22896 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22900 "maxsd\t{%2, %0|%0, %2}"
22901 [(set_attr "type" "sseadd")
22902 (set_attr "mode" "DF")])
22904 (define_insn "sminv2df3"
22905 [(set (match_operand:V2DF 0 "register_operand" "=x")
22906 (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22907 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
22909 "minpd\t{%2, %0|%0, %2}"
22910 [(set_attr "type" "sseadd")
22911 (set_attr "mode" "V2DF")])
22913 (define_insn "vmsminv2df3"
22914 [(set (match_operand:V2DF 0 "register_operand" "=x")
22915 (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
22916 (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
22920 "minsd\t{%2, %0|%0, %2}"
22921 [(set_attr "type" "sseadd")
22922 (set_attr "mode" "DF")])
22923 ;; SSE2 square root. There doesn't appear to be an extension for the
22924 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
22926 (define_insn "sqrtv2df2"
22927 [(set (match_operand:V2DF 0 "register_operand" "=x")
22928 (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
22930 "sqrtpd\t{%1, %0|%0, %1}"
22931 [(set_attr "type" "sse")
22932 (set_attr "mode" "V2DF")])
22934 (define_insn "vmsqrtv2df2"
22935 [(set (match_operand:V2DF 0 "register_operand" "=x")
22936 (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
22937 (match_operand:V2DF 2 "register_operand" "0")
22940 "sqrtsd\t{%1, %0|%0, %1}"
22941 [(set_attr "type" "sse")
22942 (set_attr "mode" "SF")])
22944 ;; SSE mask-generating compares
22946 (define_insn "maskcmpv2df3"
22947 [(set (match_operand:V2DI 0 "register_operand" "=x")
22948 (match_operator:V2DI 3 "sse_comparison_operator"
22949 [(match_operand:V2DF 1 "register_operand" "0")
22950 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
22952 "cmp%D3pd\t{%2, %0|%0, %2}"
22953 [(set_attr "type" "ssecmp")
22954 (set_attr "mode" "V2DF")])
22956 (define_insn "maskncmpv2df3"
22957 [(set (match_operand:V2DI 0 "register_operand" "=x")
22959 (match_operator:V2DI 3 "sse_comparison_operator"
22960 [(match_operand:V2DF 1 "register_operand" "0")
22961 (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
22964 if (GET_CODE (operands[3]) == UNORDERED)
22965 return "cmpordps\t{%2, %0|%0, %2}";
22967 return "cmpn%D3pd\t{%2, %0|%0, %2}";
22969 [(set_attr "type" "ssecmp")
22970 (set_attr "mode" "V2DF")])
22972 (define_insn "vmmaskcmpv2df3"
22973 [(set (match_operand:V2DI 0 "register_operand" "=x")
22975 (match_operator:V2DI 3 "sse_comparison_operator"
22976 [(match_operand:V2DF 1 "register_operand" "0")
22977 (match_operand:V2DF 2 "nonimmediate_operand" "x")])
22978 (subreg:V2DI (match_dup 1) 0)
22981 "cmp%D3sd\t{%2, %0|%0, %2}"
22982 [(set_attr "type" "ssecmp")
22983 (set_attr "mode" "DF")])
22985 (define_insn "vmmaskncmpv2df3"
22986 [(set (match_operand:V2DI 0 "register_operand" "=x")
22989 (match_operator:V2DI 3 "sse_comparison_operator"
22990 [(match_operand:V2DF 1 "register_operand" "0")
22991 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
22992 (subreg:V2DI (match_dup 1) 0)
22996 if (GET_CODE (operands[3]) == UNORDERED)
22997 return "cmpordsd\t{%2, %0|%0, %2}";
22999 return "cmpn%D3sd\t{%2, %0|%0, %2}";
23001 [(set_attr "type" "ssecmp")
23002 (set_attr "mode" "DF")])
23004 (define_insn "sse2_comi"
23005 [(set (reg:CCFP FLAGS_REG)
23006 (compare:CCFP (vec_select:DF
23007 (match_operand:V2DF 0 "register_operand" "x")
23008 (parallel [(const_int 0)]))
23010 (match_operand:V2DF 1 "register_operand" "x")
23011 (parallel [(const_int 0)]))))]
23013 "comisd\t{%1, %0|%0, %1}"
23014 [(set_attr "type" "ssecomi")
23015 (set_attr "mode" "DF")])
23017 (define_insn "sse2_ucomi"
23018 [(set (reg:CCFPU FLAGS_REG)
23019 (compare:CCFPU (vec_select:DF
23020 (match_operand:V2DF 0 "register_operand" "x")
23021 (parallel [(const_int 0)]))
23023 (match_operand:V2DF 1 "register_operand" "x")
23024 (parallel [(const_int 0)]))))]
23026 "ucomisd\t{%1, %0|%0, %1}"
23027 [(set_attr "type" "ssecomi")
23028 (set_attr "mode" "DF")])
23030 ;; SSE Strange Moves.
23032 (define_insn "sse2_movmskpd"
23033 [(set (match_operand:SI 0 "register_operand" "=r")
23034 (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
23037 "movmskpd\t{%1, %0|%0, %1}"
23038 [(set_attr "type" "ssecvt")
23039 (set_attr "mode" "V2DF")])
23041 (define_insn "sse2_pmovmskb"
23042 [(set (match_operand:SI 0 "register_operand" "=r")
23043 (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
23046 "pmovmskb\t{%1, %0|%0, %1}"
23047 [(set_attr "type" "ssecvt")
23048 (set_attr "mode" "V2DF")])
23050 (define_insn "sse2_maskmovdqu"
23051 [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
23052 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23053 (match_operand:V16QI 2 "register_operand" "x")]
23056 ;; @@@ check ordering of operands in intel/nonintel syntax
23057 "maskmovdqu\t{%2, %1|%1, %2}"
23058 [(set_attr "type" "ssecvt")
23059 (set_attr "mode" "TI")])
23061 (define_insn "sse2_maskmovdqu_rex64"
23062 [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
23063 (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
23064 (match_operand:V16QI 2 "register_operand" "x")]
23067 ;; @@@ check ordering of operands in intel/nonintel syntax
23068 "maskmovdqu\t{%2, %1|%1, %2}"
23069 [(set_attr "type" "ssecvt")
23070 (set_attr "mode" "TI")])
23072 (define_insn "sse2_movntv2df"
23073 [(set (match_operand:V2DF 0 "memory_operand" "=m")
23074 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
23077 "movntpd\t{%1, %0|%0, %1}"
23078 [(set_attr "type" "ssecvt")
23079 (set_attr "mode" "V2DF")])
23081 (define_insn "sse2_movntv2di"
23082 [(set (match_operand:V2DI 0 "memory_operand" "=m")
23083 (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
23086 "movntdq\t{%1, %0|%0, %1}"
23087 [(set_attr "type" "ssecvt")
23088 (set_attr "mode" "TI")])
23090 (define_insn "sse2_movntsi"
23091 [(set (match_operand:SI 0 "memory_operand" "=m")
23092 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
23095 "movnti\t{%1, %0|%0, %1}"
23096 [(set_attr "type" "ssecvt")
23097 (set_attr "mode" "V2DF")])
23099 ;; SSE <-> integer/MMX conversions
23101 ;; Conversions between SI and SF
23103 (define_insn "cvtdq2ps"
23104 [(set (match_operand:V4SF 0 "register_operand" "=x")
23105 (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
23107 "cvtdq2ps\t{%1, %0|%0, %1}"
23108 [(set_attr "type" "ssecvt")
23109 (set_attr "mode" "V2DF")])
23111 (define_insn "cvtps2dq"
23112 [(set (match_operand:V4SI 0 "register_operand" "=x")
23113 (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
23115 "cvtps2dq\t{%1, %0|%0, %1}"
23116 [(set_attr "type" "ssecvt")
23117 (set_attr "mode" "TI")])
23119 (define_insn "cvttps2dq"
23120 [(set (match_operand:V4SI 0 "register_operand" "=x")
23121 (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
23124 "cvttps2dq\t{%1, %0|%0, %1}"
23125 [(set_attr "type" "ssecvt")
23126 (set_attr "mode" "TI")])
23128 ;; Conversions between SI and DF
23130 (define_insn "cvtdq2pd"
23131 [(set (match_operand:V2DF 0 "register_operand" "=x")
23132 (float:V2DF (vec_select:V2SI
23133 (match_operand:V4SI 1 "nonimmediate_operand" "xm")
23136 (const_int 1)]))))]
23138 "cvtdq2pd\t{%1, %0|%0, %1}"
23139 [(set_attr "type" "ssecvt")
23140 (set_attr "mode" "V2DF")])
23142 (define_insn "cvtpd2dq"
23143 [(set (match_operand:V4SI 0 "register_operand" "=x")
23145 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
23146 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23148 "cvtpd2dq\t{%1, %0|%0, %1}"
23149 [(set_attr "type" "ssecvt")
23150 (set_attr "mode" "TI")])
23152 (define_insn "cvttpd2dq"
23153 [(set (match_operand:V4SI 0 "register_operand" "=x")
23155 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23157 (const_vector:V2SI [(const_int 0) (const_int 0)])))]
23159 "cvttpd2dq\t{%1, %0|%0, %1}"
23160 [(set_attr "type" "ssecvt")
23161 (set_attr "mode" "TI")])
23163 (define_insn "cvtpd2pi"
23164 [(set (match_operand:V2SI 0 "register_operand" "=y")
23165 (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
23167 "cvtpd2pi\t{%1, %0|%0, %1}"
23168 [(set_attr "type" "ssecvt")
23169 (set_attr "mode" "TI")])
23171 (define_insn "cvttpd2pi"
23172 [(set (match_operand:V2SI 0 "register_operand" "=y")
23173 (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
23176 "cvttpd2pi\t{%1, %0|%0, %1}"
23177 [(set_attr "type" "ssecvt")
23178 (set_attr "mode" "TI")])
23180 (define_insn "cvtpi2pd"
23181 [(set (match_operand:V2DF 0 "register_operand" "=x")
23182 (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
23184 "cvtpi2pd\t{%1, %0|%0, %1}"
23185 [(set_attr "type" "ssecvt")
23186 (set_attr "mode" "TI")])
23188 ;; Conversions between SI and DF
23190 (define_insn "cvtsd2si"
23191 [(set (match_operand:SI 0 "register_operand" "=r,r")
23192 (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23193 (parallel [(const_int 0)]))))]
23195 "cvtsd2si\t{%1, %0|%0, %1}"
23196 [(set_attr "type" "sseicvt")
23197 (set_attr "athlon_decode" "double,vector")
23198 (set_attr "mode" "SI")])
23200 (define_insn "cvtsd2siq"
23201 [(set (match_operand:DI 0 "register_operand" "=r,r")
23202 (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
23203 (parallel [(const_int 0)]))))]
23204 "TARGET_SSE2 && TARGET_64BIT"
23205 "cvtsd2siq\t{%1, %0|%0, %1}"
23206 [(set_attr "type" "sseicvt")
23207 (set_attr "athlon_decode" "double,vector")
23208 (set_attr "mode" "DI")])
23210 (define_insn "cvttsd2si"
23211 [(set (match_operand:SI 0 "register_operand" "=r,r")
23212 (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23213 (parallel [(const_int 0)]))] UNSPEC_FIX))]
23215 "cvttsd2si\t{%1, %0|%0, %1}"
23216 [(set_attr "type" "sseicvt")
23217 (set_attr "mode" "SI")
23218 (set_attr "athlon_decode" "double,vector")])
23220 (define_insn "cvttsd2siq"
23221 [(set (match_operand:DI 0 "register_operand" "=r,r")
23222 (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
23223 (parallel [(const_int 0)]))] UNSPEC_FIX))]
23224 "TARGET_SSE2 && TARGET_64BIT"
23225 "cvttsd2siq\t{%1, %0|%0, %1}"
23226 [(set_attr "type" "sseicvt")
23227 (set_attr "mode" "DI")
23228 (set_attr "athlon_decode" "double,vector")])
23230 (define_insn "cvtsi2sd"
23231 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23232 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23233 (vec_duplicate:V2DF
23235 (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
23238 "cvtsi2sd\t{%2, %0|%0, %2}"
23239 [(set_attr "type" "sseicvt")
23240 (set_attr "mode" "DF")
23241 (set_attr "athlon_decode" "double,direct")])
23243 (define_insn "cvtsi2sdq"
23244 [(set (match_operand:V2DF 0 "register_operand" "=x,x")
23245 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
23246 (vec_duplicate:V2DF
23248 (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
23250 "TARGET_SSE2 && TARGET_64BIT"
23251 "cvtsi2sdq\t{%2, %0|%0, %2}"
23252 [(set_attr "type" "sseicvt")
23253 (set_attr "mode" "DF")
23254 (set_attr "athlon_decode" "double,direct")])
23256 ;; Conversions between SF and DF
23258 (define_insn "cvtsd2ss"
23259 [(set (match_operand:V4SF 0 "register_operand" "=x,x")
23260 (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
23261 (vec_duplicate:V4SF
23262 (float_truncate:V2SF
23263 (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
23266 "cvtsd2ss\t{%2, %0|%0, %2}"
23267 [(set_attr "type" "ssecvt")
23268 (set_attr "athlon_decode" "vector,double")
23269 (set_attr "mode" "SF")])
23271 (define_insn "cvtss2sd"
23272 [(set (match_operand:V2DF 0 "register_operand" "=x")
23273 (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
23276 (match_operand:V4SF 2 "nonimmediate_operand" "xm")
23277 (parallel [(const_int 0)
23281 "cvtss2sd\t{%2, %0|%0, %2}"
23282 [(set_attr "type" "ssecvt")
23283 (set_attr "mode" "DF")])
23285 (define_insn "cvtpd2ps"
23286 [(set (match_operand:V4SF 0 "register_operand" "=x")
23289 (subreg:V2SI (float_truncate:V2SF
23290 (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
23291 (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
23293 "cvtpd2ps\t{%1, %0|%0, %1}"
23294 [(set_attr "type" "ssecvt")
23295 (set_attr "mode" "V4SF")])
23297 (define_insn "cvtps2pd"
23298 [(set (match_operand:V2DF 0 "register_operand" "=x")
23300 (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
23301 (parallel [(const_int 0)
23302 (const_int 1)]))))]
23304 "cvtps2pd\t{%1, %0|%0, %1}"
23305 [(set_attr "type" "ssecvt")
23306 (set_attr "mode" "V2DF")])
23308 ;; SSE2 variants of MMX insns
23312 (define_insn "addv16qi3"
23313 [(set (match_operand:V16QI 0 "register_operand" "=x")
23314 (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23315 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23317 "paddb\t{%2, %0|%0, %2}"
23318 [(set_attr "type" "sseiadd")
23319 (set_attr "mode" "TI")])
23321 (define_insn "addv8hi3"
23322 [(set (match_operand:V8HI 0 "register_operand" "=x")
23323 (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23324 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23326 "paddw\t{%2, %0|%0, %2}"
23327 [(set_attr "type" "sseiadd")
23328 (set_attr "mode" "TI")])
23330 (define_insn "addv4si3"
23331 [(set (match_operand:V4SI 0 "register_operand" "=x")
23332 (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
23333 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23335 "paddd\t{%2, %0|%0, %2}"
23336 [(set_attr "type" "sseiadd")
23337 (set_attr "mode" "TI")])
23339 (define_insn "addv2di3"
23340 [(set (match_operand:V2DI 0 "register_operand" "=x")
23341 (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
23342 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23344 "paddq\t{%2, %0|%0, %2}"
23345 [(set_attr "type" "sseiadd")
23346 (set_attr "mode" "TI")])
23348 (define_insn "ssaddv16qi3"
23349 [(set (match_operand:V16QI 0 "register_operand" "=x")
23350 (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23351 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23353 "paddsb\t{%2, %0|%0, %2}"
23354 [(set_attr "type" "sseiadd")
23355 (set_attr "mode" "TI")])
23357 (define_insn "ssaddv8hi3"
23358 [(set (match_operand:V8HI 0 "register_operand" "=x")
23359 (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23360 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23362 "paddsw\t{%2, %0|%0, %2}"
23363 [(set_attr "type" "sseiadd")
23364 (set_attr "mode" "TI")])
23366 (define_insn "usaddv16qi3"
23367 [(set (match_operand:V16QI 0 "register_operand" "=x")
23368 (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
23369 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23371 "paddusb\t{%2, %0|%0, %2}"
23372 [(set_attr "type" "sseiadd")
23373 (set_attr "mode" "TI")])
23375 (define_insn "usaddv8hi3"
23376 [(set (match_operand:V8HI 0 "register_operand" "=x")
23377 (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
23378 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23380 "paddusw\t{%2, %0|%0, %2}"
23381 [(set_attr "type" "sseiadd")
23382 (set_attr "mode" "TI")])
23384 (define_insn "subv16qi3"
23385 [(set (match_operand:V16QI 0 "register_operand" "=x")
23386 (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23387 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23389 "psubb\t{%2, %0|%0, %2}"
23390 [(set_attr "type" "sseiadd")
23391 (set_attr "mode" "TI")])
23393 (define_insn "subv8hi3"
23394 [(set (match_operand:V8HI 0 "register_operand" "=x")
23395 (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23396 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23398 "psubw\t{%2, %0|%0, %2}"
23399 [(set_attr "type" "sseiadd")
23400 (set_attr "mode" "TI")])
23402 (define_insn "subv4si3"
23403 [(set (match_operand:V4SI 0 "register_operand" "=x")
23404 (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
23405 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23407 "psubd\t{%2, %0|%0, %2}"
23408 [(set_attr "type" "sseiadd")
23409 (set_attr "mode" "TI")])
23411 (define_insn "subv2di3"
23412 [(set (match_operand:V2DI 0 "register_operand" "=x")
23413 (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
23414 (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
23416 "psubq\t{%2, %0|%0, %2}"
23417 [(set_attr "type" "sseiadd")
23418 (set_attr "mode" "TI")])
23420 (define_insn "sssubv16qi3"
23421 [(set (match_operand:V16QI 0 "register_operand" "=x")
23422 (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23423 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23425 "psubsb\t{%2, %0|%0, %2}"
23426 [(set_attr "type" "sseiadd")
23427 (set_attr "mode" "TI")])
23429 (define_insn "sssubv8hi3"
23430 [(set (match_operand:V8HI 0 "register_operand" "=x")
23431 (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23432 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23434 "psubsw\t{%2, %0|%0, %2}"
23435 [(set_attr "type" "sseiadd")
23436 (set_attr "mode" "TI")])
23438 (define_insn "ussubv16qi3"
23439 [(set (match_operand:V16QI 0 "register_operand" "=x")
23440 (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
23441 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23443 "psubusb\t{%2, %0|%0, %2}"
23444 [(set_attr "type" "sseiadd")
23445 (set_attr "mode" "TI")])
23447 (define_insn "ussubv8hi3"
23448 [(set (match_operand:V8HI 0 "register_operand" "=x")
23449 (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
23450 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23452 "psubusw\t{%2, %0|%0, %2}"
23453 [(set_attr "type" "sseiadd")
23454 (set_attr "mode" "TI")])
23456 (define_insn "mulv8hi3"
23457 [(set (match_operand:V8HI 0 "register_operand" "=x")
23458 (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
23459 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23461 "pmullw\t{%2, %0|%0, %2}"
23462 [(set_attr "type" "sseimul")
23463 (set_attr "mode" "TI")])
23465 (define_insn "smulv8hi3_highpart"
23466 [(set (match_operand:V8HI 0 "register_operand" "=x")
23469 (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23470 (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23473 "pmulhw\t{%2, %0|%0, %2}"
23474 [(set_attr "type" "sseimul")
23475 (set_attr "mode" "TI")])
23477 (define_insn "umulv8hi3_highpart"
23478 [(set (match_operand:V8HI 0 "register_operand" "=x")
23481 (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
23482 (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
23485 "pmulhuw\t{%2, %0|%0, %2}"
23486 [(set_attr "type" "sseimul")
23487 (set_attr "mode" "TI")])
23489 (define_insn "sse2_umulsidi3"
23490 [(set (match_operand:DI 0 "register_operand" "=y")
23491 (mult:DI (zero_extend:DI (vec_select:SI
23492 (match_operand:V2SI 1 "register_operand" "0")
23493 (parallel [(const_int 0)])))
23494 (zero_extend:DI (vec_select:SI
23495 (match_operand:V2SI 2 "nonimmediate_operand" "ym")
23496 (parallel [(const_int 0)])))))]
23498 "pmuludq\t{%2, %0|%0, %2}"
23499 [(set_attr "type" "mmxmul")
23500 (set_attr "mode" "DI")])
23502 (define_insn "sse2_umulv2siv2di3"
23503 [(set (match_operand:V2DI 0 "register_operand" "=x")
23504 (mult:V2DI (zero_extend:V2DI
23506 (match_operand:V4SI 1 "register_operand" "0")
23507 (parallel [(const_int 0) (const_int 2)])))
23510 (match_operand:V4SI 2 "nonimmediate_operand" "xm")
23511 (parallel [(const_int 0) (const_int 2)])))))]
23513 "pmuludq\t{%2, %0|%0, %2}"
23514 [(set_attr "type" "sseimul")
23515 (set_attr "mode" "TI")])
23517 (define_insn "sse2_pmaddwd"
23518 [(set (match_operand:V4SI 0 "register_operand" "=x")
23521 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
23522 (parallel [(const_int 0)
23526 (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
23527 (parallel [(const_int 0)
23532 (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
23533 (parallel [(const_int 1)
23537 (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
23538 (parallel [(const_int 1)
23541 (const_int 7)]))))))]
23543 "pmaddwd\t{%2, %0|%0, %2}"
23544 [(set_attr "type" "sseiadd")
23545 (set_attr "mode" "TI")])
23547 ;; Same as pxor, but don't show input operands so that we don't think
23549 (define_insn "sse2_clrti"
23550 [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
23553 if (get_attr_mode (insn) == MODE_TI)
23554 return "pxor\t%0, %0";
23556 return "xorps\t%0, %0";
23558 [(set_attr "type" "ssemov")
23559 (set_attr "memory" "none")
23562 (ne (symbol_ref "optimize_size")
23564 (const_string "V4SF")
23565 (const_string "TI")))])
23567 ;; MMX unsigned averages/sum of absolute differences
23569 (define_insn "sse2_uavgv16qi3"
23570 [(set (match_operand:V16QI 0 "register_operand" "=x")
23572 (plus:V16QI (plus:V16QI
23573 (match_operand:V16QI 1 "register_operand" "0")
23574 (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
23575 (const_vector:V16QI [(const_int 1) (const_int 1)
23576 (const_int 1) (const_int 1)
23577 (const_int 1) (const_int 1)
23578 (const_int 1) (const_int 1)
23579 (const_int 1) (const_int 1)
23580 (const_int 1) (const_int 1)
23581 (const_int 1) (const_int 1)
23582 (const_int 1) (const_int 1)]))
23585 "pavgb\t{%2, %0|%0, %2}"
23586 [(set_attr "type" "sseiadd")
23587 (set_attr "mode" "TI")])
23589 (define_insn "sse2_uavgv8hi3"
23590 [(set (match_operand:V8HI 0 "register_operand" "=x")
23592 (plus:V8HI (plus:V8HI
23593 (match_operand:V8HI 1 "register_operand" "0")
23594 (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
23595 (const_vector:V8HI [(const_int 1) (const_int 1)
23596 (const_int 1) (const_int 1)
23597 (const_int 1) (const_int 1)
23598 (const_int 1) (const_int 1)]))
23601 "pavgw\t{%2, %0|%0, %2}"
23602 [(set_attr "type" "sseiadd")
23603 (set_attr "mode" "TI")])
23605 ;; @@@ this isn't the right representation.
23606 (define_insn "sse2_psadbw"
23607 [(set (match_operand:V2DI 0 "register_operand" "=x")
23608 (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
23609 (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
23612 "psadbw\t{%2, %0|%0, %2}"
23613 [(set_attr "type" "sseiadd")
23614 (set_attr "mode" "TI")])
23617 ;; MMX insert/extract/shuffle
23619 (define_insn "sse2_pinsrw"
23620 [(set (match_operand:V8HI 0 "register_operand" "=x")
23621 (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
23622 (vec_duplicate:V8HI
23624 (match_operand:SI 2 "nonimmediate_operand" "rm")))
23625 (match_operand:SI 3 "const_0_to_255_operand" "N")))]
23627 "pinsrw\t{%3, %2, %0|%0, %2, %3}"
23628 [(set_attr "type" "ssecvt")
23629 (set_attr "mode" "TI")])
23631 (define_insn "sse2_pextrw"
23632 [(set (match_operand:SI 0 "register_operand" "=r")
23634 (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
23636 [(match_operand:SI 2 "const_0_to_7_operand" "N")]))))]
23638 "pextrw\t{%2, %1, %0|%0, %1, %2}"
23639 [(set_attr "type" "ssecvt")
23640 (set_attr "mode" "TI")])
23642 (define_insn "sse2_pshufd"
23643 [(set (match_operand:V4SI 0 "register_operand" "=x")
23644 (unspec:V4SI [(match_operand:V4SI 1 "nonimmediate_operand" "xm")
23645 (match_operand:SI 2 "immediate_operand" "i")]
23648 "pshufd\t{%2, %1, %0|%0, %1, %2}"
23649 [(set_attr "type" "ssecvt")
23650 (set_attr "mode" "TI")])
23652 (define_insn "sse2_pshuflw"
23653 [(set (match_operand:V8HI 0 "register_operand" "=x")
23654 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23655 (match_operand:SI 2 "immediate_operand" "i")]
23658 "pshuflw\t{%2, %1, %0|%0, %1, %2}"
23659 [(set_attr "type" "ssecvt")
23660 (set_attr "mode" "TI")])
23662 (define_insn "sse2_pshufhw"
23663 [(set (match_operand:V8HI 0 "register_operand" "=x")
23664 (unspec:V8HI [(match_operand:V8HI 1 "nonimmediate_operand" "xm")
23665 (match_operand:SI 2 "immediate_operand" "i")]
23668 "pshufhw\t{%2, %1, %0|%0, %1, %2}"
23669 [(set_attr "type" "ssecvt")
23670 (set_attr "mode" "TI")])
23672 ;; MMX mask-generating comparisons
23674 (define_insn "eqv16qi3"
23675 [(set (match_operand:V16QI 0 "register_operand" "=x")
23676 (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
23677 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23679 "pcmpeqb\t{%2, %0|%0, %2}"
23680 [(set_attr "type" "ssecmp")
23681 (set_attr "mode" "TI")])
23683 (define_insn "eqv8hi3"
23684 [(set (match_operand:V8HI 0 "register_operand" "=x")
23685 (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
23686 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23688 "pcmpeqw\t{%2, %0|%0, %2}"
23689 [(set_attr "type" "ssecmp")
23690 (set_attr "mode" "TI")])
23692 (define_insn "eqv4si3"
23693 [(set (match_operand:V4SI 0 "register_operand" "=x")
23694 (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
23695 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23697 "pcmpeqd\t{%2, %0|%0, %2}"
23698 [(set_attr "type" "ssecmp")
23699 (set_attr "mode" "TI")])
23701 (define_insn "gtv16qi3"
23702 [(set (match_operand:V16QI 0 "register_operand" "=x")
23703 (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
23704 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23706 "pcmpgtb\t{%2, %0|%0, %2}"
23707 [(set_attr "type" "ssecmp")
23708 (set_attr "mode" "TI")])
23710 (define_insn "gtv8hi3"
23711 [(set (match_operand:V8HI 0 "register_operand" "=x")
23712 (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23713 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23715 "pcmpgtw\t{%2, %0|%0, %2}"
23716 [(set_attr "type" "ssecmp")
23717 (set_attr "mode" "TI")])
23719 (define_insn "gtv4si3"
23720 [(set (match_operand:V4SI 0 "register_operand" "=x")
23721 (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23722 (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
23724 "pcmpgtd\t{%2, %0|%0, %2}"
23725 [(set_attr "type" "ssecmp")
23726 (set_attr "mode" "TI")])
23729 ;; MMX max/min insns
23731 (define_insn "umaxv16qi3"
23732 [(set (match_operand:V16QI 0 "register_operand" "=x")
23733 (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
23734 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23736 "pmaxub\t{%2, %0|%0, %2}"
23737 [(set_attr "type" "sseiadd")
23738 (set_attr "mode" "TI")])
23740 (define_insn "smaxv8hi3"
23741 [(set (match_operand:V8HI 0 "register_operand" "=x")
23742 (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
23743 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23745 "pmaxsw\t{%2, %0|%0, %2}"
23746 [(set_attr "type" "sseiadd")
23747 (set_attr "mode" "TI")])
23749 (define_insn "uminv16qi3"
23750 [(set (match_operand:V16QI 0 "register_operand" "=x")
23751 (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
23752 (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
23754 "pminub\t{%2, %0|%0, %2}"
23755 [(set_attr "type" "sseiadd")
23756 (set_attr "mode" "TI")])
23758 (define_insn "sminv8hi3"
23759 [(set (match_operand:V8HI 0 "register_operand" "=x")
23760 (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
23761 (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
23763 "pminsw\t{%2, %0|%0, %2}"
23764 [(set_attr "type" "sseiadd")
23765 (set_attr "mode" "TI")])
23770 (define_insn "ashrv8hi3"
23771 [(set (match_operand:V8HI 0 "register_operand" "=x")
23772 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23773 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23775 "psraw\t{%2, %0|%0, %2}"
23776 [(set_attr "type" "sseishft")
23777 (set_attr "mode" "TI")])
23779 (define_insn "ashrv4si3"
23780 [(set (match_operand:V4SI 0 "register_operand" "=x")
23781 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23782 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23784 "psrad\t{%2, %0|%0, %2}"
23785 [(set_attr "type" "sseishft")
23786 (set_attr "mode" "TI")])
23788 (define_insn "lshrv8hi3"
23789 [(set (match_operand:V8HI 0 "register_operand" "=x")
23790 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23791 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23793 "psrlw\t{%2, %0|%0, %2}"
23794 [(set_attr "type" "sseishft")
23795 (set_attr "mode" "TI")])
23797 (define_insn "lshrv4si3"
23798 [(set (match_operand:V4SI 0 "register_operand" "=x")
23799 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23800 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23802 "psrld\t{%2, %0|%0, %2}"
23803 [(set_attr "type" "sseishft")
23804 (set_attr "mode" "TI")])
23806 (define_insn "lshrv2di3"
23807 [(set (match_operand:V2DI 0 "register_operand" "=x")
23808 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23809 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23811 "psrlq\t{%2, %0|%0, %2}"
23812 [(set_attr "type" "sseishft")
23813 (set_attr "mode" "TI")])
23815 (define_insn "ashlv8hi3"
23816 [(set (match_operand:V8HI 0 "register_operand" "=x")
23817 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23818 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23820 "psllw\t{%2, %0|%0, %2}"
23821 [(set_attr "type" "sseishft")
23822 (set_attr "mode" "TI")])
23824 (define_insn "ashlv4si3"
23825 [(set (match_operand:V4SI 0 "register_operand" "=x")
23826 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23827 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23829 "pslld\t{%2, %0|%0, %2}"
23830 [(set_attr "type" "sseishft")
23831 (set_attr "mode" "TI")])
23833 (define_insn "ashlv2di3"
23834 [(set (match_operand:V2DI 0 "register_operand" "=x")
23835 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23836 (match_operand:SI 2 "nonmemory_operand" "xi")))]
23838 "psllq\t{%2, %0|%0, %2}"
23839 [(set_attr "type" "sseishft")
23840 (set_attr "mode" "TI")])
23842 (define_insn "ashrv8hi3_ti"
23843 [(set (match_operand:V8HI 0 "register_operand" "=x")
23844 (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23845 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23847 "psraw\t{%2, %0|%0, %2}"
23848 [(set_attr "type" "sseishft")
23849 (set_attr "mode" "TI")])
23851 (define_insn "ashrv4si3_ti"
23852 [(set (match_operand:V4SI 0 "register_operand" "=x")
23853 (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23854 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23856 "psrad\t{%2, %0|%0, %2}"
23857 [(set_attr "type" "sseishft")
23858 (set_attr "mode" "TI")])
23860 (define_insn "lshrv8hi3_ti"
23861 [(set (match_operand:V8HI 0 "register_operand" "=x")
23862 (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
23863 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23865 "psrlw\t{%2, %0|%0, %2}"
23866 [(set_attr "type" "sseishft")
23867 (set_attr "mode" "TI")])
23869 (define_insn "lshrv4si3_ti"
23870 [(set (match_operand:V4SI 0 "register_operand" "=x")
23871 (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
23872 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23874 "psrld\t{%2, %0|%0, %2}"
23875 [(set_attr "type" "sseishft")
23876 (set_attr "mode" "TI")])
23878 (define_insn "lshrv2di3_ti"
23879 [(set (match_operand:V2DI 0 "register_operand" "=x")
23880 (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
23881 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23883 "psrlq\t{%2, %0|%0, %2}"
23884 [(set_attr "type" "sseishft")
23885 (set_attr "mode" "TI")])
23887 (define_insn "ashlv8hi3_ti"
23888 [(set (match_operand:V8HI 0 "register_operand" "=x")
23889 (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
23890 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23892 "psllw\t{%2, %0|%0, %2}"
23893 [(set_attr "type" "sseishft")
23894 (set_attr "mode" "TI")])
23896 (define_insn "ashlv4si3_ti"
23897 [(set (match_operand:V4SI 0 "register_operand" "=x")
23898 (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
23899 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23901 "pslld\t{%2, %0|%0, %2}"
23902 [(set_attr "type" "sseishft")
23903 (set_attr "mode" "TI")])
23905 (define_insn "ashlv2di3_ti"
23906 [(set (match_operand:V2DI 0 "register_operand" "=x")
23907 (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
23908 (subreg:SI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
23910 "psllq\t{%2, %0|%0, %2}"
23911 [(set_attr "type" "sseishft")
23912 (set_attr "mode" "TI")])
23914 ;; See logical MMX insns for the reason for the unspec. Strictly speaking
23915 ;; we wouldn't need here it since we never generate TImode arithmetic.
23917 ;; There has to be some kind of prize for the weirdest new instruction...
23918 (define_insn "sse2_ashlti3"
23919 [(set (match_operand:TI 0 "register_operand" "=x")
23921 [(ashift:TI (match_operand:TI 1 "register_operand" "0")
23922 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23923 (const_int 8)))] UNSPEC_NOP))]
23925 "pslldq\t{%2, %0|%0, %2}"
23926 [(set_attr "type" "sseishft")
23927 (set_attr "mode" "TI")])
23929 (define_insn "sse2_lshrti3"
23930 [(set (match_operand:TI 0 "register_operand" "=x")
23932 [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
23933 (mult:SI (match_operand:SI 2 "immediate_operand" "i")
23934 (const_int 8)))] UNSPEC_NOP))]
23936 "psrldq\t{%2, %0|%0, %2}"
23937 [(set_attr "type" "sseishft")
23938 (set_attr "mode" "TI")])
23942 (define_insn "sse2_unpckhpd"
23943 [(set (match_operand:V2DF 0 "register_operand" "=x")
23945 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23946 (parallel [(const_int 1)]))
23947 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23948 (parallel [(const_int 1)]))))]
23950 "unpckhpd\t{%2, %0|%0, %2}"
23951 [(set_attr "type" "ssecvt")
23952 (set_attr "mode" "V2DF")])
23954 (define_insn "sse2_unpcklpd"
23955 [(set (match_operand:V2DF 0 "register_operand" "=x")
23957 (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
23958 (parallel [(const_int 0)]))
23959 (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
23960 (parallel [(const_int 0)]))))]
23962 "unpcklpd\t{%2, %0|%0, %2}"
23963 [(set_attr "type" "ssecvt")
23964 (set_attr "mode" "V2DF")])
23966 ;; MMX pack/unpack insns.
23968 (define_insn "sse2_packsswb"
23969 [(set (match_operand:V16QI 0 "register_operand" "=x")
23971 (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23972 (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23974 "packsswb\t{%2, %0|%0, %2}"
23975 [(set_attr "type" "ssecvt")
23976 (set_attr "mode" "TI")])
23978 (define_insn "sse2_packssdw"
23979 [(set (match_operand:V8HI 0 "register_operand" "=x")
23981 (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
23982 (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
23984 "packssdw\t{%2, %0|%0, %2}"
23985 [(set_attr "type" "ssecvt")
23986 (set_attr "mode" "TI")])
23988 (define_insn "sse2_packuswb"
23989 [(set (match_operand:V16QI 0 "register_operand" "=x")
23991 (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
23992 (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
23994 "packuswb\t{%2, %0|%0, %2}"
23995 [(set_attr "type" "ssecvt")
23996 (set_attr "mode" "TI")])
23998 (define_insn "sse2_punpckhbw"
23999 [(set (match_operand:V16QI 0 "register_operand" "=x")
24001 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24002 (parallel [(const_int 8) (const_int 0)
24003 (const_int 9) (const_int 1)
24004 (const_int 10) (const_int 2)
24005 (const_int 11) (const_int 3)
24006 (const_int 12) (const_int 4)
24007 (const_int 13) (const_int 5)
24008 (const_int 14) (const_int 6)
24009 (const_int 15) (const_int 7)]))
24010 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24011 (parallel [(const_int 0) (const_int 8)
24012 (const_int 1) (const_int 9)
24013 (const_int 2) (const_int 10)
24014 (const_int 3) (const_int 11)
24015 (const_int 4) (const_int 12)
24016 (const_int 5) (const_int 13)
24017 (const_int 6) (const_int 14)
24018 (const_int 7) (const_int 15)]))
24019 (const_int 21845)))]
24021 "punpckhbw\t{%2, %0|%0, %2}"
24022 [(set_attr "type" "ssecvt")
24023 (set_attr "mode" "TI")])
24025 (define_insn "sse2_punpckhwd"
24026 [(set (match_operand:V8HI 0 "register_operand" "=x")
24028 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24029 (parallel [(const_int 4) (const_int 0)
24030 (const_int 5) (const_int 1)
24031 (const_int 6) (const_int 2)
24032 (const_int 7) (const_int 3)]))
24033 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24034 (parallel [(const_int 0) (const_int 4)
24035 (const_int 1) (const_int 5)
24036 (const_int 2) (const_int 6)
24037 (const_int 3) (const_int 7)]))
24040 "punpckhwd\t{%2, %0|%0, %2}"
24041 [(set_attr "type" "ssecvt")
24042 (set_attr "mode" "TI")])
24044 (define_insn "sse2_punpckhdq"
24045 [(set (match_operand:V4SI 0 "register_operand" "=x")
24047 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24048 (parallel [(const_int 2) (const_int 0)
24049 (const_int 3) (const_int 1)]))
24050 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24051 (parallel [(const_int 0) (const_int 2)
24052 (const_int 1) (const_int 3)]))
24055 "punpckhdq\t{%2, %0|%0, %2}"
24056 [(set_attr "type" "ssecvt")
24057 (set_attr "mode" "TI")])
24059 (define_insn "sse2_punpcklbw"
24060 [(set (match_operand:V16QI 0 "register_operand" "=x")
24062 (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
24063 (parallel [(const_int 0) (const_int 8)
24064 (const_int 1) (const_int 9)
24065 (const_int 2) (const_int 10)
24066 (const_int 3) (const_int 11)
24067 (const_int 4) (const_int 12)
24068 (const_int 5) (const_int 13)
24069 (const_int 6) (const_int 14)
24070 (const_int 7) (const_int 15)]))
24071 (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
24072 (parallel [(const_int 8) (const_int 0)
24073 (const_int 9) (const_int 1)
24074 (const_int 10) (const_int 2)
24075 (const_int 11) (const_int 3)
24076 (const_int 12) (const_int 4)
24077 (const_int 13) (const_int 5)
24078 (const_int 14) (const_int 6)
24079 (const_int 15) (const_int 7)]))
24080 (const_int 21845)))]
24082 "punpcklbw\t{%2, %0|%0, %2}"
24083 [(set_attr "type" "ssecvt")
24084 (set_attr "mode" "TI")])
24086 (define_insn "sse2_punpcklwd"
24087 [(set (match_operand:V8HI 0 "register_operand" "=x")
24089 (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
24090 (parallel [(const_int 0) (const_int 4)
24091 (const_int 1) (const_int 5)
24092 (const_int 2) (const_int 6)
24093 (const_int 3) (const_int 7)]))
24094 (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
24095 (parallel [(const_int 4) (const_int 0)
24096 (const_int 5) (const_int 1)
24097 (const_int 6) (const_int 2)
24098 (const_int 7) (const_int 3)]))
24101 "punpcklwd\t{%2, %0|%0, %2}"
24102 [(set_attr "type" "ssecvt")
24103 (set_attr "mode" "TI")])
24105 (define_insn "sse2_punpckldq"
24106 [(set (match_operand:V4SI 0 "register_operand" "=x")
24108 (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
24109 (parallel [(const_int 0) (const_int 2)
24110 (const_int 1) (const_int 3)]))
24111 (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
24112 (parallel [(const_int 2) (const_int 0)
24113 (const_int 3) (const_int 1)]))
24116 "punpckldq\t{%2, %0|%0, %2}"
24117 [(set_attr "type" "ssecvt")
24118 (set_attr "mode" "TI")])
24120 (define_insn "sse2_punpcklqdq"
24121 [(set (match_operand:V2DI 0 "register_operand" "=x")
24123 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24124 (parallel [(const_int 1)
24126 (match_operand:V2DI 1 "register_operand" "0")
24129 "punpcklqdq\t{%2, %0|%0, %2}"
24130 [(set_attr "type" "ssecvt")
24131 (set_attr "mode" "TI")])
24133 (define_insn "sse2_punpckhqdq"
24134 [(set (match_operand:V2DI 0 "register_operand" "=x")
24136 (match_operand:V2DI 1 "register_operand" "0")
24137 (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
24138 (parallel [(const_int 1)
24142 "punpckhqdq\t{%2, %0|%0, %2}"
24143 [(set_attr "type" "ssecvt")
24144 (set_attr "mode" "TI")])
24148 (define_insn "sse2_movapd"
24149 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24150 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24153 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24154 "movapd\t{%1, %0|%0, %1}"
24155 [(set_attr "type" "ssemov")
24156 (set_attr "mode" "V2DF")])
24158 (define_insn "sse2_movupd"
24159 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24160 (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
24163 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24164 "movupd\t{%1, %0|%0, %1}"
24165 [(set_attr "type" "ssecvt")
24166 (set_attr "mode" "V2DF")])
24168 (define_insn "sse2_movdqa"
24169 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24170 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24173 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24174 "movdqa\t{%1, %0|%0, %1}"
24175 [(set_attr "type" "ssemov")
24176 (set_attr "mode" "TI")])
24178 (define_insn "sse2_movdqu"
24179 [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
24180 (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
24183 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
24184 "movdqu\t{%1, %0|%0, %1}"
24185 [(set_attr "type" "ssecvt")
24186 (set_attr "mode" "TI")])
24188 (define_insn "sse2_movdq2q"
24189 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
24190 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
24191 (parallel [(const_int 0)])))]
24192 "TARGET_SSE2 && !TARGET_64BIT"
24194 movq\t{%1, %0|%0, %1}
24195 movdq2q\t{%1, %0|%0, %1}"
24196 [(set_attr "type" "ssecvt")
24197 (set_attr "mode" "TI")])
24199 (define_insn "sse2_movdq2q_rex64"
24200 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
24201 (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
24202 (parallel [(const_int 0)])))]
24203 "TARGET_SSE2 && TARGET_64BIT"
24205 movq\t{%1, %0|%0, %1}
24206 movdq2q\t{%1, %0|%0, %1}
24207 movd\t{%1, %0|%0, %1}"
24208 [(set_attr "type" "ssecvt")
24209 (set_attr "mode" "TI")])
24211 (define_insn "sse2_movq2dq"
24212 [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
24213 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
24215 "TARGET_SSE2 && !TARGET_64BIT"
24217 movq\t{%1, %0|%0, %1}
24218 movq2dq\t{%1, %0|%0, %1}"
24219 [(set_attr "type" "ssecvt,ssemov")
24220 (set_attr "mode" "TI")])
24222 (define_insn "sse2_movq2dq_rex64"
24223 [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
24224 (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
24226 "TARGET_SSE2 && TARGET_64BIT"
24228 movq\t{%1, %0|%0, %1}
24229 movq2dq\t{%1, %0|%0, %1}
24230 movd\t{%1, %0|%0, %1}"
24231 [(set_attr "type" "ssecvt,ssemov,ssecvt")
24232 (set_attr "mode" "TI")])
24234 (define_insn "sse2_movq"
24235 [(set (match_operand:V2DI 0 "register_operand" "=x")
24236 (vec_concat:V2DI (vec_select:DI
24237 (match_operand:V2DI 1 "nonimmediate_operand" "xm")
24238 (parallel [(const_int 0)]))
24241 "movq\t{%1, %0|%0, %1}"
24242 [(set_attr "type" "ssemov")
24243 (set_attr "mode" "TI")])
24245 (define_insn "sse2_loadd"
24246 [(set (match_operand:V4SI 0 "register_operand" "=x")
24248 (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
24249 (const_vector:V4SI [(const_int 0)
24255 "movd\t{%1, %0|%0, %1}"
24256 [(set_attr "type" "ssemov")
24257 (set_attr "mode" "TI")])
24259 (define_insn "sse2_stored"
24260 [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
24262 (match_operand:V4SI 1 "register_operand" "x")
24263 (parallel [(const_int 0)])))]
24265 "movd\t{%1, %0|%0, %1}"
24266 [(set_attr "type" "ssemov")
24267 (set_attr "mode" "TI")])
24269 (define_insn "sse2_movhpd"
24270 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
24272 (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
24273 (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
24275 "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
24276 "movhpd\t{%2, %0|%0, %2}"
24277 [(set_attr "type" "ssecvt")
24278 (set_attr "mode" "V2DF")])
24280 (define_expand "sse2_loadsd"
24281 [(match_operand:V2DF 0 "register_operand" "")
24282 (match_operand:DF 1 "memory_operand" "")]
24285 emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
24286 CONST0_RTX (V2DFmode)));
24290 (define_insn "sse2_loadsd_1"
24291 [(set (match_operand:V2DF 0 "register_operand" "=x")
24293 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
24294 (match_operand:V2DF 2 "const0_operand" "X")
24297 "movsd\t{%1, %0|%0, %1}"
24298 [(set_attr "type" "ssecvt")
24299 (set_attr "mode" "DF")])
24301 (define_insn "sse2_movsd"
24302 [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
24304 (match_operand:V2DF 1 "nonimmediate_operand" "0,0,0")
24305 (match_operand:V2DF 2 "nonimmediate_operand" "x,m,x")
24307 "TARGET_SSE2 && ix86_binary_operator_ok (UNKNOWN, V2DFmode, operands)"
24308 "@movsd\t{%2, %0|%0, %2}
24309 movlpd\t{%2, %0|%0, %2}
24310 movlpd\t{%2, %0|%0, %2}"
24311 [(set_attr "type" "ssecvt")
24312 (set_attr "mode" "DF,V2DF,V2DF")])
24314 (define_insn "sse2_storesd"
24315 [(set (match_operand:DF 0 "memory_operand" "=m")
24317 (match_operand:V2DF 1 "register_operand" "x")
24318 (parallel [(const_int 0)])))]
24320 "movsd\t{%1, %0|%0, %1}"
24321 [(set_attr "type" "ssecvt")
24322 (set_attr "mode" "DF")])
24324 (define_insn "sse2_shufpd"
24325 [(set (match_operand:V2DF 0 "register_operand" "=x")
24326 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24327 (match_operand:V2DF 2 "nonimmediate_operand" "xm")
24328 (match_operand:SI 3 "immediate_operand" "i")]
24331 ;; @@@ check operand order for intel/nonintel syntax
24332 "shufpd\t{%3, %2, %0|%0, %2, %3}"
24333 [(set_attr "type" "ssecvt")
24334 (set_attr "mode" "V2DF")])
24336 (define_insn "sse2_clflush"
24337 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
24341 [(set_attr "type" "sse")
24342 (set_attr "memory" "unknown")])
24344 (define_expand "sse2_mfence"
24345 [(set (match_dup 0)
24346 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24349 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24350 MEM_VOLATILE_P (operands[0]) = 1;
24353 (define_insn "*mfence_insn"
24354 [(set (match_operand:BLK 0 "" "")
24355 (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
24358 [(set_attr "type" "sse")
24359 (set_attr "memory" "unknown")])
24361 (define_expand "sse2_lfence"
24362 [(set (match_dup 0)
24363 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24366 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
24367 MEM_VOLATILE_P (operands[0]) = 1;
24370 (define_insn "*lfence_insn"
24371 [(set (match_operand:BLK 0 "" "")
24372 (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
24375 [(set_attr "type" "sse")
24376 (set_attr "memory" "unknown")])
24380 (define_insn "mwait"
24381 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24382 (match_operand:SI 1 "register_operand" "c")]
24386 [(set_attr "length" "3")])
24388 (define_insn "monitor"
24389 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
24390 (match_operand:SI 1 "register_operand" "c")
24391 (match_operand:SI 2 "register_operand" "d")]
24394 "monitor\t%0, %1, %2"
24395 [(set_attr "length" "3")])
24399 (define_insn "addsubv4sf3"
24400 [(set (match_operand:V4SF 0 "register_operand" "=x")
24401 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24402 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24405 "addsubps\t{%2, %0|%0, %2}"
24406 [(set_attr "type" "sseadd")
24407 (set_attr "mode" "V4SF")])
24409 (define_insn "addsubv2df3"
24410 [(set (match_operand:V2DF 0 "register_operand" "=x")
24411 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24412 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24415 "addsubpd\t{%2, %0|%0, %2}"
24416 [(set_attr "type" "sseadd")
24417 (set_attr "mode" "V2DF")])
24419 (define_insn "haddv4sf3"
24420 [(set (match_operand:V4SF 0 "register_operand" "=x")
24421 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24422 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24425 "haddps\t{%2, %0|%0, %2}"
24426 [(set_attr "type" "sseadd")
24427 (set_attr "mode" "V4SF")])
24429 (define_insn "haddv2df3"
24430 [(set (match_operand:V2DF 0 "register_operand" "=x")
24431 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24432 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24435 "haddpd\t{%2, %0|%0, %2}"
24436 [(set_attr "type" "sseadd")
24437 (set_attr "mode" "V2DF")])
24439 (define_insn "hsubv4sf3"
24440 [(set (match_operand:V4SF 0 "register_operand" "=x")
24441 (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
24442 (match_operand:V4SF 2 "nonimmediate_operand" "xm")]
24445 "hsubps\t{%2, %0|%0, %2}"
24446 [(set_attr "type" "sseadd")
24447 (set_attr "mode" "V4SF")])
24449 (define_insn "hsubv2df3"
24450 [(set (match_operand:V2DF 0 "register_operand" "=x")
24451 (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
24452 (match_operand:V2DF 2 "nonimmediate_operand" "xm")]
24455 "hsubpd\t{%2, %0|%0, %2}"
24456 [(set_attr "type" "sseadd")
24457 (set_attr "mode" "V2DF")])
24459 (define_insn "movshdup"
24460 [(set (match_operand:V4SF 0 "register_operand" "=x")
24462 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSHDUP))]
24464 "movshdup\t{%1, %0|%0, %1}"
24465 [(set_attr "type" "sse")
24466 (set_attr "mode" "V4SF")])
24468 (define_insn "movsldup"
24469 [(set (match_operand:V4SF 0 "register_operand" "=x")
24471 [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_MOVSLDUP))]
24473 "movsldup\t{%1, %0|%0, %1}"
24474 [(set_attr "type" "sse")
24475 (set_attr "mode" "V4SF")])
24477 (define_insn "lddqu"
24478 [(set (match_operand:V16QI 0 "register_operand" "=x")
24479 (unspec:V16QI [(match_operand:V16QI 1 "memory_operand" "m")]
24482 "lddqu\t{%1, %0|%0, %1}"
24483 [(set_attr "type" "ssecvt")
24484 (set_attr "mode" "TI")])
24486 (define_insn "loadddup"
24487 [(set (match_operand:V2DF 0 "register_operand" "=x")
24488 (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m")))]
24490 "movddup\t{%1, %0|%0, %1}"
24491 [(set_attr "type" "ssecvt")
24492 (set_attr "mode" "DF")])
24494 (define_insn "movddup"
24495 [(set (match_operand:V2DF 0 "register_operand" "=x")
24496 (vec_duplicate:V2DF
24497 (vec_select:DF (match_operand:V2DF 1 "register_operand" "x")
24498 (parallel [(const_int 0)]))))]
24500 "movddup\t{%1, %0|%0, %1}"
24501 [(set_attr "type" "ssecvt")
24502 (set_attr "mode" "DF")])