1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
77 ; Other random patterns
87 ; For SSE/MMX support:
88 (UNSPEC_FIX_NOTRUNC 30)
96 (UNSPEC_NOP 38) ; prevents combiner cleverness
107 ; Generic math support
109 (UNSPEC_IEEE_MIN 51) ; not commutative
110 (UNSPEC_IEEE_MAX 52) ; not commutative
123 (UNSPEC_FRNDINT_FLOOR 70)
124 (UNSPEC_FRNDINT_CEIL 71)
125 (UNSPEC_FRNDINT_TRUNC 72)
126 (UNSPEC_FRNDINT_MASK_PM 73)
127 (UNSPEC_FIST_FLOOR 74)
128 (UNSPEC_FIST_CEIL 75)
130 ; x87 Double output FP
131 (UNSPEC_SINCOS_COS 80)
132 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_XTRACT_FRACT 84)
136 (UNSPEC_XTRACT_EXP 85)
137 (UNSPEC_FSCALE_FRACT 86)
138 (UNSPEC_FSCALE_EXP 87)
147 (UNSPEC_SP_TLS_SET 102)
148 (UNSPEC_SP_TLS_TEST 103)
152 [(UNSPECV_BLOCKAGE 0)
153 (UNSPECV_STACK_PROBE 1)
162 (UNSPECV_CMPXCHG_1 10)
163 (UNSPECV_CMPXCHG_2 11)
168 ;; Registers by name.
177 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; In C guard expressions, put expressions which may be compile-time
181 ;; constants first. This allows for better optimization. For
182 ;; example, write "TARGET_64BIT && reload_completed", not
183 ;; "reload_completed && TARGET_64BIT".
186 ;; Processor type. This attribute must exactly match the processor_type
187 ;; enumeration in i386.h.
188 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
189 (const (symbol_ref "ix86_tune")))
191 ;; A basic instruction type. Refinements due to arguments to be
192 ;; provided in other attributes.
195 alu,alu1,negnot,imov,imovx,lea,
196 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
197 icmp,test,ibr,setcc,icmov,
198 push,pop,call,callv,leave,
200 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
201 sselog,sselog1,sseiadd,sseishft,sseimul,
202 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
203 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
204 (const_string "other"))
206 ;; Main data type used by the insn
208 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
209 (const_string "unknown"))
211 ;; The CPU unit operations uses.
212 (define_attr "unit" "integer,i387,sse,mmx,unknown"
213 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
214 (const_string "i387")
215 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
216 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
218 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
220 (eq_attr "type" "other")
221 (const_string "unknown")]
222 (const_string "integer")))
224 ;; The (bounding maximum) length of an instruction immediate.
225 (define_attr "length_immediate" ""
226 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
228 (eq_attr "unit" "i387,sse,mmx")
230 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
232 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
233 (eq_attr "type" "imov,test")
234 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
235 (eq_attr "type" "call")
236 (if_then_else (match_operand 0 "constant_call_address_operand" "")
239 (eq_attr "type" "callv")
240 (if_then_else (match_operand 1 "constant_call_address_operand" "")
243 ;; We don't know the size before shorten_branches. Expect
244 ;; the instruction to fit for better scheduling.
245 (eq_attr "type" "ibr")
248 (symbol_ref "/* Update immediate_length and other attributes! */
249 gcc_unreachable (),1")))
251 ;; The (bounding maximum) length of an instruction address.
252 (define_attr "length_address" ""
253 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
255 (and (eq_attr "type" "call")
256 (match_operand 0 "constant_call_address_operand" ""))
258 (and (eq_attr "type" "callv")
259 (match_operand 1 "constant_call_address_operand" ""))
262 (symbol_ref "ix86_attr_length_address_default (insn)")))
264 ;; Set when length prefix is used.
265 (define_attr "prefix_data16" ""
266 (if_then_else (ior (eq_attr "mode" "HI")
267 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
271 ;; Set when string REP prefix is used.
272 (define_attr "prefix_rep" ""
273 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
277 ;; Set when 0f opcode prefix is used.
278 (define_attr "prefix_0f" ""
280 (ior (eq_attr "type" "imovx,setcc,icmov")
281 (eq_attr "unit" "sse,mmx"))
285 ;; Set when REX opcode prefix is used.
286 (define_attr "prefix_rex" ""
287 (cond [(and (eq_attr "mode" "DI")
288 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
290 (and (eq_attr "mode" "QI")
291 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
300 ;; Set when modrm byte is used.
301 (define_attr "modrm" ""
302 (cond [(eq_attr "type" "str,cld,leave")
304 (eq_attr "unit" "i387")
306 (and (eq_attr "type" "incdec")
307 (ior (match_operand:SI 1 "register_operand" "")
308 (match_operand:HI 1 "register_operand" "")))
310 (and (eq_attr "type" "push")
311 (not (match_operand 1 "memory_operand" "")))
313 (and (eq_attr "type" "pop")
314 (not (match_operand 0 "memory_operand" "")))
316 (and (eq_attr "type" "imov")
317 (ior (and (match_operand 0 "register_operand" "")
318 (match_operand 1 "immediate_operand" ""))
319 (ior (and (match_operand 0 "ax_reg_operand" "")
320 (match_operand 1 "memory_displacement_only_operand" ""))
321 (and (match_operand 0 "memory_displacement_only_operand" "")
322 (match_operand 1 "ax_reg_operand" "")))))
324 (and (eq_attr "type" "call")
325 (match_operand 0 "constant_call_address_operand" ""))
327 (and (eq_attr "type" "callv")
328 (match_operand 1 "constant_call_address_operand" ""))
333 ;; The (bounding maximum) length of an instruction in bytes.
334 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
335 ;; Later we may want to split them and compute proper length as for
337 (define_attr "length" ""
338 (cond [(eq_attr "type" "other,multi,fistp,frndint")
340 (eq_attr "type" "fcmp")
342 (eq_attr "unit" "i387")
344 (plus (attr "prefix_data16")
345 (attr "length_address")))]
346 (plus (plus (attr "modrm")
347 (plus (attr "prefix_0f")
348 (plus (attr "prefix_rex")
350 (plus (attr "prefix_rep")
351 (plus (attr "prefix_data16")
352 (plus (attr "length_immediate")
353 (attr "length_address")))))))
355 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
356 ;; `store' if there is a simple memory reference therein, or `unknown'
357 ;; if the instruction is complex.
359 (define_attr "memory" "none,load,store,both,unknown"
360 (cond [(eq_attr "type" "other,multi,str")
361 (const_string "unknown")
362 (eq_attr "type" "lea,fcmov,fpspc,cld")
363 (const_string "none")
364 (eq_attr "type" "fistp,leave")
365 (const_string "both")
366 (eq_attr "type" "frndint")
367 (const_string "load")
368 (eq_attr "type" "push")
369 (if_then_else (match_operand 1 "memory_operand" "")
370 (const_string "both")
371 (const_string "store"))
372 (eq_attr "type" "pop")
373 (if_then_else (match_operand 0 "memory_operand" "")
374 (const_string "both")
375 (const_string "load"))
376 (eq_attr "type" "setcc")
377 (if_then_else (match_operand 0 "memory_operand" "")
378 (const_string "store")
379 (const_string "none"))
380 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
381 (if_then_else (ior (match_operand 0 "memory_operand" "")
382 (match_operand 1 "memory_operand" ""))
383 (const_string "load")
384 (const_string "none"))
385 (eq_attr "type" "ibr")
386 (if_then_else (match_operand 0 "memory_operand" "")
387 (const_string "load")
388 (const_string "none"))
389 (eq_attr "type" "call")
390 (if_then_else (match_operand 0 "constant_call_address_operand" "")
391 (const_string "none")
392 (const_string "load"))
393 (eq_attr "type" "callv")
394 (if_then_else (match_operand 1 "constant_call_address_operand" "")
395 (const_string "none")
396 (const_string "load"))
397 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
398 (match_operand 1 "memory_operand" ""))
399 (const_string "both")
400 (and (match_operand 0 "memory_operand" "")
401 (match_operand 1 "memory_operand" ""))
402 (const_string "both")
403 (match_operand 0 "memory_operand" "")
404 (const_string "store")
405 (match_operand 1 "memory_operand" "")
406 (const_string "load")
408 "!alu1,negnot,ishift1,
409 imov,imovx,icmp,test,
411 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
412 mmx,mmxmov,mmxcmp,mmxcvt")
413 (match_operand 2 "memory_operand" ""))
414 (const_string "load")
415 (and (eq_attr "type" "icmov")
416 (match_operand 3 "memory_operand" ""))
417 (const_string "load")
419 (const_string "none")))
421 ;; Indicates if an instruction has both an immediate and a displacement.
423 (define_attr "imm_disp" "false,true,unknown"
424 (cond [(eq_attr "type" "other,multi")
425 (const_string "unknown")
426 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
427 (and (match_operand 0 "memory_displacement_operand" "")
428 (match_operand 1 "immediate_operand" "")))
429 (const_string "true")
430 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
431 (and (match_operand 0 "memory_displacement_operand" "")
432 (match_operand 2 "immediate_operand" "")))
433 (const_string "true")
435 (const_string "false")))
437 ;; Indicates if an FP operation has an integer source.
439 (define_attr "fp_int_src" "false,true"
440 (const_string "false"))
442 ;; Defines rounding mode of an FP operation.
444 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
445 (const_string "any"))
447 ;; Describe a user's asm statement.
448 (define_asm_attributes
449 [(set_attr "length" "128")
450 (set_attr "type" "multi")])
452 ;; All x87 floating point modes
453 (define_mode_macro X87MODEF [SF DF XF])
455 ;; All integer modes handled by x87 fisttp operator.
456 (define_mode_macro X87MODEI [HI SI DI])
458 ;; All integer modes handled by integer x87 operators.
459 (define_mode_macro X87MODEI12 [HI SI])
461 ;; All SSE floating point modes
462 (define_mode_macro SSEMODEF [SF DF])
464 ;; All integer modes handled by SSE cvtts?2si* operators.
465 (define_mode_macro SSEMODEI24 [SI DI])
468 ;; Scheduling descriptions
470 (include "pentium.md")
473 (include "athlon.md")
476 ;; Operand and operator predicates
478 (include "predicates.md")
481 ;; Compare instructions.
483 ;; All compare insns have expanders that save the operands away without
484 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
485 ;; after the cmp) will actually emit the cmpM.
487 (define_expand "cmpti"
488 [(set (reg:CC FLAGS_REG)
489 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
490 (match_operand:TI 1 "x86_64_general_operand" "")))]
493 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494 operands[0] = force_reg (TImode, operands[0]);
495 ix86_compare_op0 = operands[0];
496 ix86_compare_op1 = operands[1];
500 (define_expand "cmpdi"
501 [(set (reg:CC FLAGS_REG)
502 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
503 (match_operand:DI 1 "x86_64_general_operand" "")))]
506 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507 operands[0] = force_reg (DImode, operands[0]);
508 ix86_compare_op0 = operands[0];
509 ix86_compare_op1 = operands[1];
513 (define_expand "cmpsi"
514 [(set (reg:CC FLAGS_REG)
515 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
516 (match_operand:SI 1 "general_operand" "")))]
519 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
520 operands[0] = force_reg (SImode, operands[0]);
521 ix86_compare_op0 = operands[0];
522 ix86_compare_op1 = operands[1];
526 (define_expand "cmphi"
527 [(set (reg:CC FLAGS_REG)
528 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
529 (match_operand:HI 1 "general_operand" "")))]
532 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
533 operands[0] = force_reg (HImode, operands[0]);
534 ix86_compare_op0 = operands[0];
535 ix86_compare_op1 = operands[1];
539 (define_expand "cmpqi"
540 [(set (reg:CC FLAGS_REG)
541 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
542 (match_operand:QI 1 "general_operand" "")))]
545 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
546 operands[0] = force_reg (QImode, operands[0]);
547 ix86_compare_op0 = operands[0];
548 ix86_compare_op1 = operands[1];
552 (define_insn "cmpdi_ccno_1_rex64"
553 [(set (reg FLAGS_REG)
554 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
555 (match_operand:DI 1 "const0_operand" "n,n")))]
556 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
558 test{q}\t{%0, %0|%0, %0}
559 cmp{q}\t{%1, %0|%0, %1}"
560 [(set_attr "type" "test,icmp")
561 (set_attr "length_immediate" "0,1")
562 (set_attr "mode" "DI")])
564 (define_insn "*cmpdi_minus_1_rex64"
565 [(set (reg FLAGS_REG)
566 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
567 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
569 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
570 "cmp{q}\t{%1, %0|%0, %1}"
571 [(set_attr "type" "icmp")
572 (set_attr "mode" "DI")])
574 (define_expand "cmpdi_1_rex64"
575 [(set (reg:CC FLAGS_REG)
576 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
577 (match_operand:DI 1 "general_operand" "")))]
581 (define_insn "cmpdi_1_insn_rex64"
582 [(set (reg FLAGS_REG)
583 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
584 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
585 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
586 "cmp{q}\t{%1, %0|%0, %1}"
587 [(set_attr "type" "icmp")
588 (set_attr "mode" "DI")])
591 (define_insn "*cmpsi_ccno_1"
592 [(set (reg FLAGS_REG)
593 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
594 (match_operand:SI 1 "const0_operand" "n,n")))]
595 "ix86_match_ccmode (insn, CCNOmode)"
597 test{l}\t{%0, %0|%0, %0}
598 cmp{l}\t{%1, %0|%0, %1}"
599 [(set_attr "type" "test,icmp")
600 (set_attr "length_immediate" "0,1")
601 (set_attr "mode" "SI")])
603 (define_insn "*cmpsi_minus_1"
604 [(set (reg FLAGS_REG)
605 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
606 (match_operand:SI 1 "general_operand" "ri,mr"))
608 "ix86_match_ccmode (insn, CCGOCmode)"
609 "cmp{l}\t{%1, %0|%0, %1}"
610 [(set_attr "type" "icmp")
611 (set_attr "mode" "SI")])
613 (define_expand "cmpsi_1"
614 [(set (reg:CC FLAGS_REG)
615 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
616 (match_operand:SI 1 "general_operand" "ri,mr")))]
620 (define_insn "*cmpsi_1_insn"
621 [(set (reg FLAGS_REG)
622 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623 (match_operand:SI 1 "general_operand" "ri,mr")))]
624 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
625 && ix86_match_ccmode (insn, CCmode)"
626 "cmp{l}\t{%1, %0|%0, %1}"
627 [(set_attr "type" "icmp")
628 (set_attr "mode" "SI")])
630 (define_insn "*cmphi_ccno_1"
631 [(set (reg FLAGS_REG)
632 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
633 (match_operand:HI 1 "const0_operand" "n,n")))]
634 "ix86_match_ccmode (insn, CCNOmode)"
636 test{w}\t{%0, %0|%0, %0}
637 cmp{w}\t{%1, %0|%0, %1}"
638 [(set_attr "type" "test,icmp")
639 (set_attr "length_immediate" "0,1")
640 (set_attr "mode" "HI")])
642 (define_insn "*cmphi_minus_1"
643 [(set (reg FLAGS_REG)
644 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
645 (match_operand:HI 1 "general_operand" "ri,mr"))
647 "ix86_match_ccmode (insn, CCGOCmode)"
648 "cmp{w}\t{%1, %0|%0, %1}"
649 [(set_attr "type" "icmp")
650 (set_attr "mode" "HI")])
652 (define_insn "*cmphi_1"
653 [(set (reg FLAGS_REG)
654 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
655 (match_operand:HI 1 "general_operand" "ri,mr")))]
656 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
657 && ix86_match_ccmode (insn, CCmode)"
658 "cmp{w}\t{%1, %0|%0, %1}"
659 [(set_attr "type" "icmp")
660 (set_attr "mode" "HI")])
662 (define_insn "*cmpqi_ccno_1"
663 [(set (reg FLAGS_REG)
664 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
665 (match_operand:QI 1 "const0_operand" "n,n")))]
666 "ix86_match_ccmode (insn, CCNOmode)"
668 test{b}\t{%0, %0|%0, %0}
669 cmp{b}\t{$0, %0|%0, 0}"
670 [(set_attr "type" "test,icmp")
671 (set_attr "length_immediate" "0,1")
672 (set_attr "mode" "QI")])
674 (define_insn "*cmpqi_1"
675 [(set (reg FLAGS_REG)
676 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
677 (match_operand:QI 1 "general_operand" "qi,mq")))]
678 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
679 && ix86_match_ccmode (insn, CCmode)"
680 "cmp{b}\t{%1, %0|%0, %1}"
681 [(set_attr "type" "icmp")
682 (set_attr "mode" "QI")])
684 (define_insn "*cmpqi_minus_1"
685 [(set (reg FLAGS_REG)
686 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
687 (match_operand:QI 1 "general_operand" "qi,mq"))
689 "ix86_match_ccmode (insn, CCGOCmode)"
690 "cmp{b}\t{%1, %0|%0, %1}"
691 [(set_attr "type" "icmp")
692 (set_attr "mode" "QI")])
694 (define_insn "*cmpqi_ext_1"
695 [(set (reg FLAGS_REG)
697 (match_operand:QI 0 "general_operand" "Qm")
700 (match_operand 1 "ext_register_operand" "Q")
703 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
704 "cmp{b}\t{%h1, %0|%0, %h1}"
705 [(set_attr "type" "icmp")
706 (set_attr "mode" "QI")])
708 (define_insn "*cmpqi_ext_1_rex64"
709 [(set (reg FLAGS_REG)
711 (match_operand:QI 0 "register_operand" "Q")
714 (match_operand 1 "ext_register_operand" "Q")
717 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
718 "cmp{b}\t{%h1, %0|%0, %h1}"
719 [(set_attr "type" "icmp")
720 (set_attr "mode" "QI")])
722 (define_insn "*cmpqi_ext_2"
723 [(set (reg FLAGS_REG)
727 (match_operand 0 "ext_register_operand" "Q")
730 (match_operand:QI 1 "const0_operand" "n")))]
731 "ix86_match_ccmode (insn, CCNOmode)"
733 [(set_attr "type" "test")
734 (set_attr "length_immediate" "0")
735 (set_attr "mode" "QI")])
737 (define_expand "cmpqi_ext_3"
738 [(set (reg:CC FLAGS_REG)
742 (match_operand 0 "ext_register_operand" "")
745 (match_operand:QI 1 "general_operand" "")))]
749 (define_insn "cmpqi_ext_3_insn"
750 [(set (reg FLAGS_REG)
754 (match_operand 0 "ext_register_operand" "Q")
757 (match_operand:QI 1 "general_operand" "Qmn")))]
758 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
759 "cmp{b}\t{%1, %h0|%h0, %1}"
760 [(set_attr "type" "icmp")
761 (set_attr "mode" "QI")])
763 (define_insn "cmpqi_ext_3_insn_rex64"
764 [(set (reg FLAGS_REG)
768 (match_operand 0 "ext_register_operand" "Q")
771 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
772 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
773 "cmp{b}\t{%1, %h0|%h0, %1}"
774 [(set_attr "type" "icmp")
775 (set_attr "mode" "QI")])
777 (define_insn "*cmpqi_ext_4"
778 [(set (reg FLAGS_REG)
782 (match_operand 0 "ext_register_operand" "Q")
787 (match_operand 1 "ext_register_operand" "Q")
790 "ix86_match_ccmode (insn, CCmode)"
791 "cmp{b}\t{%h1, %h0|%h0, %h1}"
792 [(set_attr "type" "icmp")
793 (set_attr "mode" "QI")])
795 ;; These implement float point compares.
796 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
797 ;; which would allow mix and match FP modes on the compares. Which is what
798 ;; the old patterns did, but with many more of them.
800 (define_expand "cmpxf"
801 [(set (reg:CC FLAGS_REG)
802 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
803 (match_operand:XF 1 "nonmemory_operand" "")))]
806 ix86_compare_op0 = operands[0];
807 ix86_compare_op1 = operands[1];
811 (define_expand "cmpdf"
812 [(set (reg:CC FLAGS_REG)
813 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
814 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
815 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
817 ix86_compare_op0 = operands[0];
818 ix86_compare_op1 = operands[1];
822 (define_expand "cmpsf"
823 [(set (reg:CC FLAGS_REG)
824 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
825 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
826 "TARGET_80387 || TARGET_SSE_MATH"
828 ix86_compare_op0 = operands[0];
829 ix86_compare_op1 = operands[1];
833 ;; FP compares, step 1:
834 ;; Set the FP condition codes.
836 ;; CCFPmode compare with exceptions
837 ;; CCFPUmode compare with no exceptions
839 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
840 ;; used to manage the reg stack popping would not be preserved.
842 (define_insn "*cmpfp_0"
843 [(set (match_operand:HI 0 "register_operand" "=a")
846 (match_operand 1 "register_operand" "f")
847 (match_operand 2 "const0_operand" "X"))]
850 && FLOAT_MODE_P (GET_MODE (operands[1]))
851 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
852 "* return output_fp_compare (insn, operands, 0, 0);"
853 [(set_attr "type" "multi")
854 (set_attr "unit" "i387")
856 (cond [(match_operand:SF 1 "" "")
858 (match_operand:DF 1 "" "")
861 (const_string "XF")))])
863 (define_insn "*cmpfp_sf"
864 [(set (match_operand:HI 0 "register_operand" "=a")
867 (match_operand:SF 1 "register_operand" "f")
868 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
871 "* return output_fp_compare (insn, operands, 0, 0);"
872 [(set_attr "type" "multi")
873 (set_attr "unit" "i387")
874 (set_attr "mode" "SF")])
876 (define_insn "*cmpfp_df"
877 [(set (match_operand:HI 0 "register_operand" "=a")
880 (match_operand:DF 1 "register_operand" "f")
881 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
884 "* return output_fp_compare (insn, operands, 0, 0);"
885 [(set_attr "type" "multi")
886 (set_attr "unit" "i387")
887 (set_attr "mode" "DF")])
889 (define_insn "*cmpfp_xf"
890 [(set (match_operand:HI 0 "register_operand" "=a")
893 (match_operand:XF 1 "register_operand" "f")
894 (match_operand:XF 2 "register_operand" "f"))]
897 "* return output_fp_compare (insn, operands, 0, 0);"
898 [(set_attr "type" "multi")
899 (set_attr "unit" "i387")
900 (set_attr "mode" "XF")])
902 (define_insn "*cmpfp_u"
903 [(set (match_operand:HI 0 "register_operand" "=a")
906 (match_operand 1 "register_operand" "f")
907 (match_operand 2 "register_operand" "f"))]
910 && FLOAT_MODE_P (GET_MODE (operands[1]))
911 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
912 "* return output_fp_compare (insn, operands, 0, 1);"
913 [(set_attr "type" "multi")
914 (set_attr "unit" "i387")
916 (cond [(match_operand:SF 1 "" "")
918 (match_operand:DF 1 "" "")
921 (const_string "XF")))])
923 (define_insn "*cmpfp_<mode>"
924 [(set (match_operand:HI 0 "register_operand" "=a")
927 (match_operand 1 "register_operand" "f")
928 (match_operator 3 "float_operator"
929 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
931 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
932 && FLOAT_MODE_P (GET_MODE (operands[1]))
933 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
934 "* return output_fp_compare (insn, operands, 0, 0);"
935 [(set_attr "type" "multi")
936 (set_attr "unit" "i387")
937 (set_attr "fp_int_src" "true")
938 (set_attr "mode" "<MODE>")])
940 ;; FP compares, step 2
941 ;; Move the fpsw to ax.
943 (define_insn "x86_fnstsw_1"
944 [(set (match_operand:HI 0 "register_operand" "=a")
945 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
948 [(set_attr "length" "2")
949 (set_attr "mode" "SI")
950 (set_attr "unit" "i387")])
952 ;; FP compares, step 3
953 ;; Get ax into flags, general case.
955 (define_insn "x86_sahf_1"
956 [(set (reg:CC FLAGS_REG)
957 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
960 [(set_attr "length" "1")
961 (set_attr "athlon_decode" "vector")
962 (set_attr "mode" "SI")])
964 ;; Pentium Pro can do steps 1 through 3 in one go.
966 (define_insn "*cmpfp_i_mixed"
967 [(set (reg:CCFP FLAGS_REG)
968 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
969 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
971 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
972 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
973 "* return output_fp_compare (insn, operands, 1, 0);"
974 [(set_attr "type" "fcmp,ssecomi")
976 (if_then_else (match_operand:SF 1 "" "")
978 (const_string "DF")))
979 (set_attr "athlon_decode" "vector")])
981 (define_insn "*cmpfp_i_sse"
982 [(set (reg:CCFP FLAGS_REG)
983 (compare:CCFP (match_operand 0 "register_operand" "x")
984 (match_operand 1 "nonimmediate_operand" "xm")))]
986 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
987 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
988 "* return output_fp_compare (insn, operands, 1, 0);"
989 [(set_attr "type" "ssecomi")
991 (if_then_else (match_operand:SF 1 "" "")
993 (const_string "DF")))
994 (set_attr "athlon_decode" "vector")])
996 (define_insn "*cmpfp_i_i387"
997 [(set (reg:CCFP FLAGS_REG)
998 (compare:CCFP (match_operand 0 "register_operand" "f")
999 (match_operand 1 "register_operand" "f")))]
1000 "TARGET_80387 && TARGET_CMOVE
1001 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1002 && FLOAT_MODE_P (GET_MODE (operands[0]))
1003 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1004 "* return output_fp_compare (insn, operands, 1, 0);"
1005 [(set_attr "type" "fcmp")
1007 (cond [(match_operand:SF 1 "" "")
1009 (match_operand:DF 1 "" "")
1012 (const_string "XF")))
1013 (set_attr "athlon_decode" "vector")])
1015 (define_insn "*cmpfp_iu_mixed"
1016 [(set (reg:CCFPU FLAGS_REG)
1017 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1018 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1019 "TARGET_MIX_SSE_I387
1020 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022 "* return output_fp_compare (insn, operands, 1, 1);"
1023 [(set_attr "type" "fcmp,ssecomi")
1025 (if_then_else (match_operand:SF 1 "" "")
1027 (const_string "DF")))
1028 (set_attr "athlon_decode" "vector")])
1030 (define_insn "*cmpfp_iu_sse"
1031 [(set (reg:CCFPU FLAGS_REG)
1032 (compare:CCFPU (match_operand 0 "register_operand" "x")
1033 (match_operand 1 "nonimmediate_operand" "xm")))]
1035 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1036 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1037 "* return output_fp_compare (insn, operands, 1, 1);"
1038 [(set_attr "type" "ssecomi")
1040 (if_then_else (match_operand:SF 1 "" "")
1042 (const_string "DF")))
1043 (set_attr "athlon_decode" "vector")])
1045 (define_insn "*cmpfp_iu_387"
1046 [(set (reg:CCFPU FLAGS_REG)
1047 (compare:CCFPU (match_operand 0 "register_operand" "f")
1048 (match_operand 1 "register_operand" "f")))]
1049 "TARGET_80387 && TARGET_CMOVE
1050 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1051 && FLOAT_MODE_P (GET_MODE (operands[0]))
1052 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1053 "* return output_fp_compare (insn, operands, 1, 1);"
1054 [(set_attr "type" "fcmp")
1056 (cond [(match_operand:SF 1 "" "")
1058 (match_operand:DF 1 "" "")
1061 (const_string "XF")))
1062 (set_attr "athlon_decode" "vector")])
1064 ;; Move instructions.
1066 ;; General case of fullword move.
1068 (define_expand "movsi"
1069 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1070 (match_operand:SI 1 "general_operand" ""))]
1072 "ix86_expand_move (SImode, operands); DONE;")
1074 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1077 ;; %%% We don't use a post-inc memory reference because x86 is not a
1078 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1079 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1080 ;; targets without our curiosities, and it is just as easy to represent
1081 ;; this differently.
1083 (define_insn "*pushsi2"
1084 [(set (match_operand:SI 0 "push_operand" "=<")
1085 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1088 [(set_attr "type" "push")
1089 (set_attr "mode" "SI")])
1091 ;; For 64BIT abi we always round up to 8 bytes.
1092 (define_insn "*pushsi2_rex64"
1093 [(set (match_operand:SI 0 "push_operand" "=X")
1094 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1097 [(set_attr "type" "push")
1098 (set_attr "mode" "SI")])
1100 (define_insn "*pushsi2_prologue"
1101 [(set (match_operand:SI 0 "push_operand" "=<")
1102 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1103 (clobber (mem:BLK (scratch)))]
1106 [(set_attr "type" "push")
1107 (set_attr "mode" "SI")])
1109 (define_insn "*popsi1_epilogue"
1110 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1111 (mem:SI (reg:SI SP_REG)))
1112 (set (reg:SI SP_REG)
1113 (plus:SI (reg:SI SP_REG) (const_int 4)))
1114 (clobber (mem:BLK (scratch)))]
1117 [(set_attr "type" "pop")
1118 (set_attr "mode" "SI")])
1120 (define_insn "popsi1"
1121 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122 (mem:SI (reg:SI SP_REG)))
1123 (set (reg:SI SP_REG)
1124 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1127 [(set_attr "type" "pop")
1128 (set_attr "mode" "SI")])
1130 (define_insn "*movsi_xor"
1131 [(set (match_operand:SI 0 "register_operand" "=r")
1132 (match_operand:SI 1 "const0_operand" "i"))
1133 (clobber (reg:CC FLAGS_REG))]
1134 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1135 "xor{l}\t{%0, %0|%0, %0}"
1136 [(set_attr "type" "alu1")
1137 (set_attr "mode" "SI")
1138 (set_attr "length_immediate" "0")])
1140 (define_insn "*movsi_or"
1141 [(set (match_operand:SI 0 "register_operand" "=r")
1142 (match_operand:SI 1 "immediate_operand" "i"))
1143 (clobber (reg:CC FLAGS_REG))]
1145 && operands[1] == constm1_rtx
1146 && (TARGET_PENTIUM || optimize_size)"
1148 operands[1] = constm1_rtx;
1149 return "or{l}\t{%1, %0|%0, %1}";
1151 [(set_attr "type" "alu1")
1152 (set_attr "mode" "SI")
1153 (set_attr "length_immediate" "1")])
1155 (define_insn "*movsi_1"
1156 [(set (match_operand:SI 0 "nonimmediate_operand"
1157 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1158 (match_operand:SI 1 "general_operand"
1159 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1160 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1162 switch (get_attr_type (insn))
1165 if (get_attr_mode (insn) == MODE_TI)
1166 return "pxor\t%0, %0";
1167 return "xorps\t%0, %0";
1170 switch (get_attr_mode (insn))
1173 return "movdqa\t{%1, %0|%0, %1}";
1175 return "movaps\t{%1, %0|%0, %1}";
1177 return "movd\t{%1, %0|%0, %1}";
1179 return "movss\t{%1, %0|%0, %1}";
1185 return "pxor\t%0, %0";
1188 if (get_attr_mode (insn) == MODE_DI)
1189 return "movq\t{%1, %0|%0, %1}";
1190 return "movd\t{%1, %0|%0, %1}";
1193 return "lea{l}\t{%1, %0|%0, %1}";
1196 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1197 return "mov{l}\t{%1, %0|%0, %1}";
1201 (cond [(eq_attr "alternative" "2")
1202 (const_string "mmxadd")
1203 (eq_attr "alternative" "3,4,5")
1204 (const_string "mmxmov")
1205 (eq_attr "alternative" "6")
1206 (const_string "sselog1")
1207 (eq_attr "alternative" "7,8,9,10,11")
1208 (const_string "ssemov")
1209 (match_operand:DI 1 "pic_32bit_operand" "")
1210 (const_string "lea")
1212 (const_string "imov")))
1214 (cond [(eq_attr "alternative" "2,3")
1216 (eq_attr "alternative" "6,7")
1218 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1219 (const_string "V4SF")
1220 (const_string "TI"))
1221 (and (eq_attr "alternative" "8,9,10,11")
1222 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1225 (const_string "SI")))])
1227 ;; Stores and loads of ax to arbitrary constant address.
1228 ;; We fake an second form of instruction to force reload to load address
1229 ;; into register when rax is not available
1230 (define_insn "*movabssi_1_rex64"
1231 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1232 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1233 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1235 movabs{l}\t{%1, %P0|%P0, %1}
1236 mov{l}\t{%1, %a0|%a0, %1}"
1237 [(set_attr "type" "imov")
1238 (set_attr "modrm" "0,*")
1239 (set_attr "length_address" "8,0")
1240 (set_attr "length_immediate" "0,*")
1241 (set_attr "memory" "store")
1242 (set_attr "mode" "SI")])
1244 (define_insn "*movabssi_2_rex64"
1245 [(set (match_operand:SI 0 "register_operand" "=a,r")
1246 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1247 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1249 movabs{l}\t{%P1, %0|%0, %P1}
1250 mov{l}\t{%a1, %0|%0, %a1}"
1251 [(set_attr "type" "imov")
1252 (set_attr "modrm" "0,*")
1253 (set_attr "length_address" "8,0")
1254 (set_attr "length_immediate" "0")
1255 (set_attr "memory" "load")
1256 (set_attr "mode" "SI")])
1258 (define_insn "*swapsi"
1259 [(set (match_operand:SI 0 "register_operand" "+r")
1260 (match_operand:SI 1 "register_operand" "+r"))
1265 [(set_attr "type" "imov")
1266 (set_attr "mode" "SI")
1267 (set_attr "pent_pair" "np")
1268 (set_attr "athlon_decode" "vector")])
1270 (define_expand "movhi"
1271 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272 (match_operand:HI 1 "general_operand" ""))]
1274 "ix86_expand_move (HImode, operands); DONE;")
1276 (define_insn "*pushhi2"
1277 [(set (match_operand:HI 0 "push_operand" "=X")
1278 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1281 [(set_attr "type" "push")
1282 (set_attr "mode" "SI")])
1284 ;; For 64BIT abi we always round up to 8 bytes.
1285 (define_insn "*pushhi2_rex64"
1286 [(set (match_operand:HI 0 "push_operand" "=X")
1287 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1290 [(set_attr "type" "push")
1291 (set_attr "mode" "DI")])
1293 (define_insn "*movhi_1"
1294 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1295 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1296 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1298 switch (get_attr_type (insn))
1301 /* movzwl is faster than movw on p2 due to partial word stalls,
1302 though not as fast as an aligned movl. */
1303 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1305 if (get_attr_mode (insn) == MODE_SI)
1306 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1308 return "mov{w}\t{%1, %0|%0, %1}";
1312 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1313 (const_string "imov")
1314 (and (eq_attr "alternative" "0")
1315 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1317 (eq (symbol_ref "TARGET_HIMODE_MATH")
1319 (const_string "imov")
1320 (and (eq_attr "alternative" "1,2")
1321 (match_operand:HI 1 "aligned_operand" ""))
1322 (const_string "imov")
1323 (and (ne (symbol_ref "TARGET_MOVX")
1325 (eq_attr "alternative" "0,2"))
1326 (const_string "imovx")
1328 (const_string "imov")))
1330 (cond [(eq_attr "type" "imovx")
1332 (and (eq_attr "alternative" "1,2")
1333 (match_operand:HI 1 "aligned_operand" ""))
1335 (and (eq_attr "alternative" "0")
1336 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1338 (eq (symbol_ref "TARGET_HIMODE_MATH")
1342 (const_string "HI")))])
1344 ;; Stores and loads of ax to arbitrary constant address.
1345 ;; We fake an second form of instruction to force reload to load address
1346 ;; into register when rax is not available
1347 (define_insn "*movabshi_1_rex64"
1348 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1349 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1350 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1352 movabs{w}\t{%1, %P0|%P0, %1}
1353 mov{w}\t{%1, %a0|%a0, %1}"
1354 [(set_attr "type" "imov")
1355 (set_attr "modrm" "0,*")
1356 (set_attr "length_address" "8,0")
1357 (set_attr "length_immediate" "0,*")
1358 (set_attr "memory" "store")
1359 (set_attr "mode" "HI")])
1361 (define_insn "*movabshi_2_rex64"
1362 [(set (match_operand:HI 0 "register_operand" "=a,r")
1363 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1364 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1366 movabs{w}\t{%P1, %0|%0, %P1}
1367 mov{w}\t{%a1, %0|%0, %a1}"
1368 [(set_attr "type" "imov")
1369 (set_attr "modrm" "0,*")
1370 (set_attr "length_address" "8,0")
1371 (set_attr "length_immediate" "0")
1372 (set_attr "memory" "load")
1373 (set_attr "mode" "HI")])
1375 (define_insn "*swaphi_1"
1376 [(set (match_operand:HI 0 "register_operand" "+r")
1377 (match_operand:HI 1 "register_operand" "+r"))
1380 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1382 [(set_attr "type" "imov")
1383 (set_attr "mode" "SI")
1384 (set_attr "pent_pair" "np")
1385 (set_attr "athlon_decode" "vector")])
1387 (define_insn "*swaphi_2"
1388 [(set (match_operand:HI 0 "register_operand" "+r")
1389 (match_operand:HI 1 "register_operand" "+r"))
1392 "TARGET_PARTIAL_REG_STALL"
1394 [(set_attr "type" "imov")
1395 (set_attr "mode" "HI")
1396 (set_attr "pent_pair" "np")
1397 (set_attr "athlon_decode" "vector")])
1399 (define_expand "movstricthi"
1400 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1401 (match_operand:HI 1 "general_operand" ""))]
1402 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1404 /* Don't generate memory->memory moves, go through a register */
1405 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1406 operands[1] = force_reg (HImode, operands[1]);
1409 (define_insn "*movstricthi_1"
1410 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1411 (match_operand:HI 1 "general_operand" "rn,m"))]
1412 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1413 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1414 "mov{w}\t{%1, %0|%0, %1}"
1415 [(set_attr "type" "imov")
1416 (set_attr "mode" "HI")])
1418 (define_insn "*movstricthi_xor"
1419 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1420 (match_operand:HI 1 "const0_operand" "i"))
1421 (clobber (reg:CC FLAGS_REG))]
1423 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1424 "xor{w}\t{%0, %0|%0, %0}"
1425 [(set_attr "type" "alu1")
1426 (set_attr "mode" "HI")
1427 (set_attr "length_immediate" "0")])
1429 (define_expand "movqi"
1430 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1431 (match_operand:QI 1 "general_operand" ""))]
1433 "ix86_expand_move (QImode, operands); DONE;")
1435 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1436 ;; "push a byte". But actually we use pushl, which has the effect
1437 ;; of rounding the amount pushed up to a word.
1439 (define_insn "*pushqi2"
1440 [(set (match_operand:QI 0 "push_operand" "=X")
1441 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1444 [(set_attr "type" "push")
1445 (set_attr "mode" "SI")])
1447 ;; For 64BIT abi we always round up to 8 bytes.
1448 (define_insn "*pushqi2_rex64"
1449 [(set (match_operand:QI 0 "push_operand" "=X")
1450 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1453 [(set_attr "type" "push")
1454 (set_attr "mode" "DI")])
1456 ;; Situation is quite tricky about when to choose full sized (SImode) move
1457 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1458 ;; partial register dependency machines (such as AMD Athlon), where QImode
1459 ;; moves issue extra dependency and for partial register stalls machines
1460 ;; that don't use QImode patterns (and QImode move cause stall on the next
1463 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1464 ;; register stall machines with, where we use QImode instructions, since
1465 ;; partial register stall can be caused there. Then we use movzx.
1466 (define_insn "*movqi_1"
1467 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1468 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1469 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1471 switch (get_attr_type (insn))
1474 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1475 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1477 if (get_attr_mode (insn) == MODE_SI)
1478 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1480 return "mov{b}\t{%1, %0|%0, %1}";
1484 (cond [(and (eq_attr "alternative" "5")
1485 (not (match_operand:QI 1 "aligned_operand" "")))
1486 (const_string "imovx")
1487 (ne (symbol_ref "optimize_size") (const_int 0))
1488 (const_string "imov")
1489 (and (eq_attr "alternative" "3")
1490 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1492 (eq (symbol_ref "TARGET_QIMODE_MATH")
1494 (const_string "imov")
1495 (eq_attr "alternative" "3,5")
1496 (const_string "imovx")
1497 (and (ne (symbol_ref "TARGET_MOVX")
1499 (eq_attr "alternative" "2"))
1500 (const_string "imovx")
1502 (const_string "imov")))
1504 (cond [(eq_attr "alternative" "3,4,5")
1506 (eq_attr "alternative" "6")
1508 (eq_attr "type" "imovx")
1510 (and (eq_attr "type" "imov")
1511 (and (eq_attr "alternative" "0,1")
1512 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1515 ;; Avoid partial register stalls when not using QImode arithmetic
1516 (and (eq_attr "type" "imov")
1517 (and (eq_attr "alternative" "0,1")
1518 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1520 (eq (symbol_ref "TARGET_QIMODE_MATH")
1524 (const_string "QI")))])
1526 (define_expand "reload_outqi"
1527 [(parallel [(match_operand:QI 0 "" "=m")
1528 (match_operand:QI 1 "register_operand" "r")
1529 (match_operand:QI 2 "register_operand" "=&q")])]
1533 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1535 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1536 if (! q_regs_operand (op1, QImode))
1538 emit_insn (gen_movqi (op2, op1));
1541 emit_insn (gen_movqi (op0, op1));
1545 (define_insn "*swapqi_1"
1546 [(set (match_operand:QI 0 "register_operand" "+r")
1547 (match_operand:QI 1 "register_operand" "+r"))
1550 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1552 [(set_attr "type" "imov")
1553 (set_attr "mode" "SI")
1554 (set_attr "pent_pair" "np")
1555 (set_attr "athlon_decode" "vector")])
1557 (define_insn "*swapqi_2"
1558 [(set (match_operand:QI 0 "register_operand" "+q")
1559 (match_operand:QI 1 "register_operand" "+q"))
1562 "TARGET_PARTIAL_REG_STALL"
1564 [(set_attr "type" "imov")
1565 (set_attr "mode" "QI")
1566 (set_attr "pent_pair" "np")
1567 (set_attr "athlon_decode" "vector")])
1569 (define_expand "movstrictqi"
1570 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1571 (match_operand:QI 1 "general_operand" ""))]
1572 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1574 /* Don't generate memory->memory moves, go through a register. */
1575 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1576 operands[1] = force_reg (QImode, operands[1]);
1579 (define_insn "*movstrictqi_1"
1580 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1581 (match_operand:QI 1 "general_operand" "*qn,m"))]
1582 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1583 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1584 "mov{b}\t{%1, %0|%0, %1}"
1585 [(set_attr "type" "imov")
1586 (set_attr "mode" "QI")])
1588 (define_insn "*movstrictqi_xor"
1589 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1590 (match_operand:QI 1 "const0_operand" "i"))
1591 (clobber (reg:CC FLAGS_REG))]
1592 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1593 "xor{b}\t{%0, %0|%0, %0}"
1594 [(set_attr "type" "alu1")
1595 (set_attr "mode" "QI")
1596 (set_attr "length_immediate" "0")])
1598 (define_insn "*movsi_extv_1"
1599 [(set (match_operand:SI 0 "register_operand" "=R")
1600 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1604 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1605 [(set_attr "type" "imovx")
1606 (set_attr "mode" "SI")])
1608 (define_insn "*movhi_extv_1"
1609 [(set (match_operand:HI 0 "register_operand" "=R")
1610 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1614 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1615 [(set_attr "type" "imovx")
1616 (set_attr "mode" "SI")])
1618 (define_insn "*movqi_extv_1"
1619 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1620 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1625 switch (get_attr_type (insn))
1628 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1630 return "mov{b}\t{%h1, %0|%0, %h1}";
1634 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1635 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1636 (ne (symbol_ref "TARGET_MOVX")
1638 (const_string "imovx")
1639 (const_string "imov")))
1641 (if_then_else (eq_attr "type" "imovx")
1643 (const_string "QI")))])
1645 (define_insn "*movqi_extv_1_rex64"
1646 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1647 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1652 switch (get_attr_type (insn))
1655 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1657 return "mov{b}\t{%h1, %0|%0, %h1}";
1661 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1662 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1663 (ne (symbol_ref "TARGET_MOVX")
1665 (const_string "imovx")
1666 (const_string "imov")))
1668 (if_then_else (eq_attr "type" "imovx")
1670 (const_string "QI")))])
1672 ;; Stores and loads of ax to arbitrary constant address.
1673 ;; We fake an second form of instruction to force reload to load address
1674 ;; into register when rax is not available
1675 (define_insn "*movabsqi_1_rex64"
1676 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1677 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1678 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1680 movabs{b}\t{%1, %P0|%P0, %1}
1681 mov{b}\t{%1, %a0|%a0, %1}"
1682 [(set_attr "type" "imov")
1683 (set_attr "modrm" "0,*")
1684 (set_attr "length_address" "8,0")
1685 (set_attr "length_immediate" "0,*")
1686 (set_attr "memory" "store")
1687 (set_attr "mode" "QI")])
1689 (define_insn "*movabsqi_2_rex64"
1690 [(set (match_operand:QI 0 "register_operand" "=a,r")
1691 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1692 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1694 movabs{b}\t{%P1, %0|%0, %P1}
1695 mov{b}\t{%a1, %0|%0, %a1}"
1696 [(set_attr "type" "imov")
1697 (set_attr "modrm" "0,*")
1698 (set_attr "length_address" "8,0")
1699 (set_attr "length_immediate" "0")
1700 (set_attr "memory" "load")
1701 (set_attr "mode" "QI")])
1703 (define_insn "*movdi_extzv_1"
1704 [(set (match_operand:DI 0 "register_operand" "=R")
1705 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1709 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1710 [(set_attr "type" "imovx")
1711 (set_attr "mode" "DI")])
1713 (define_insn "*movsi_extzv_1"
1714 [(set (match_operand:SI 0 "register_operand" "=R")
1715 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1719 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1720 [(set_attr "type" "imovx")
1721 (set_attr "mode" "SI")])
1723 (define_insn "*movqi_extzv_2"
1724 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1725 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1730 switch (get_attr_type (insn))
1733 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1735 return "mov{b}\t{%h1, %0|%0, %h1}";
1739 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1740 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1741 (ne (symbol_ref "TARGET_MOVX")
1743 (const_string "imovx")
1744 (const_string "imov")))
1746 (if_then_else (eq_attr "type" "imovx")
1748 (const_string "QI")))])
1750 (define_insn "*movqi_extzv_2_rex64"
1751 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1752 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1757 switch (get_attr_type (insn))
1760 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1762 return "mov{b}\t{%h1, %0|%0, %h1}";
1766 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1767 (ne (symbol_ref "TARGET_MOVX")
1769 (const_string "imovx")
1770 (const_string "imov")))
1772 (if_then_else (eq_attr "type" "imovx")
1774 (const_string "QI")))])
1776 (define_insn "movsi_insv_1"
1777 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1780 (match_operand:SI 1 "general_operand" "Qmn"))]
1782 "mov{b}\t{%b1, %h0|%h0, %b1}"
1783 [(set_attr "type" "imov")
1784 (set_attr "mode" "QI")])
1786 (define_insn "movdi_insv_1_rex64"
1787 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1790 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1792 "mov{b}\t{%b1, %h0|%h0, %b1}"
1793 [(set_attr "type" "imov")
1794 (set_attr "mode" "QI")])
1796 (define_insn "*movqi_insv_2"
1797 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1800 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1803 "mov{b}\t{%h1, %h0|%h0, %h1}"
1804 [(set_attr "type" "imov")
1805 (set_attr "mode" "QI")])
1807 (define_expand "movdi"
1808 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1809 (match_operand:DI 1 "general_operand" ""))]
1811 "ix86_expand_move (DImode, operands); DONE;")
1813 (define_insn "*pushdi"
1814 [(set (match_operand:DI 0 "push_operand" "=<")
1815 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1819 (define_insn "*pushdi2_rex64"
1820 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1821 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1826 [(set_attr "type" "push,multi")
1827 (set_attr "mode" "DI")])
1829 ;; Convert impossible pushes of immediate to existing instructions.
1830 ;; First try to get scratch register and go through it. In case this
1831 ;; fails, push sign extended lower part first and then overwrite
1832 ;; upper part by 32bit move.
1834 [(match_scratch:DI 2 "r")
1835 (set (match_operand:DI 0 "push_operand" "")
1836 (match_operand:DI 1 "immediate_operand" ""))]
1837 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1838 && !x86_64_immediate_operand (operands[1], DImode)"
1839 [(set (match_dup 2) (match_dup 1))
1840 (set (match_dup 0) (match_dup 2))]
1843 ;; We need to define this as both peepholer and splitter for case
1844 ;; peephole2 pass is not run.
1845 ;; "&& 1" is needed to keep it from matching the previous pattern.
1847 [(set (match_operand:DI 0 "push_operand" "")
1848 (match_operand:DI 1 "immediate_operand" ""))]
1849 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1850 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1851 [(set (match_dup 0) (match_dup 1))
1852 (set (match_dup 2) (match_dup 3))]
1853 "split_di (operands + 1, 1, operands + 2, operands + 3);
1854 operands[1] = gen_lowpart (DImode, operands[2]);
1855 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1860 [(set (match_operand:DI 0 "push_operand" "")
1861 (match_operand:DI 1 "immediate_operand" ""))]
1862 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1863 ? flow2_completed : reload_completed)
1864 && !symbolic_operand (operands[1], DImode)
1865 && !x86_64_immediate_operand (operands[1], DImode)"
1866 [(set (match_dup 0) (match_dup 1))
1867 (set (match_dup 2) (match_dup 3))]
1868 "split_di (operands + 1, 1, operands + 2, operands + 3);
1869 operands[1] = gen_lowpart (DImode, operands[2]);
1870 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1874 (define_insn "*pushdi2_prologue_rex64"
1875 [(set (match_operand:DI 0 "push_operand" "=<")
1876 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1877 (clobber (mem:BLK (scratch)))]
1880 [(set_attr "type" "push")
1881 (set_attr "mode" "DI")])
1883 (define_insn "*popdi1_epilogue_rex64"
1884 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1885 (mem:DI (reg:DI SP_REG)))
1886 (set (reg:DI SP_REG)
1887 (plus:DI (reg:DI SP_REG) (const_int 8)))
1888 (clobber (mem:BLK (scratch)))]
1891 [(set_attr "type" "pop")
1892 (set_attr "mode" "DI")])
1894 (define_insn "popdi1"
1895 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1896 (mem:DI (reg:DI SP_REG)))
1897 (set (reg:DI SP_REG)
1898 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1901 [(set_attr "type" "pop")
1902 (set_attr "mode" "DI")])
1904 (define_insn "*movdi_xor_rex64"
1905 [(set (match_operand:DI 0 "register_operand" "=r")
1906 (match_operand:DI 1 "const0_operand" "i"))
1907 (clobber (reg:CC FLAGS_REG))]
1908 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1909 && reload_completed"
1910 "xor{l}\t{%k0, %k0|%k0, %k0}"
1911 [(set_attr "type" "alu1")
1912 (set_attr "mode" "SI")
1913 (set_attr "length_immediate" "0")])
1915 (define_insn "*movdi_or_rex64"
1916 [(set (match_operand:DI 0 "register_operand" "=r")
1917 (match_operand:DI 1 "const_int_operand" "i"))
1918 (clobber (reg:CC FLAGS_REG))]
1919 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1921 && operands[1] == constm1_rtx"
1923 operands[1] = constm1_rtx;
1924 return "or{q}\t{%1, %0|%0, %1}";
1926 [(set_attr "type" "alu1")
1927 (set_attr "mode" "DI")
1928 (set_attr "length_immediate" "1")])
1930 (define_insn "*movdi_2"
1931 [(set (match_operand:DI 0 "nonimmediate_operand"
1932 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1933 (match_operand:DI 1 "general_operand"
1934 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1935 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1940 movq\t{%1, %0|%0, %1}
1941 movq\t{%1, %0|%0, %1}
1943 movq\t{%1, %0|%0, %1}
1944 movdqa\t{%1, %0|%0, %1}
1945 movq\t{%1, %0|%0, %1}
1947 movlps\t{%1, %0|%0, %1}
1948 movaps\t{%1, %0|%0, %1}
1949 movlps\t{%1, %0|%0, %1}"
1950 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1951 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1954 [(set (match_operand:DI 0 "push_operand" "")
1955 (match_operand:DI 1 "general_operand" ""))]
1956 "!TARGET_64BIT && reload_completed
1957 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1959 "ix86_split_long_move (operands); DONE;")
1961 ;; %%% This multiword shite has got to go.
1963 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1964 (match_operand:DI 1 "general_operand" ""))]
1965 "!TARGET_64BIT && reload_completed
1966 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1967 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1969 "ix86_split_long_move (operands); DONE;")
1971 (define_insn "*movdi_1_rex64"
1972 [(set (match_operand:DI 0 "nonimmediate_operand"
1973 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1974 (match_operand:DI 1 "general_operand"
1975 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1976 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1978 switch (get_attr_type (insn))
1981 if (which_alternative == 13)
1982 return "movq2dq\t{%1, %0|%0, %1}";
1984 return "movdq2q\t{%1, %0|%0, %1}";
1986 if (get_attr_mode (insn) == MODE_TI)
1987 return "movdqa\t{%1, %0|%0, %1}";
1990 /* Moves from and into integer register is done using movd opcode with
1992 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1993 return "movd\t{%1, %0|%0, %1}";
1994 return "movq\t{%1, %0|%0, %1}";
1997 return "pxor\t%0, %0";
2001 return "lea{q}\t{%a1, %0|%0, %a1}";
2003 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2004 if (get_attr_mode (insn) == MODE_SI)
2005 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2006 else if (which_alternative == 2)
2007 return "movabs{q}\t{%1, %0|%0, %1}";
2009 return "mov{q}\t{%1, %0|%0, %1}";
2013 (cond [(eq_attr "alternative" "5")
2014 (const_string "mmxadd")
2015 (eq_attr "alternative" "6,7,8")
2016 (const_string "mmxmov")
2017 (eq_attr "alternative" "9")
2018 (const_string "sselog1")
2019 (eq_attr "alternative" "10,11,12")
2020 (const_string "ssemov")
2021 (eq_attr "alternative" "13,14")
2022 (const_string "ssecvt")
2023 (eq_attr "alternative" "4")
2024 (const_string "multi")
2025 (match_operand:DI 1 "pic_32bit_operand" "")
2026 (const_string "lea")
2028 (const_string "imov")))
2029 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2030 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2031 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2033 ;; Stores and loads of ax to arbitrary constant address.
2034 ;; We fake an second form of instruction to force reload to load address
2035 ;; into register when rax is not available
2036 (define_insn "*movabsdi_1_rex64"
2037 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2038 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2039 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2041 movabs{q}\t{%1, %P0|%P0, %1}
2042 mov{q}\t{%1, %a0|%a0, %1}"
2043 [(set_attr "type" "imov")
2044 (set_attr "modrm" "0,*")
2045 (set_attr "length_address" "8,0")
2046 (set_attr "length_immediate" "0,*")
2047 (set_attr "memory" "store")
2048 (set_attr "mode" "DI")])
2050 (define_insn "*movabsdi_2_rex64"
2051 [(set (match_operand:DI 0 "register_operand" "=a,r")
2052 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2053 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2055 movabs{q}\t{%P1, %0|%0, %P1}
2056 mov{q}\t{%a1, %0|%0, %a1}"
2057 [(set_attr "type" "imov")
2058 (set_attr "modrm" "0,*")
2059 (set_attr "length_address" "8,0")
2060 (set_attr "length_immediate" "0")
2061 (set_attr "memory" "load")
2062 (set_attr "mode" "DI")])
2064 ;; Convert impossible stores of immediate to existing instructions.
2065 ;; First try to get scratch register and go through it. In case this
2066 ;; fails, move by 32bit parts.
2068 [(match_scratch:DI 2 "r")
2069 (set (match_operand:DI 0 "memory_operand" "")
2070 (match_operand:DI 1 "immediate_operand" ""))]
2071 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072 && !x86_64_immediate_operand (operands[1], DImode)"
2073 [(set (match_dup 2) (match_dup 1))
2074 (set (match_dup 0) (match_dup 2))]
2077 ;; We need to define this as both peepholer and splitter for case
2078 ;; peephole2 pass is not run.
2079 ;; "&& 1" is needed to keep it from matching the previous pattern.
2081 [(set (match_operand:DI 0 "memory_operand" "")
2082 (match_operand:DI 1 "immediate_operand" ""))]
2083 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2084 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2085 [(set (match_dup 2) (match_dup 3))
2086 (set (match_dup 4) (match_dup 5))]
2087 "split_di (operands, 2, operands + 2, operands + 4);")
2090 [(set (match_operand:DI 0 "memory_operand" "")
2091 (match_operand:DI 1 "immediate_operand" ""))]
2092 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2093 ? flow2_completed : reload_completed)
2094 && !symbolic_operand (operands[1], DImode)
2095 && !x86_64_immediate_operand (operands[1], DImode)"
2096 [(set (match_dup 2) (match_dup 3))
2097 (set (match_dup 4) (match_dup 5))]
2098 "split_di (operands, 2, operands + 2, operands + 4);")
2100 (define_insn "*swapdi_rex64"
2101 [(set (match_operand:DI 0 "register_operand" "+r")
2102 (match_operand:DI 1 "register_operand" "+r"))
2107 [(set_attr "type" "imov")
2108 (set_attr "mode" "DI")
2109 (set_attr "pent_pair" "np")
2110 (set_attr "athlon_decode" "vector")])
2112 (define_expand "movti"
2113 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2114 (match_operand:TI 1 "nonimmediate_operand" ""))]
2115 "TARGET_SSE || TARGET_64BIT"
2118 ix86_expand_move (TImode, operands);
2120 ix86_expand_vector_move (TImode, operands);
2124 (define_insn "*movti_internal"
2125 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2126 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2127 "TARGET_SSE && !TARGET_64BIT
2128 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2130 switch (which_alternative)
2133 if (get_attr_mode (insn) == MODE_V4SF)
2134 return "xorps\t%0, %0";
2136 return "pxor\t%0, %0";
2139 if (get_attr_mode (insn) == MODE_V4SF)
2140 return "movaps\t{%1, %0|%0, %1}";
2142 return "movdqa\t{%1, %0|%0, %1}";
2147 [(set_attr "type" "sselog1,ssemov,ssemov")
2149 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2150 (ne (symbol_ref "optimize_size") (const_int 0)))
2151 (const_string "V4SF")
2152 (and (eq_attr "alternative" "2")
2153 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2155 (const_string "V4SF")]
2156 (const_string "TI")))])
2158 (define_insn "*movti_rex64"
2159 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2160 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2162 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2164 switch (which_alternative)
2170 if (get_attr_mode (insn) == MODE_V4SF)
2171 return "xorps\t%0, %0";
2173 return "pxor\t%0, %0";
2176 if (get_attr_mode (insn) == MODE_V4SF)
2177 return "movaps\t{%1, %0|%0, %1}";
2179 return "movdqa\t{%1, %0|%0, %1}";
2184 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2186 (cond [(eq_attr "alternative" "2,3")
2188 (ne (symbol_ref "optimize_size")
2190 (const_string "V4SF")
2191 (const_string "TI"))
2192 (eq_attr "alternative" "4")
2194 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2196 (ne (symbol_ref "optimize_size")
2198 (const_string "V4SF")
2199 (const_string "TI"))]
2200 (const_string "DI")))])
2203 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2204 (match_operand:TI 1 "general_operand" ""))]
2205 "reload_completed && !SSE_REG_P (operands[0])
2206 && !SSE_REG_P (operands[1])"
2208 "ix86_split_long_move (operands); DONE;")
2210 (define_expand "movsf"
2211 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2212 (match_operand:SF 1 "general_operand" ""))]
2214 "ix86_expand_move (SFmode, operands); DONE;")
2216 (define_insn "*pushsf"
2217 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2218 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2221 /* Anything else should be already split before reg-stack. */
2222 gcc_assert (which_alternative == 1);
2223 return "push{l}\t%1";
2225 [(set_attr "type" "multi,push,multi")
2226 (set_attr "unit" "i387,*,*")
2227 (set_attr "mode" "SF,SI,SF")])
2229 (define_insn "*pushsf_rex64"
2230 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2231 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2234 /* Anything else should be already split before reg-stack. */
2235 gcc_assert (which_alternative == 1);
2236 return "push{q}\t%q1";
2238 [(set_attr "type" "multi,push,multi")
2239 (set_attr "unit" "i387,*,*")
2240 (set_attr "mode" "SF,DI,SF")])
2243 [(set (match_operand:SF 0 "push_operand" "")
2244 (match_operand:SF 1 "memory_operand" ""))]
2246 && GET_CODE (operands[1]) == MEM
2247 && constant_pool_reference_p (operands[1])"
2250 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2253 ;; %%% Kill this when call knows how to work this out.
2255 [(set (match_operand:SF 0 "push_operand" "")
2256 (match_operand:SF 1 "any_fp_register_operand" ""))]
2258 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2259 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2262 [(set (match_operand:SF 0 "push_operand" "")
2263 (match_operand:SF 1 "any_fp_register_operand" ""))]
2265 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2266 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2268 (define_insn "*movsf_1"
2269 [(set (match_operand:SF 0 "nonimmediate_operand"
2270 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2271 (match_operand:SF 1 "general_operand"
2272 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2273 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2274 && (reload_in_progress || reload_completed
2275 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2276 || GET_CODE (operands[1]) != CONST_DOUBLE
2277 || memory_operand (operands[0], SFmode))"
2279 switch (which_alternative)
2282 return output_387_reg_move (insn, operands);
2285 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2286 return "fstp%z0\t%y0";
2288 return "fst%z0\t%y0";
2291 return standard_80387_constant_opcode (operands[1]);
2295 return "mov{l}\t{%1, %0|%0, %1}";
2297 if (get_attr_mode (insn) == MODE_TI)
2298 return "pxor\t%0, %0";
2300 return "xorps\t%0, %0";
2302 if (get_attr_mode (insn) == MODE_V4SF)
2303 return "movaps\t{%1, %0|%0, %1}";
2305 return "movss\t{%1, %0|%0, %1}";
2308 return "movss\t{%1, %0|%0, %1}";
2312 return "movd\t{%1, %0|%0, %1}";
2315 return "movq\t{%1, %0|%0, %1}";
2321 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2323 (cond [(eq_attr "alternative" "3,4,9,10")
2325 (eq_attr "alternative" "5")
2327 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2329 (ne (symbol_ref "TARGET_SSE2")
2331 (eq (symbol_ref "optimize_size")
2334 (const_string "V4SF"))
2335 /* For architectures resolving dependencies on
2336 whole SSE registers use APS move to break dependency
2337 chains, otherwise use short move to avoid extra work.
2339 Do the same for architectures resolving dependencies on
2340 the parts. While in DF mode it is better to always handle
2341 just register parts, the SF mode is different due to lack
2342 of instructions to load just part of the register. It is
2343 better to maintain the whole registers in single format
2344 to avoid problems on using packed logical operations. */
2345 (eq_attr "alternative" "6")
2347 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2349 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2351 (const_string "V4SF")
2352 (const_string "SF"))
2353 (eq_attr "alternative" "11")
2354 (const_string "DI")]
2355 (const_string "SF")))])
2357 (define_insn "*swapsf"
2358 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2359 (match_operand:SF 1 "fp_register_operand" "+f"))
2362 "reload_completed || TARGET_80387"
2364 if (STACK_TOP_P (operands[0]))
2369 [(set_attr "type" "fxch")
2370 (set_attr "mode" "SF")])
2372 (define_expand "movdf"
2373 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2374 (match_operand:DF 1 "general_operand" ""))]
2376 "ix86_expand_move (DFmode, operands); DONE;")
2378 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2379 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2380 ;; On the average, pushdf using integers can be still shorter. Allow this
2381 ;; pattern for optimize_size too.
2383 (define_insn "*pushdf_nointeger"
2384 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2385 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2386 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2388 /* This insn should be already split before reg-stack. */
2391 [(set_attr "type" "multi")
2392 (set_attr "unit" "i387,*,*,*")
2393 (set_attr "mode" "DF,SI,SI,DF")])
2395 (define_insn "*pushdf_integer"
2396 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2397 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2398 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2400 /* This insn should be already split before reg-stack. */
2403 [(set_attr "type" "multi")
2404 (set_attr "unit" "i387,*,*")
2405 (set_attr "mode" "DF,SI,DF")])
2407 ;; %%% Kill this when call knows how to work this out.
2409 [(set (match_operand:DF 0 "push_operand" "")
2410 (match_operand:DF 1 "any_fp_register_operand" ""))]
2411 "!TARGET_64BIT && reload_completed"
2412 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2413 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2417 [(set (match_operand:DF 0 "push_operand" "")
2418 (match_operand:DF 1 "any_fp_register_operand" ""))]
2419 "TARGET_64BIT && reload_completed"
2420 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2421 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2425 [(set (match_operand:DF 0 "push_operand" "")
2426 (match_operand:DF 1 "general_operand" ""))]
2429 "ix86_split_long_move (operands); DONE;")
2431 ;; Moving is usually shorter when only FP registers are used. This separate
2432 ;; movdf pattern avoids the use of integer registers for FP operations
2433 ;; when optimizing for size.
2435 (define_insn "*movdf_nointeger"
2436 [(set (match_operand:DF 0 "nonimmediate_operand"
2437 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2438 (match_operand:DF 1 "general_operand"
2439 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2440 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2441 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2442 && (reload_in_progress || reload_completed
2443 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2444 || GET_CODE (operands[1]) != CONST_DOUBLE
2445 || memory_operand (operands[0], DFmode))"
2447 switch (which_alternative)
2450 return output_387_reg_move (insn, operands);
2453 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2454 return "fstp%z0\t%y0";
2456 return "fst%z0\t%y0";
2459 return standard_80387_constant_opcode (operands[1]);
2465 switch (get_attr_mode (insn))
2468 return "xorps\t%0, %0";
2470 return "xorpd\t%0, %0";
2472 return "pxor\t%0, %0";
2479 switch (get_attr_mode (insn))
2482 return "movaps\t{%1, %0|%0, %1}";
2484 return "movapd\t{%1, %0|%0, %1}";
2486 return "movdqa\t{%1, %0|%0, %1}";
2488 return "movq\t{%1, %0|%0, %1}";
2490 return "movsd\t{%1, %0|%0, %1}";
2492 return "movlpd\t{%1, %0|%0, %1}";
2494 return "movlps\t{%1, %0|%0, %1}";
2503 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2505 (cond [(eq_attr "alternative" "0,1,2")
2507 (eq_attr "alternative" "3,4")
2510 /* For SSE1, we have many fewer alternatives. */
2511 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2512 (cond [(eq_attr "alternative" "5,6")
2513 (const_string "V4SF")
2515 (const_string "V2SF"))
2517 /* xorps is one byte shorter. */
2518 (eq_attr "alternative" "5")
2519 (cond [(ne (symbol_ref "optimize_size")
2521 (const_string "V4SF")
2522 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2526 (const_string "V2DF"))
2528 /* For architectures resolving dependencies on
2529 whole SSE registers use APD move to break dependency
2530 chains, otherwise use short move to avoid extra work.
2532 movaps encodes one byte shorter. */
2533 (eq_attr "alternative" "6")
2535 [(ne (symbol_ref "optimize_size")
2537 (const_string "V4SF")
2538 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2540 (const_string "V2DF")
2542 (const_string "DF"))
2543 /* For architectures resolving dependencies on register
2544 parts we may avoid extra work to zero out upper part
2546 (eq_attr "alternative" "7")
2548 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2550 (const_string "V1DF")
2551 (const_string "DF"))
2553 (const_string "DF")))])
2555 (define_insn "*movdf_integer"
2556 [(set (match_operand:DF 0 "nonimmediate_operand"
2557 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2558 (match_operand:DF 1 "general_operand"
2559 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2560 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2561 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2562 && (reload_in_progress || reload_completed
2563 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2564 || GET_CODE (operands[1]) != CONST_DOUBLE
2565 || memory_operand (operands[0], DFmode))"
2567 switch (which_alternative)
2570 return output_387_reg_move (insn, operands);
2573 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2574 return "fstp%z0\t%y0";
2576 return "fst%z0\t%y0";
2579 return standard_80387_constant_opcode (operands[1]);
2586 switch (get_attr_mode (insn))
2589 return "xorps\t%0, %0";
2591 return "xorpd\t%0, %0";
2593 return "pxor\t%0, %0";
2600 switch (get_attr_mode (insn))
2603 return "movaps\t{%1, %0|%0, %1}";
2605 return "movapd\t{%1, %0|%0, %1}";
2607 return "movdqa\t{%1, %0|%0, %1}";
2609 return "movq\t{%1, %0|%0, %1}";
2611 return "movsd\t{%1, %0|%0, %1}";
2613 return "movlpd\t{%1, %0|%0, %1}";
2615 return "movlps\t{%1, %0|%0, %1}";
2624 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2626 (cond [(eq_attr "alternative" "0,1,2")
2628 (eq_attr "alternative" "3,4")
2631 /* For SSE1, we have many fewer alternatives. */
2632 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2633 (cond [(eq_attr "alternative" "5,6")
2634 (const_string "V4SF")
2636 (const_string "V2SF"))
2638 /* xorps is one byte shorter. */
2639 (eq_attr "alternative" "5")
2640 (cond [(ne (symbol_ref "optimize_size")
2642 (const_string "V4SF")
2643 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2647 (const_string "V2DF"))
2649 /* For architectures resolving dependencies on
2650 whole SSE registers use APD move to break dependency
2651 chains, otherwise use short move to avoid extra work.
2653 movaps encodes one byte shorter. */
2654 (eq_attr "alternative" "6")
2656 [(ne (symbol_ref "optimize_size")
2658 (const_string "V4SF")
2659 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2661 (const_string "V2DF")
2663 (const_string "DF"))
2664 /* For architectures resolving dependencies on register
2665 parts we may avoid extra work to zero out upper part
2667 (eq_attr "alternative" "7")
2669 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2671 (const_string "V1DF")
2672 (const_string "DF"))
2674 (const_string "DF")))])
2677 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2678 (match_operand:DF 1 "general_operand" ""))]
2680 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2681 && ! (ANY_FP_REG_P (operands[0]) ||
2682 (GET_CODE (operands[0]) == SUBREG
2683 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2684 && ! (ANY_FP_REG_P (operands[1]) ||
2685 (GET_CODE (operands[1]) == SUBREG
2686 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2688 "ix86_split_long_move (operands); DONE;")
2690 (define_insn "*swapdf"
2691 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2692 (match_operand:DF 1 "fp_register_operand" "+f"))
2695 "reload_completed || TARGET_80387"
2697 if (STACK_TOP_P (operands[0]))
2702 [(set_attr "type" "fxch")
2703 (set_attr "mode" "DF")])
2705 (define_expand "movxf"
2706 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2707 (match_operand:XF 1 "general_operand" ""))]
2709 "ix86_expand_move (XFmode, operands); DONE;")
2711 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2712 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2713 ;; Pushing using integer instructions is longer except for constants
2714 ;; and direct memory references.
2715 ;; (assuming that any given constant is pushed only once, but this ought to be
2716 ;; handled elsewhere).
2718 (define_insn "*pushxf_nointeger"
2719 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2720 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2723 /* This insn should be already split before reg-stack. */
2726 [(set_attr "type" "multi")
2727 (set_attr "unit" "i387,*,*")
2728 (set_attr "mode" "XF,SI,SI")])
2730 (define_insn "*pushxf_integer"
2731 [(set (match_operand:XF 0 "push_operand" "=<,<")
2732 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2735 /* This insn should be already split before reg-stack. */
2738 [(set_attr "type" "multi")
2739 (set_attr "unit" "i387,*")
2740 (set_attr "mode" "XF,SI")])
2743 [(set (match_operand 0 "push_operand" "")
2744 (match_operand 1 "general_operand" ""))]
2746 && (GET_MODE (operands[0]) == XFmode
2747 || GET_MODE (operands[0]) == DFmode)
2748 && !ANY_FP_REG_P (operands[1])"
2750 "ix86_split_long_move (operands); DONE;")
2753 [(set (match_operand:XF 0 "push_operand" "")
2754 (match_operand:XF 1 "any_fp_register_operand" ""))]
2756 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2757 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2758 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2761 [(set (match_operand:XF 0 "push_operand" "")
2762 (match_operand:XF 1 "any_fp_register_operand" ""))]
2764 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2765 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2766 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2768 ;; Do not use integer registers when optimizing for size
2769 (define_insn "*movxf_nointeger"
2770 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2771 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2773 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2774 && (reload_in_progress || reload_completed
2775 || GET_CODE (operands[1]) != CONST_DOUBLE
2776 || memory_operand (operands[0], XFmode))"
2778 switch (which_alternative)
2781 return output_387_reg_move (insn, operands);
2784 /* There is no non-popping store to memory for XFmode. So if
2785 we need one, follow the store with a load. */
2786 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2787 return "fstp%z0\t%y0\;fld%z0\t%y0";
2789 return "fstp%z0\t%y0";
2792 return standard_80387_constant_opcode (operands[1]);
2800 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2801 (set_attr "mode" "XF,XF,XF,SI,SI")])
2803 (define_insn "*movxf_integer"
2804 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2805 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2807 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2808 && (reload_in_progress || reload_completed
2809 || GET_CODE (operands[1]) != CONST_DOUBLE
2810 || memory_operand (operands[0], XFmode))"
2812 switch (which_alternative)
2815 return output_387_reg_move (insn, operands);
2818 /* There is no non-popping store to memory for XFmode. So if
2819 we need one, follow the store with a load. */
2820 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2821 return "fstp%z0\t%y0\;fld%z0\t%y0";
2823 return "fstp%z0\t%y0";
2826 return standard_80387_constant_opcode (operands[1]);
2835 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2836 (set_attr "mode" "XF,XF,XF,SI,SI")])
2839 [(set (match_operand 0 "nonimmediate_operand" "")
2840 (match_operand 1 "general_operand" ""))]
2842 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2843 && GET_MODE (operands[0]) == XFmode
2844 && ! (ANY_FP_REG_P (operands[0]) ||
2845 (GET_CODE (operands[0]) == SUBREG
2846 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2847 && ! (ANY_FP_REG_P (operands[1]) ||
2848 (GET_CODE (operands[1]) == SUBREG
2849 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2851 "ix86_split_long_move (operands); DONE;")
2854 [(set (match_operand 0 "register_operand" "")
2855 (match_operand 1 "memory_operand" ""))]
2857 && GET_CODE (operands[1]) == MEM
2858 && (GET_MODE (operands[0]) == XFmode
2859 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2860 && constant_pool_reference_p (operands[1])"
2861 [(set (match_dup 0) (match_dup 1))]
2863 rtx c = avoid_constant_pool_reference (operands[1]);
2864 rtx r = operands[0];
2866 if (GET_CODE (r) == SUBREG)
2871 if (!standard_sse_constant_p (c))
2874 else if (FP_REG_P (r))
2876 if (!standard_80387_constant_p (c))
2879 else if (MMX_REG_P (r))
2885 (define_insn "swapxf"
2886 [(set (match_operand:XF 0 "register_operand" "+f")
2887 (match_operand:XF 1 "register_operand" "+f"))
2892 if (STACK_TOP_P (operands[0]))
2897 [(set_attr "type" "fxch")
2898 (set_attr "mode" "XF")])
2900 (define_expand "movtf"
2901 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2902 (match_operand:TF 1 "nonimmediate_operand" ""))]
2905 ix86_expand_move (TFmode, operands);
2909 (define_insn "*movtf_internal"
2910 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2911 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2913 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2915 switch (which_alternative)
2921 if (get_attr_mode (insn) == MODE_V4SF)
2922 return "xorps\t%0, %0";
2924 return "pxor\t%0, %0";
2927 if (get_attr_mode (insn) == MODE_V4SF)
2928 return "movaps\t{%1, %0|%0, %1}";
2930 return "movdqa\t{%1, %0|%0, %1}";
2935 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2937 (cond [(eq_attr "alternative" "2,3")
2939 (ne (symbol_ref "optimize_size")
2941 (const_string "V4SF")
2942 (const_string "TI"))
2943 (eq_attr "alternative" "4")
2945 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2947 (ne (symbol_ref "optimize_size")
2949 (const_string "V4SF")
2950 (const_string "TI"))]
2951 (const_string "DI")))])
2954 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2955 (match_operand:TF 1 "general_operand" ""))]
2956 "reload_completed && !SSE_REG_P (operands[0])
2957 && !SSE_REG_P (operands[1])"
2959 "ix86_split_long_move (operands); DONE;")
2961 ;; Zero extension instructions
2963 (define_expand "zero_extendhisi2"
2964 [(set (match_operand:SI 0 "register_operand" "")
2965 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2968 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2970 operands[1] = force_reg (HImode, operands[1]);
2971 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2976 (define_insn "zero_extendhisi2_and"
2977 [(set (match_operand:SI 0 "register_operand" "=r")
2978 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2979 (clobber (reg:CC FLAGS_REG))]
2980 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2982 [(set_attr "type" "alu1")
2983 (set_attr "mode" "SI")])
2986 [(set (match_operand:SI 0 "register_operand" "")
2987 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2988 (clobber (reg:CC FLAGS_REG))]
2989 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2990 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2991 (clobber (reg:CC FLAGS_REG))])]
2994 (define_insn "*zero_extendhisi2_movzwl"
2995 [(set (match_operand:SI 0 "register_operand" "=r")
2996 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2997 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2998 "movz{wl|x}\t{%1, %0|%0, %1}"
2999 [(set_attr "type" "imovx")
3000 (set_attr "mode" "SI")])
3002 (define_expand "zero_extendqihi2"
3004 [(set (match_operand:HI 0 "register_operand" "")
3005 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3006 (clobber (reg:CC FLAGS_REG))])]
3010 (define_insn "*zero_extendqihi2_and"
3011 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3012 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3013 (clobber (reg:CC FLAGS_REG))]
3014 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3016 [(set_attr "type" "alu1")
3017 (set_attr "mode" "HI")])
3019 (define_insn "*zero_extendqihi2_movzbw_and"
3020 [(set (match_operand:HI 0 "register_operand" "=r,r")
3021 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3022 (clobber (reg:CC FLAGS_REG))]
3023 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3025 [(set_attr "type" "imovx,alu1")
3026 (set_attr "mode" "HI")])
3028 ; zero extend to SImode here to avoid partial register stalls
3029 (define_insn "*zero_extendqihi2_movzbl"
3030 [(set (match_operand:HI 0 "register_operand" "=r")
3031 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3032 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3033 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3034 [(set_attr "type" "imovx")
3035 (set_attr "mode" "SI")])
3037 ;; For the movzbw case strip only the clobber
3039 [(set (match_operand:HI 0 "register_operand" "")
3040 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3041 (clobber (reg:CC FLAGS_REG))]
3043 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3044 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3045 [(set (match_operand:HI 0 "register_operand" "")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3048 ;; When source and destination does not overlap, clear destination
3049 ;; first and then do the movb
3051 [(set (match_operand:HI 0 "register_operand" "")
3052 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3053 (clobber (reg:CC FLAGS_REG))]
3055 && ANY_QI_REG_P (operands[0])
3056 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3057 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3058 [(set (match_dup 0) (const_int 0))
3059 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3060 "operands[2] = gen_lowpart (QImode, operands[0]);")
3062 ;; Rest is handled by single and.
3064 [(set (match_operand:HI 0 "register_operand" "")
3065 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3066 (clobber (reg:CC FLAGS_REG))]
3068 && true_regnum (operands[0]) == true_regnum (operands[1])"
3069 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3070 (clobber (reg:CC FLAGS_REG))])]
3073 (define_expand "zero_extendqisi2"
3075 [(set (match_operand:SI 0 "register_operand" "")
3076 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3077 (clobber (reg:CC FLAGS_REG))])]
3081 (define_insn "*zero_extendqisi2_and"
3082 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3083 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3084 (clobber (reg:CC FLAGS_REG))]
3085 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3087 [(set_attr "type" "alu1")
3088 (set_attr "mode" "SI")])
3090 (define_insn "*zero_extendqisi2_movzbw_and"
3091 [(set (match_operand:SI 0 "register_operand" "=r,r")
3092 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3093 (clobber (reg:CC FLAGS_REG))]
3094 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3096 [(set_attr "type" "imovx,alu1")
3097 (set_attr "mode" "SI")])
3099 (define_insn "*zero_extendqisi2_movzbw"
3100 [(set (match_operand:SI 0 "register_operand" "=r")
3101 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3102 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3103 "movz{bl|x}\t{%1, %0|%0, %1}"
3104 [(set_attr "type" "imovx")
3105 (set_attr "mode" "SI")])
3107 ;; For the movzbl case strip only the clobber
3109 [(set (match_operand:SI 0 "register_operand" "")
3110 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111 (clobber (reg:CC FLAGS_REG))]
3113 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3114 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3116 (zero_extend:SI (match_dup 1)))])
3118 ;; When source and destination does not overlap, clear destination
3119 ;; first and then do the movb
3121 [(set (match_operand:SI 0 "register_operand" "")
3122 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3123 (clobber (reg:CC FLAGS_REG))]
3125 && ANY_QI_REG_P (operands[0])
3126 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3127 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3128 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3129 [(set (match_dup 0) (const_int 0))
3130 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3131 "operands[2] = gen_lowpart (QImode, operands[0]);")
3133 ;; Rest is handled by single and.
3135 [(set (match_operand:SI 0 "register_operand" "")
3136 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3137 (clobber (reg:CC FLAGS_REG))]
3139 && true_regnum (operands[0]) == true_regnum (operands[1])"
3140 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3141 (clobber (reg:CC FLAGS_REG))])]
3144 ;; %%% Kill me once multi-word ops are sane.
3145 (define_expand "zero_extendsidi2"
3146 [(set (match_operand:DI 0 "register_operand" "=r")
3147 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3151 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3156 (define_insn "zero_extendsidi2_32"
3157 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3158 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3159 (clobber (reg:CC FLAGS_REG))]
3165 movd\t{%1, %0|%0, %1}
3166 movd\t{%1, %0|%0, %1}"
3167 [(set_attr "mode" "SI,SI,SI,DI,TI")
3168 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3170 (define_insn "zero_extendsidi2_rex64"
3171 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3172 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
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")
3210 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3212 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3213 [(set_attr "type" "imovx")
3214 (set_attr "mode" "DI")])
3216 (define_insn "zero_extendqidi2"
3217 [(set (match_operand:DI 0 "register_operand" "=r")
3218 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3220 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3221 [(set_attr "type" "imovx")
3222 (set_attr "mode" "DI")])
3224 ;; Sign extension instructions
3226 (define_expand "extendsidi2"
3227 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3228 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3229 (clobber (reg:CC FLAGS_REG))
3230 (clobber (match_scratch:SI 2 ""))])]
3235 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3240 (define_insn "*extendsidi2_1"
3241 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3242 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3243 (clobber (reg:CC FLAGS_REG))
3244 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3248 (define_insn "extendsidi2_rex64"
3249 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3250 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3254 movs{lq|x}\t{%1,%0|%0, %1}"
3255 [(set_attr "type" "imovx")
3256 (set_attr "mode" "DI")
3257 (set_attr "prefix_0f" "0")
3258 (set_attr "modrm" "0,1")])
3260 (define_insn "extendhidi2"
3261 [(set (match_operand:DI 0 "register_operand" "=r")
3262 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3264 "movs{wq|x}\t{%1,%0|%0, %1}"
3265 [(set_attr "type" "imovx")
3266 (set_attr "mode" "DI")])
3268 (define_insn "extendqidi2"
3269 [(set (match_operand:DI 0 "register_operand" "=r")
3270 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3272 "movs{bq|x}\t{%1,%0|%0, %1}"
3273 [(set_attr "type" "imovx")
3274 (set_attr "mode" "DI")])
3276 ;; Extend to memory case when source register does die.
3278 [(set (match_operand:DI 0 "memory_operand" "")
3279 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3280 (clobber (reg:CC FLAGS_REG))
3281 (clobber (match_operand:SI 2 "register_operand" ""))]
3283 && dead_or_set_p (insn, operands[1])
3284 && !reg_mentioned_p (operands[1], operands[0]))"
3285 [(set (match_dup 3) (match_dup 1))
3286 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3287 (clobber (reg:CC FLAGS_REG))])
3288 (set (match_dup 4) (match_dup 1))]
3289 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3291 ;; Extend to memory case when source register does not die.
3293 [(set (match_operand:DI 0 "memory_operand" "")
3294 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3295 (clobber (reg:CC FLAGS_REG))
3296 (clobber (match_operand:SI 2 "register_operand" ""))]
3300 split_di (&operands[0], 1, &operands[3], &operands[4]);
3302 emit_move_insn (operands[3], operands[1]);
3304 /* Generate a cltd if possible and doing so it profitable. */
3305 if (true_regnum (operands[1]) == 0
3306 && true_regnum (operands[2]) == 1
3307 && (optimize_size || TARGET_USE_CLTD))
3309 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3313 emit_move_insn (operands[2], operands[1]);
3314 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3316 emit_move_insn (operands[4], operands[2]);
3320 ;; Extend to register case. Optimize case where source and destination
3321 ;; registers match and cases where we can use cltd.
3323 [(set (match_operand:DI 0 "register_operand" "")
3324 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3325 (clobber (reg:CC FLAGS_REG))
3326 (clobber (match_scratch:SI 2 ""))]
3330 split_di (&operands[0], 1, &operands[3], &operands[4]);
3332 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3333 emit_move_insn (operands[3], operands[1]);
3335 /* Generate a cltd if possible and doing so it profitable. */
3336 if (true_regnum (operands[3]) == 0
3337 && (optimize_size || TARGET_USE_CLTD))
3339 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3343 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3344 emit_move_insn (operands[4], operands[1]);
3346 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3350 (define_insn "extendhisi2"
3351 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3352 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3355 switch (get_attr_prefix_0f (insn))
3358 return "{cwtl|cwde}";
3360 return "movs{wl|x}\t{%1,%0|%0, %1}";
3363 [(set_attr "type" "imovx")
3364 (set_attr "mode" "SI")
3365 (set (attr "prefix_0f")
3366 ;; movsx is short decodable while cwtl is vector decoded.
3367 (if_then_else (and (eq_attr "cpu" "!k6")
3368 (eq_attr "alternative" "0"))
3370 (const_string "1")))
3372 (if_then_else (eq_attr "prefix_0f" "0")
3374 (const_string "1")))])
3376 (define_insn "*extendhisi2_zext"
3377 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3379 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3382 switch (get_attr_prefix_0f (insn))
3385 return "{cwtl|cwde}";
3387 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3390 [(set_attr "type" "imovx")
3391 (set_attr "mode" "SI")
3392 (set (attr "prefix_0f")
3393 ;; movsx is short decodable while cwtl is vector decoded.
3394 (if_then_else (and (eq_attr "cpu" "!k6")
3395 (eq_attr "alternative" "0"))
3397 (const_string "1")))
3399 (if_then_else (eq_attr "prefix_0f" "0")
3401 (const_string "1")))])
3403 (define_insn "extendqihi2"
3404 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3405 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3408 switch (get_attr_prefix_0f (insn))
3411 return "{cbtw|cbw}";
3413 return "movs{bw|x}\t{%1,%0|%0, %1}";
3416 [(set_attr "type" "imovx")
3417 (set_attr "mode" "HI")
3418 (set (attr "prefix_0f")
3419 ;; movsx is short decodable while cwtl is vector decoded.
3420 (if_then_else (and (eq_attr "cpu" "!k6")
3421 (eq_attr "alternative" "0"))
3423 (const_string "1")))
3425 (if_then_else (eq_attr "prefix_0f" "0")
3427 (const_string "1")))])
3429 (define_insn "extendqisi2"
3430 [(set (match_operand:SI 0 "register_operand" "=r")
3431 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3433 "movs{bl|x}\t{%1,%0|%0, %1}"
3434 [(set_attr "type" "imovx")
3435 (set_attr "mode" "SI")])
3437 (define_insn "*extendqisi2_zext"
3438 [(set (match_operand:DI 0 "register_operand" "=r")
3440 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3442 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3443 [(set_attr "type" "imovx")
3444 (set_attr "mode" "SI")])
3446 ;; Conversions between float and double.
3448 ;; These are all no-ops in the model used for the 80387. So just
3451 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3452 (define_insn "*dummy_extendsfdf2"
3453 [(set (match_operand:DF 0 "push_operand" "=<")
3454 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3459 [(set (match_operand:DF 0 "push_operand" "")
3460 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3462 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3463 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3466 [(set (match_operand:DF 0 "push_operand" "")
3467 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3469 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3470 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3472 (define_insn "*dummy_extendsfxf2"
3473 [(set (match_operand:XF 0 "push_operand" "=<")
3474 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3479 [(set (match_operand:XF 0 "push_operand" "")
3480 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3482 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3483 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3484 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3487 [(set (match_operand:XF 0 "push_operand" "")
3488 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3490 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3491 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3492 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3495 [(set (match_operand:XF 0 "push_operand" "")
3496 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3498 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3499 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3500 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3503 [(set (match_operand:XF 0 "push_operand" "")
3504 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3506 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3507 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3508 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3510 (define_expand "extendsfdf2"
3511 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3512 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3513 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3515 /* ??? Needed for compress_float_constant since all fp constants
3516 are LEGITIMATE_CONSTANT_P. */
3517 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3518 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3519 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3520 operands[1] = force_reg (SFmode, operands[1]);
3523 (define_insn "*extendsfdf2_mixed"
3524 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3525 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3526 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3527 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3529 switch (which_alternative)
3532 return output_387_reg_move (insn, operands);
3535 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3536 return "fstp%z0\t%y0";
3538 return "fst%z0\t%y0";
3541 return "cvtss2sd\t{%1, %0|%0, %1}";
3547 [(set_attr "type" "fmov,fmov,ssecvt")
3548 (set_attr "mode" "SF,XF,DF")])
3550 (define_insn "*extendsfdf2_sse"
3551 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3552 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3553 "TARGET_SSE2 && TARGET_SSE_MATH
3554 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3555 "cvtss2sd\t{%1, %0|%0, %1}"
3556 [(set_attr "type" "ssecvt")
3557 (set_attr "mode" "DF")])
3559 (define_insn "*extendsfdf2_i387"
3560 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3561 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3563 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3565 switch (which_alternative)
3568 return output_387_reg_move (insn, operands);
3571 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3572 return "fstp%z0\t%y0";
3574 return "fst%z0\t%y0";
3580 [(set_attr "type" "fmov")
3581 (set_attr "mode" "SF,XF")])
3583 (define_expand "extendsfxf2"
3584 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3585 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3588 /* ??? Needed for compress_float_constant since all fp constants
3589 are LEGITIMATE_CONSTANT_P. */
3590 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3591 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3592 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3593 operands[1] = force_reg (SFmode, operands[1]);
3596 (define_insn "*extendsfxf2_i387"
3597 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3598 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3600 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3602 switch (which_alternative)
3605 return output_387_reg_move (insn, operands);
3608 /* There is no non-popping store to memory for XFmode. So if
3609 we need one, follow the store with a load. */
3610 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3611 return "fstp%z0\t%y0";
3613 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3619 [(set_attr "type" "fmov")
3620 (set_attr "mode" "SF,XF")])
3622 (define_expand "extenddfxf2"
3623 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3624 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3627 /* ??? Needed for compress_float_constant since all fp constants
3628 are LEGITIMATE_CONSTANT_P. */
3629 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3630 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3631 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3632 operands[1] = force_reg (DFmode, operands[1]);
3635 (define_insn "*extenddfxf2_i387"
3636 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3637 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3639 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3641 switch (which_alternative)
3644 return output_387_reg_move (insn, operands);
3647 /* There is no non-popping store to memory for XFmode. So if
3648 we need one, follow the store with a load. */
3649 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3650 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3652 return "fstp%z0\t%y0";
3658 [(set_attr "type" "fmov")
3659 (set_attr "mode" "DF,XF")])
3661 ;; %%% This seems bad bad news.
3662 ;; This cannot output into an f-reg because there is no way to be sure
3663 ;; of truncating in that case. Otherwise this is just like a simple move
3664 ;; insn. So we pretend we can output to a reg in order to get better
3665 ;; register preferencing, but we really use a stack slot.
3667 ;; Conversion from DFmode to SFmode.
3669 (define_expand "truncdfsf2"
3670 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3672 (match_operand:DF 1 "nonimmediate_operand" "")))]
3673 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3675 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3676 operands[1] = force_reg (DFmode, operands[1]);
3678 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3680 else if (flag_unsafe_math_optimizations)
3684 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3685 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3690 (define_expand "truncdfsf2_with_temp"
3691 [(parallel [(set (match_operand:SF 0 "" "")
3692 (float_truncate:SF (match_operand:DF 1 "" "")))
3693 (clobber (match_operand:SF 2 "" ""))])]
3696 (define_insn "*truncdfsf_fast_mixed"
3697 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3699 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3700 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3702 switch (which_alternative)
3705 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3706 return "fstp%z0\t%y0";
3708 return "fst%z0\t%y0";
3710 return output_387_reg_move (insn, operands);
3712 return "cvtsd2ss\t{%1, %0|%0, %1}";
3717 [(set_attr "type" "fmov,fmov,ssecvt")
3718 (set_attr "mode" "SF")])
3720 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3721 ;; because nothing we do here is unsafe.
3722 (define_insn "*truncdfsf_fast_sse"
3723 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3725 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3726 "TARGET_SSE2 && TARGET_SSE_MATH"
3727 "cvtsd2ss\t{%1, %0|%0, %1}"
3728 [(set_attr "type" "ssecvt")
3729 (set_attr "mode" "SF")])
3731 (define_insn "*truncdfsf_fast_i387"
3732 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3734 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3735 "TARGET_80387 && flag_unsafe_math_optimizations"
3736 "* return output_387_reg_move (insn, operands);"
3737 [(set_attr "type" "fmov")
3738 (set_attr "mode" "SF")])
3740 (define_insn "*truncdfsf_mixed"
3741 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3743 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3744 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3745 "TARGET_MIX_SSE_I387"
3747 switch (which_alternative)
3750 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3751 return "fstp%z0\t%y0";
3753 return "fst%z0\t%y0";
3757 return "cvtsd2ss\t{%1, %0|%0, %1}";
3762 [(set_attr "type" "fmov,multi,ssecvt")
3763 (set_attr "unit" "*,i387,*")
3764 (set_attr "mode" "SF")])
3766 (define_insn "*truncdfsf_i387"
3767 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3769 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3770 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3773 switch (which_alternative)
3776 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3777 return "fstp%z0\t%y0";
3779 return "fst%z0\t%y0";
3786 [(set_attr "type" "fmov,multi")
3787 (set_attr "unit" "*,i387")
3788 (set_attr "mode" "SF")])
3790 (define_insn "*truncdfsf2_i387_1"
3791 [(set (match_operand:SF 0 "memory_operand" "=m")
3793 (match_operand:DF 1 "register_operand" "f")))]
3795 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3796 && !TARGET_MIX_SSE_I387"
3798 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3799 return "fstp%z0\t%y0";
3801 return "fst%z0\t%y0";
3803 [(set_attr "type" "fmov")
3804 (set_attr "mode" "SF")])
3807 [(set (match_operand:SF 0 "register_operand" "")
3809 (match_operand:DF 1 "fp_register_operand" "")))
3810 (clobber (match_operand 2 "" ""))]
3812 [(set (match_dup 2) (match_dup 1))
3813 (set (match_dup 0) (match_dup 2))]
3815 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3818 ;; Conversion from XFmode to SFmode.
3820 (define_expand "truncxfsf2"
3821 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3823 (match_operand:XF 1 "register_operand" "")))
3824 (clobber (match_dup 2))])]
3827 if (flag_unsafe_math_optimizations)
3829 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3830 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3831 if (reg != operands[0])
3832 emit_move_insn (operands[0], reg);
3836 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3839 (define_insn "*truncxfsf2_mixed"
3840 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3842 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3843 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3844 "TARGET_MIX_SSE_I387"
3846 gcc_assert (!which_alternative);
3847 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3848 return "fstp%z0\t%y0";
3850 return "fst%z0\t%y0";
3852 [(set_attr "type" "fmov,multi,multi,multi")
3853 (set_attr "unit" "*,i387,i387,i387")
3854 (set_attr "mode" "SF")])
3856 (define_insn "truncxfsf2_i387_noop"
3857 [(set (match_operand:SF 0 "register_operand" "=f")
3858 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3859 "TARGET_80387 && flag_unsafe_math_optimizations"
3861 return output_387_reg_move (insn, operands);
3863 [(set_attr "type" "fmov")
3864 (set_attr "mode" "SF")])
3866 (define_insn "*truncxfsf2_i387"
3867 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3869 (match_operand:XF 1 "register_operand" "f,f,f")))
3870 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3873 gcc_assert (!which_alternative);
3874 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3875 return "fstp%z0\t%y0";
3877 return "fst%z0\t%y0";
3879 [(set_attr "type" "fmov,multi,multi")
3880 (set_attr "unit" "*,i387,i387")
3881 (set_attr "mode" "SF")])
3883 (define_insn "*truncxfsf2_i387_1"
3884 [(set (match_operand:SF 0 "memory_operand" "=m")
3886 (match_operand:XF 1 "register_operand" "f")))]
3889 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3890 return "fstp%z0\t%y0";
3892 return "fst%z0\t%y0";
3894 [(set_attr "type" "fmov")
3895 (set_attr "mode" "SF")])
3898 [(set (match_operand:SF 0 "register_operand" "")
3900 (match_operand:XF 1 "register_operand" "")))
3901 (clobber (match_operand:SF 2 "memory_operand" ""))]
3902 "TARGET_80387 && reload_completed"
3903 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3904 (set (match_dup 0) (match_dup 2))]
3908 [(set (match_operand:SF 0 "memory_operand" "")
3910 (match_operand:XF 1 "register_operand" "")))
3911 (clobber (match_operand:SF 2 "memory_operand" ""))]
3913 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3916 ;; Conversion from XFmode to DFmode.
3918 (define_expand "truncxfdf2"
3919 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3921 (match_operand:XF 1 "register_operand" "")))
3922 (clobber (match_dup 2))])]
3925 if (flag_unsafe_math_optimizations)
3927 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3928 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3929 if (reg != operands[0])
3930 emit_move_insn (operands[0], reg);
3934 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3937 (define_insn "*truncxfdf2_mixed"
3938 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3940 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3941 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3942 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3944 gcc_assert (!which_alternative);
3945 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3946 return "fstp%z0\t%y0";
3948 return "fst%z0\t%y0";
3950 [(set_attr "type" "fmov,multi,multi,multi")
3951 (set_attr "unit" "*,i387,i387,i387")
3952 (set_attr "mode" "DF")])
3954 (define_insn "truncxfdf2_i387_noop"
3955 [(set (match_operand:DF 0 "register_operand" "=f")
3956 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3957 "TARGET_80387 && flag_unsafe_math_optimizations"
3959 return output_387_reg_move (insn, operands);
3961 [(set_attr "type" "fmov")
3962 (set_attr "mode" "DF")])
3964 (define_insn "*truncxfdf2_i387"
3965 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3967 (match_operand:XF 1 "register_operand" "f,f,f")))
3968 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3971 gcc_assert (!which_alternative);
3972 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3973 return "fstp%z0\t%y0";
3975 return "fst%z0\t%y0";
3977 [(set_attr "type" "fmov,multi,multi")
3978 (set_attr "unit" "*,i387,i387")
3979 (set_attr "mode" "DF")])
3981 (define_insn "*truncxfdf2_i387_1"
3982 [(set (match_operand:DF 0 "memory_operand" "=m")
3984 (match_operand:XF 1 "register_operand" "f")))]
3987 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3988 return "fstp%z0\t%y0";
3990 return "fst%z0\t%y0";
3992 [(set_attr "type" "fmov")
3993 (set_attr "mode" "DF")])
3996 [(set (match_operand:DF 0 "register_operand" "")
3998 (match_operand:XF 1 "register_operand" "")))
3999 (clobber (match_operand:DF 2 "memory_operand" ""))]
4000 "TARGET_80387 && reload_completed"
4001 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4002 (set (match_dup 0) (match_dup 2))]
4006 [(set (match_operand:DF 0 "memory_operand" "")
4008 (match_operand:XF 1 "register_operand" "")))
4009 (clobber (match_operand:DF 2 "memory_operand" ""))]
4011 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4014 ;; Signed conversion to DImode.
4016 (define_expand "fix_truncxfdi2"
4017 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4018 (fix:DI (match_operand:XF 1 "register_operand" "")))
4019 (clobber (reg:CC FLAGS_REG))])]
4024 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4029 (define_expand "fix_trunc<mode>di2"
4030 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4031 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4032 (clobber (reg:CC FLAGS_REG))])]
4033 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4036 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4038 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4041 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4043 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4044 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4045 if (out != operands[0])
4046 emit_move_insn (operands[0], out);
4051 ;; Signed conversion to SImode.
4053 (define_expand "fix_truncxfsi2"
4054 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4055 (fix:SI (match_operand:XF 1 "register_operand" "")))
4056 (clobber (reg:CC FLAGS_REG))])]
4061 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4066 (define_expand "fix_trunc<mode>si2"
4067 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4068 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4069 (clobber (reg:CC FLAGS_REG))])]
4070 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4073 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4075 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4078 if (SSE_FLOAT_MODE_P (<MODE>mode))
4080 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4081 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4082 if (out != operands[0])
4083 emit_move_insn (operands[0], out);
4088 ;; Signed conversion to HImode.
4090 (define_expand "fix_trunc<mode>hi2"
4091 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4092 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4093 (clobber (reg:CC FLAGS_REG))])]
4095 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4099 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4104 ;; When SSE is available, it is always faster to use it!
4105 (define_insn "fix_truncsfdi_sse"
4106 [(set (match_operand:DI 0 "register_operand" "=r,r")
4107 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4108 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4109 "cvttss2si{q}\t{%1, %0|%0, %1}"
4110 [(set_attr "type" "sseicvt")
4111 (set_attr "mode" "SF")
4112 (set_attr "athlon_decode" "double,vector")])
4114 (define_insn "fix_truncdfdi_sse"
4115 [(set (match_operand:DI 0 "register_operand" "=r,r")
4116 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4117 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4118 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4119 [(set_attr "type" "sseicvt")
4120 (set_attr "mode" "DF")
4121 (set_attr "athlon_decode" "double,vector")])
4123 (define_insn "fix_truncsfsi_sse"
4124 [(set (match_operand:SI 0 "register_operand" "=r,r")
4125 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4126 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4127 "cvttss2si\t{%1, %0|%0, %1}"
4128 [(set_attr "type" "sseicvt")
4129 (set_attr "mode" "DF")
4130 (set_attr "athlon_decode" "double,vector")])
4132 (define_insn "fix_truncdfsi_sse"
4133 [(set (match_operand:SI 0 "register_operand" "=r,r")
4134 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4135 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4136 "cvttsd2si\t{%1, %0|%0, %1}"
4137 [(set_attr "type" "sseicvt")
4138 (set_attr "mode" "DF")
4139 (set_attr "athlon_decode" "double,vector")])
4141 ;; Avoid vector decoded forms of the instruction.
4143 [(match_scratch:DF 2 "Y")
4144 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4145 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4146 "TARGET_K8 && !optimize_size"
4147 [(set (match_dup 2) (match_dup 1))
4148 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4152 [(match_scratch:SF 2 "x")
4153 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4154 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4155 "TARGET_K8 && !optimize_size"
4156 [(set (match_dup 2) (match_dup 1))
4157 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4160 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4161 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4162 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4164 && FLOAT_MODE_P (GET_MODE (operands[1]))
4165 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4166 && (TARGET_64BIT || <MODE>mode != DImode))
4168 && !(reload_completed || reload_in_progress)"
4173 if (memory_operand (operands[0], VOIDmode))
4174 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4177 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4178 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4184 [(set_attr "type" "fisttp")
4185 (set_attr "mode" "<MODE>")])
4187 (define_insn "fix_trunc<mode>_i387_fisttp"
4188 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4189 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4190 (clobber (match_scratch:XF 2 "=&1f"))]
4192 && FLOAT_MODE_P (GET_MODE (operands[1]))
4193 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4194 && (TARGET_64BIT || <MODE>mode != DImode))
4195 && TARGET_SSE_MATH)"
4196 "* return output_fix_trunc (insn, operands, 1);"
4197 [(set_attr "type" "fisttp")
4198 (set_attr "mode" "<MODE>")])
4200 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4201 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4202 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4203 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4204 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4206 && FLOAT_MODE_P (GET_MODE (operands[1]))
4207 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4208 && (TARGET_64BIT || <MODE>mode != DImode))
4209 && TARGET_SSE_MATH)"
4211 [(set_attr "type" "fisttp")
4212 (set_attr "mode" "<MODE>")])
4215 [(set (match_operand:X87MODEI 0 "register_operand" "")
4216 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4217 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4218 (clobber (match_scratch 3 ""))]
4220 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4221 (clobber (match_dup 3))])
4222 (set (match_dup 0) (match_dup 2))]
4226 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4227 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4228 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4229 (clobber (match_scratch 3 ""))]
4231 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4232 (clobber (match_dup 3))])]
4235 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4236 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4237 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4238 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4239 ;; function in i386.c.
4240 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4241 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4242 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4243 (clobber (reg:CC FLAGS_REG))]
4244 "TARGET_80387 && !TARGET_FISTTP
4245 && FLOAT_MODE_P (GET_MODE (operands[1]))
4246 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4247 && (TARGET_64BIT || <MODE>mode != DImode))
4248 && !(reload_completed || reload_in_progress)"
4253 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4255 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4256 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4257 if (memory_operand (operands[0], VOIDmode))
4258 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4259 operands[2], operands[3]));
4262 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4263 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4264 operands[2], operands[3],
4269 [(set_attr "type" "fistp")
4270 (set_attr "i387_cw" "trunc")
4271 (set_attr "mode" "<MODE>")])
4273 (define_insn "fix_truncdi_i387"
4274 [(set (match_operand:DI 0 "memory_operand" "=m")
4275 (fix:DI (match_operand 1 "register_operand" "f")))
4276 (use (match_operand:HI 2 "memory_operand" "m"))
4277 (use (match_operand:HI 3 "memory_operand" "m"))
4278 (clobber (match_scratch:XF 4 "=&1f"))]
4279 "TARGET_80387 && !TARGET_FISTTP
4280 && FLOAT_MODE_P (GET_MODE (operands[1]))
4281 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4282 "* return output_fix_trunc (insn, operands, 0);"
4283 [(set_attr "type" "fistp")
4284 (set_attr "i387_cw" "trunc")
4285 (set_attr "mode" "DI")])
4287 (define_insn "fix_truncdi_i387_with_temp"
4288 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4289 (fix:DI (match_operand 1 "register_operand" "f,f")))
4290 (use (match_operand:HI 2 "memory_operand" "m,m"))
4291 (use (match_operand:HI 3 "memory_operand" "m,m"))
4292 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4293 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4294 "TARGET_80387 && !TARGET_FISTTP
4295 && FLOAT_MODE_P (GET_MODE (operands[1]))
4296 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4298 [(set_attr "type" "fistp")
4299 (set_attr "i387_cw" "trunc")
4300 (set_attr "mode" "DI")])
4303 [(set (match_operand:DI 0 "register_operand" "")
4304 (fix:DI (match_operand 1 "register_operand" "")))
4305 (use (match_operand:HI 2 "memory_operand" ""))
4306 (use (match_operand:HI 3 "memory_operand" ""))
4307 (clobber (match_operand:DI 4 "memory_operand" ""))
4308 (clobber (match_scratch 5 ""))]
4310 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4313 (clobber (match_dup 5))])
4314 (set (match_dup 0) (match_dup 4))]
4318 [(set (match_operand:DI 0 "memory_operand" "")
4319 (fix:DI (match_operand 1 "register_operand" "")))
4320 (use (match_operand:HI 2 "memory_operand" ""))
4321 (use (match_operand:HI 3 "memory_operand" ""))
4322 (clobber (match_operand:DI 4 "memory_operand" ""))
4323 (clobber (match_scratch 5 ""))]
4325 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4328 (clobber (match_dup 5))])]
4331 (define_insn "fix_trunc<mode>_i387"
4332 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4333 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4334 (use (match_operand:HI 2 "memory_operand" "m"))
4335 (use (match_operand:HI 3 "memory_operand" "m"))]
4336 "TARGET_80387 && !TARGET_FISTTP
4337 && FLOAT_MODE_P (GET_MODE (operands[1]))
4338 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4339 "* return output_fix_trunc (insn, operands, 0);"
4340 [(set_attr "type" "fistp")
4341 (set_attr "i387_cw" "trunc")
4342 (set_attr "mode" "<MODE>")])
4344 (define_insn "fix_trunc<mode>_i387_with_temp"
4345 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4346 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4347 (use (match_operand:HI 2 "memory_operand" "m,m"))
4348 (use (match_operand:HI 3 "memory_operand" "m,m"))
4349 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4350 "TARGET_80387 && !TARGET_FISTTP
4351 && FLOAT_MODE_P (GET_MODE (operands[1]))
4352 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4354 [(set_attr "type" "fistp")
4355 (set_attr "i387_cw" "trunc")
4356 (set_attr "mode" "<MODE>")])
4359 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4360 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4361 (use (match_operand:HI 2 "memory_operand" ""))
4362 (use (match_operand:HI 3 "memory_operand" ""))
4363 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4365 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4367 (use (match_dup 3))])
4368 (set (match_dup 0) (match_dup 4))]
4372 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4373 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4374 (use (match_operand:HI 2 "memory_operand" ""))
4375 (use (match_operand:HI 3 "memory_operand" ""))
4376 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4378 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4380 (use (match_dup 3))])]
4383 (define_insn "x86_fnstcw_1"
4384 [(set (match_operand:HI 0 "memory_operand" "=m")
4385 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4388 [(set_attr "length" "2")
4389 (set_attr "mode" "HI")
4390 (set_attr "unit" "i387")])
4392 (define_insn "x86_fldcw_1"
4393 [(set (reg:HI FPSR_REG)
4394 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4397 [(set_attr "length" "2")
4398 (set_attr "mode" "HI")
4399 (set_attr "unit" "i387")
4400 (set_attr "athlon_decode" "vector")])
4402 ;; Conversion between fixed point and floating point.
4404 ;; Even though we only accept memory inputs, the backend _really_
4405 ;; wants to be able to do this between registers.
4407 (define_expand "floathisf2"
4408 [(set (match_operand:SF 0 "register_operand" "")
4409 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4410 "TARGET_80387 || TARGET_SSE_MATH"
4412 if (TARGET_SSE_MATH)
4414 emit_insn (gen_floatsisf2 (operands[0],
4415 convert_to_mode (SImode, operands[1], 0)));
4420 (define_insn "*floathisf2_i387"
4421 [(set (match_operand:SF 0 "register_operand" "=f,f")
4422 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4423 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4427 [(set_attr "type" "fmov,multi")
4428 (set_attr "mode" "SF")
4429 (set_attr "unit" "*,i387")
4430 (set_attr "fp_int_src" "true")])
4432 (define_expand "floatsisf2"
4433 [(set (match_operand:SF 0 "register_operand" "")
4434 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4435 "TARGET_80387 || TARGET_SSE_MATH"
4438 (define_insn "*floatsisf2_mixed"
4439 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4440 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4441 "TARGET_MIX_SSE_I387"
4445 cvtsi2ss\t{%1, %0|%0, %1}
4446 cvtsi2ss\t{%1, %0|%0, %1}"
4447 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4448 (set_attr "mode" "SF")
4449 (set_attr "unit" "*,i387,*,*")
4450 (set_attr "athlon_decode" "*,*,vector,double")
4451 (set_attr "fp_int_src" "true")])
4453 (define_insn "*floatsisf2_sse"
4454 [(set (match_operand:SF 0 "register_operand" "=x,x")
4455 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4457 "cvtsi2ss\t{%1, %0|%0, %1}"
4458 [(set_attr "type" "sseicvt")
4459 (set_attr "mode" "SF")
4460 (set_attr "athlon_decode" "vector,double")
4461 (set_attr "fp_int_src" "true")])
4463 (define_insn "*floatsisf2_i387"
4464 [(set (match_operand:SF 0 "register_operand" "=f,f")
4465 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4470 [(set_attr "type" "fmov,multi")
4471 (set_attr "mode" "SF")
4472 (set_attr "unit" "*,i387")
4473 (set_attr "fp_int_src" "true")])
4475 (define_expand "floatdisf2"
4476 [(set (match_operand:SF 0 "register_operand" "")
4477 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4478 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4481 (define_insn "*floatdisf2_mixed"
4482 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4483 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4484 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4488 cvtsi2ss{q}\t{%1, %0|%0, %1}
4489 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4490 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4491 (set_attr "mode" "SF")
4492 (set_attr "unit" "*,i387,*,*")
4493 (set_attr "athlon_decode" "*,*,vector,double")
4494 (set_attr "fp_int_src" "true")])
4496 (define_insn "*floatdisf2_sse"
4497 [(set (match_operand:SF 0 "register_operand" "=x,x")
4498 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4499 "TARGET_64BIT && TARGET_SSE_MATH"
4500 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4501 [(set_attr "type" "sseicvt")
4502 (set_attr "mode" "SF")
4503 (set_attr "athlon_decode" "vector,double")
4504 (set_attr "fp_int_src" "true")])
4506 (define_insn "*floatdisf2_i387"
4507 [(set (match_operand:SF 0 "register_operand" "=f,f")
4508 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4513 [(set_attr "type" "fmov,multi")
4514 (set_attr "mode" "SF")
4515 (set_attr "unit" "*,i387")
4516 (set_attr "fp_int_src" "true")])
4518 (define_expand "floathidf2"
4519 [(set (match_operand:DF 0 "register_operand" "")
4520 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4521 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4523 if (TARGET_SSE2 && TARGET_SSE_MATH)
4525 emit_insn (gen_floatsidf2 (operands[0],
4526 convert_to_mode (SImode, operands[1], 0)));
4531 (define_insn "*floathidf2_i387"
4532 [(set (match_operand:DF 0 "register_operand" "=f,f")
4533 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4534 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4538 [(set_attr "type" "fmov,multi")
4539 (set_attr "mode" "DF")
4540 (set_attr "unit" "*,i387")
4541 (set_attr "fp_int_src" "true")])
4543 (define_expand "floatsidf2"
4544 [(set (match_operand:DF 0 "register_operand" "")
4545 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4546 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4549 (define_insn "*floatsidf2_mixed"
4550 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4551 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4552 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4556 cvtsi2sd\t{%1, %0|%0, %1}
4557 cvtsi2sd\t{%1, %0|%0, %1}"
4558 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4559 (set_attr "mode" "DF")
4560 (set_attr "unit" "*,i387,*,*")
4561 (set_attr "athlon_decode" "*,*,double,direct")
4562 (set_attr "fp_int_src" "true")])
4564 (define_insn "*floatsidf2_sse"
4565 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4566 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4567 "TARGET_SSE2 && TARGET_SSE_MATH"
4568 "cvtsi2sd\t{%1, %0|%0, %1}"
4569 [(set_attr "type" "sseicvt")
4570 (set_attr "mode" "DF")
4571 (set_attr "athlon_decode" "double,direct")
4572 (set_attr "fp_int_src" "true")])
4574 (define_insn "*floatsidf2_i387"
4575 [(set (match_operand:DF 0 "register_operand" "=f,f")
4576 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4581 [(set_attr "type" "fmov,multi")
4582 (set_attr "mode" "DF")
4583 (set_attr "unit" "*,i387")
4584 (set_attr "fp_int_src" "true")])
4586 (define_expand "floatdidf2"
4587 [(set (match_operand:DF 0 "register_operand" "")
4588 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4589 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4592 (define_insn "*floatdidf2_mixed"
4593 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4594 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4595 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4599 cvtsi2sd{q}\t{%1, %0|%0, %1}
4600 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4601 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4602 (set_attr "mode" "DF")
4603 (set_attr "unit" "*,i387,*,*")
4604 (set_attr "athlon_decode" "*,*,double,direct")
4605 (set_attr "fp_int_src" "true")])
4607 (define_insn "*floatdidf2_sse"
4608 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4609 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4610 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4611 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4612 [(set_attr "type" "sseicvt")
4613 (set_attr "mode" "DF")
4614 (set_attr "athlon_decode" "double,direct")
4615 (set_attr "fp_int_src" "true")])
4617 (define_insn "*floatdidf2_i387"
4618 [(set (match_operand:DF 0 "register_operand" "=f,f")
4619 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4624 [(set_attr "type" "fmov,multi")
4625 (set_attr "mode" "DF")
4626 (set_attr "unit" "*,i387")
4627 (set_attr "fp_int_src" "true")])
4629 (define_insn "floathixf2"
4630 [(set (match_operand:XF 0 "register_operand" "=f,f")
4631 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4636 [(set_attr "type" "fmov,multi")
4637 (set_attr "mode" "XF")
4638 (set_attr "unit" "*,i387")
4639 (set_attr "fp_int_src" "true")])
4641 (define_insn "floatsixf2"
4642 [(set (match_operand:XF 0 "register_operand" "=f,f")
4643 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4648 [(set_attr "type" "fmov,multi")
4649 (set_attr "mode" "XF")
4650 (set_attr "unit" "*,i387")
4651 (set_attr "fp_int_src" "true")])
4653 (define_insn "floatdixf2"
4654 [(set (match_operand:XF 0 "register_operand" "=f,f")
4655 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4660 [(set_attr "type" "fmov,multi")
4661 (set_attr "mode" "XF")
4662 (set_attr "unit" "*,i387")
4663 (set_attr "fp_int_src" "true")])
4665 ;; %%% Kill these when reload knows how to do it.
4667 [(set (match_operand 0 "fp_register_operand" "")
4668 (float (match_operand 1 "register_operand" "")))]
4671 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4674 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4675 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4676 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4677 ix86_free_from_memory (GET_MODE (operands[1]));
4681 (define_expand "floatunssisf2"
4682 [(use (match_operand:SF 0 "register_operand" ""))
4683 (use (match_operand:SI 1 "register_operand" ""))]
4684 "!TARGET_64BIT && TARGET_SSE_MATH"
4685 "x86_emit_floatuns (operands); DONE;")
4687 (define_expand "floatunsdisf2"
4688 [(use (match_operand:SF 0 "register_operand" ""))
4689 (use (match_operand:DI 1 "register_operand" ""))]
4690 "TARGET_64BIT && TARGET_SSE_MATH"
4691 "x86_emit_floatuns (operands); DONE;")
4693 (define_expand "floatunsdidf2"
4694 [(use (match_operand:DF 0 "register_operand" ""))
4695 (use (match_operand:DI 1 "register_operand" ""))]
4696 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4697 "x86_emit_floatuns (operands); DONE;")
4699 ;; SSE extract/set expanders
4704 ;; %%% splits for addditi3
4706 (define_expand "addti3"
4707 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4708 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4709 (match_operand:TI 2 "x86_64_general_operand" "")))
4710 (clobber (reg:CC FLAGS_REG))]
4712 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4714 (define_insn "*addti3_1"
4715 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4716 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4717 (match_operand:TI 2 "general_operand" "roiF,riF")))
4718 (clobber (reg:CC FLAGS_REG))]
4719 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4723 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4724 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4725 (match_operand:TI 2 "general_operand" "")))
4726 (clobber (reg:CC FLAGS_REG))]
4727 "TARGET_64BIT && reload_completed"
4728 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4730 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4731 (parallel [(set (match_dup 3)
4732 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4735 (clobber (reg:CC FLAGS_REG))])]
4736 "split_ti (operands+0, 1, operands+0, operands+3);
4737 split_ti (operands+1, 1, operands+1, operands+4);
4738 split_ti (operands+2, 1, operands+2, operands+5);")
4740 ;; %%% splits for addsidi3
4741 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4742 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4743 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4745 (define_expand "adddi3"
4746 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4747 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4748 (match_operand:DI 2 "x86_64_general_operand" "")))
4749 (clobber (reg:CC FLAGS_REG))]
4751 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4753 (define_insn "*adddi3_1"
4754 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4755 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4756 (match_operand:DI 2 "general_operand" "roiF,riF")))
4757 (clobber (reg:CC FLAGS_REG))]
4758 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4762 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4763 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4764 (match_operand:DI 2 "general_operand" "")))
4765 (clobber (reg:CC FLAGS_REG))]
4766 "!TARGET_64BIT && reload_completed"
4767 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4769 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4770 (parallel [(set (match_dup 3)
4771 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4774 (clobber (reg:CC FLAGS_REG))])]
4775 "split_di (operands+0, 1, operands+0, operands+3);
4776 split_di (operands+1, 1, operands+1, operands+4);
4777 split_di (operands+2, 1, operands+2, operands+5);")
4779 (define_insn "adddi3_carry_rex64"
4780 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4781 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4782 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4783 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4784 (clobber (reg:CC FLAGS_REG))]
4785 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4786 "adc{q}\t{%2, %0|%0, %2}"
4787 [(set_attr "type" "alu")
4788 (set_attr "pent_pair" "pu")
4789 (set_attr "mode" "DI")])
4791 (define_insn "*adddi3_cc_rex64"
4792 [(set (reg:CC FLAGS_REG)
4793 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4794 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4796 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4797 (plus:DI (match_dup 1) (match_dup 2)))]
4798 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4799 "add{q}\t{%2, %0|%0, %2}"
4800 [(set_attr "type" "alu")
4801 (set_attr "mode" "DI")])
4803 (define_insn "addqi3_carry"
4804 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4805 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4806 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4807 (match_operand:QI 2 "general_operand" "qi,qm")))
4808 (clobber (reg:CC FLAGS_REG))]
4809 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4810 "adc{b}\t{%2, %0|%0, %2}"
4811 [(set_attr "type" "alu")
4812 (set_attr "pent_pair" "pu")
4813 (set_attr "mode" "QI")])
4815 (define_insn "addhi3_carry"
4816 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4817 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4818 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4819 (match_operand:HI 2 "general_operand" "ri,rm")))
4820 (clobber (reg:CC FLAGS_REG))]
4821 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4822 "adc{w}\t{%2, %0|%0, %2}"
4823 [(set_attr "type" "alu")
4824 (set_attr "pent_pair" "pu")
4825 (set_attr "mode" "HI")])
4827 (define_insn "addsi3_carry"
4828 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4829 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4830 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4831 (match_operand:SI 2 "general_operand" "ri,rm")))
4832 (clobber (reg:CC FLAGS_REG))]
4833 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4834 "adc{l}\t{%2, %0|%0, %2}"
4835 [(set_attr "type" "alu")
4836 (set_attr "pent_pair" "pu")
4837 (set_attr "mode" "SI")])
4839 (define_insn "*addsi3_carry_zext"
4840 [(set (match_operand:DI 0 "register_operand" "=r")
4842 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4843 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4844 (match_operand:SI 2 "general_operand" "rim"))))
4845 (clobber (reg:CC FLAGS_REG))]
4846 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4847 "adc{l}\t{%2, %k0|%k0, %2}"
4848 [(set_attr "type" "alu")
4849 (set_attr "pent_pair" "pu")
4850 (set_attr "mode" "SI")])
4852 (define_insn "*addsi3_cc"
4853 [(set (reg:CC FLAGS_REG)
4854 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4855 (match_operand:SI 2 "general_operand" "ri,rm")]
4857 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4858 (plus:SI (match_dup 1) (match_dup 2)))]
4859 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4860 "add{l}\t{%2, %0|%0, %2}"
4861 [(set_attr "type" "alu")
4862 (set_attr "mode" "SI")])
4864 (define_insn "addqi3_cc"
4865 [(set (reg:CC FLAGS_REG)
4866 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4867 (match_operand:QI 2 "general_operand" "qi,qm")]
4869 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4870 (plus:QI (match_dup 1) (match_dup 2)))]
4871 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4872 "add{b}\t{%2, %0|%0, %2}"
4873 [(set_attr "type" "alu")
4874 (set_attr "mode" "QI")])
4876 (define_expand "addsi3"
4877 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4878 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4879 (match_operand:SI 2 "general_operand" "")))
4880 (clobber (reg:CC FLAGS_REG))])]
4882 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4884 (define_insn "*lea_1"
4885 [(set (match_operand:SI 0 "register_operand" "=r")
4886 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4888 "lea{l}\t{%a1, %0|%0, %a1}"
4889 [(set_attr "type" "lea")
4890 (set_attr "mode" "SI")])
4892 (define_insn "*lea_1_rex64"
4893 [(set (match_operand:SI 0 "register_operand" "=r")
4894 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4896 "lea{l}\t{%a1, %0|%0, %a1}"
4897 [(set_attr "type" "lea")
4898 (set_attr "mode" "SI")])
4900 (define_insn "*lea_1_zext"
4901 [(set (match_operand:DI 0 "register_operand" "=r")
4903 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4905 "lea{l}\t{%a1, %k0|%k0, %a1}"
4906 [(set_attr "type" "lea")
4907 (set_attr "mode" "SI")])
4909 (define_insn "*lea_2_rex64"
4910 [(set (match_operand:DI 0 "register_operand" "=r")
4911 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4913 "lea{q}\t{%a1, %0|%0, %a1}"
4914 [(set_attr "type" "lea")
4915 (set_attr "mode" "DI")])
4917 ;; The lea patterns for non-Pmodes needs to be matched by several
4918 ;; insns converted to real lea by splitters.
4920 (define_insn_and_split "*lea_general_1"
4921 [(set (match_operand 0 "register_operand" "=r")
4922 (plus (plus (match_operand 1 "index_register_operand" "l")
4923 (match_operand 2 "register_operand" "r"))
4924 (match_operand 3 "immediate_operand" "i")))]
4925 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4926 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4927 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4928 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4929 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4930 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4931 || GET_MODE (operands[3]) == VOIDmode)"
4933 "&& reload_completed"
4937 operands[0] = gen_lowpart (SImode, operands[0]);
4938 operands[1] = gen_lowpart (Pmode, operands[1]);
4939 operands[2] = gen_lowpart (Pmode, operands[2]);
4940 operands[3] = gen_lowpart (Pmode, operands[3]);
4941 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4943 if (Pmode != SImode)
4944 pat = gen_rtx_SUBREG (SImode, pat, 0);
4945 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4948 [(set_attr "type" "lea")
4949 (set_attr "mode" "SI")])
4951 (define_insn_and_split "*lea_general_1_zext"
4952 [(set (match_operand:DI 0 "register_operand" "=r")
4954 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4955 (match_operand:SI 2 "register_operand" "r"))
4956 (match_operand:SI 3 "immediate_operand" "i"))))]
4959 "&& reload_completed"
4961 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4963 (match_dup 3)) 0)))]
4965 operands[1] = gen_lowpart (Pmode, operands[1]);
4966 operands[2] = gen_lowpart (Pmode, operands[2]);
4967 operands[3] = gen_lowpart (Pmode, operands[3]);
4969 [(set_attr "type" "lea")
4970 (set_attr "mode" "SI")])
4972 (define_insn_and_split "*lea_general_2"
4973 [(set (match_operand 0 "register_operand" "=r")
4974 (plus (mult (match_operand 1 "index_register_operand" "l")
4975 (match_operand 2 "const248_operand" "i"))
4976 (match_operand 3 "nonmemory_operand" "ri")))]
4977 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4978 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4979 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4980 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4981 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4982 || GET_MODE (operands[3]) == VOIDmode)"
4984 "&& reload_completed"
4988 operands[0] = gen_lowpart (SImode, operands[0]);
4989 operands[1] = gen_lowpart (Pmode, operands[1]);
4990 operands[3] = gen_lowpart (Pmode, operands[3]);
4991 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4993 if (Pmode != SImode)
4994 pat = gen_rtx_SUBREG (SImode, pat, 0);
4995 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4998 [(set_attr "type" "lea")
4999 (set_attr "mode" "SI")])
5001 (define_insn_and_split "*lea_general_2_zext"
5002 [(set (match_operand:DI 0 "register_operand" "=r")
5004 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5005 (match_operand:SI 2 "const248_operand" "n"))
5006 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5009 "&& reload_completed"
5011 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5013 (match_dup 3)) 0)))]
5015 operands[1] = gen_lowpart (Pmode, operands[1]);
5016 operands[3] = gen_lowpart (Pmode, operands[3]);
5018 [(set_attr "type" "lea")
5019 (set_attr "mode" "SI")])
5021 (define_insn_and_split "*lea_general_3"
5022 [(set (match_operand 0 "register_operand" "=r")
5023 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5024 (match_operand 2 "const248_operand" "i"))
5025 (match_operand 3 "register_operand" "r"))
5026 (match_operand 4 "immediate_operand" "i")))]
5027 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5028 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5029 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5030 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5031 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5033 "&& reload_completed"
5037 operands[0] = gen_lowpart (SImode, operands[0]);
5038 operands[1] = gen_lowpart (Pmode, operands[1]);
5039 operands[3] = gen_lowpart (Pmode, operands[3]);
5040 operands[4] = gen_lowpart (Pmode, operands[4]);
5041 pat = gen_rtx_PLUS (Pmode,
5042 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5046 if (Pmode != SImode)
5047 pat = gen_rtx_SUBREG (SImode, pat, 0);
5048 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5051 [(set_attr "type" "lea")
5052 (set_attr "mode" "SI")])
5054 (define_insn_and_split "*lea_general_3_zext"
5055 [(set (match_operand:DI 0 "register_operand" "=r")
5057 (plus:SI (plus:SI (mult:SI
5058 (match_operand:SI 1 "index_register_operand" "l")
5059 (match_operand:SI 2 "const248_operand" "n"))
5060 (match_operand:SI 3 "register_operand" "r"))
5061 (match_operand:SI 4 "immediate_operand" "i"))))]
5064 "&& reload_completed"
5066 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5069 (match_dup 4)) 0)))]
5071 operands[1] = gen_lowpart (Pmode, operands[1]);
5072 operands[3] = gen_lowpart (Pmode, operands[3]);
5073 operands[4] = gen_lowpart (Pmode, operands[4]);
5075 [(set_attr "type" "lea")
5076 (set_attr "mode" "SI")])
5078 (define_insn "*adddi_1_rex64"
5079 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5080 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5081 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5082 (clobber (reg:CC FLAGS_REG))]
5083 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5085 switch (get_attr_type (insn))
5088 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5089 return "lea{q}\t{%a2, %0|%0, %a2}";
5092 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5093 if (operands[2] == const1_rtx)
5094 return "inc{q}\t%0";
5097 gcc_assert (operands[2] == constm1_rtx);
5098 return "dec{q}\t%0";
5102 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5104 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5105 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5106 if (GET_CODE (operands[2]) == CONST_INT
5107 /* Avoid overflows. */
5108 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5109 && (INTVAL (operands[2]) == 128
5110 || (INTVAL (operands[2]) < 0
5111 && INTVAL (operands[2]) != -128)))
5113 operands[2] = GEN_INT (-INTVAL (operands[2]));
5114 return "sub{q}\t{%2, %0|%0, %2}";
5116 return "add{q}\t{%2, %0|%0, %2}";
5120 (cond [(eq_attr "alternative" "2")
5121 (const_string "lea")
5122 ; Current assemblers are broken and do not allow @GOTOFF in
5123 ; ought but a memory context.
5124 (match_operand:DI 2 "pic_symbolic_operand" "")
5125 (const_string "lea")
5126 (match_operand:DI 2 "incdec_operand" "")
5127 (const_string "incdec")
5129 (const_string "alu")))
5130 (set_attr "mode" "DI")])
5132 ;; Convert lea to the lea pattern to avoid flags dependency.
5134 [(set (match_operand:DI 0 "register_operand" "")
5135 (plus:DI (match_operand:DI 1 "register_operand" "")
5136 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5137 (clobber (reg:CC FLAGS_REG))]
5138 "TARGET_64BIT && reload_completed
5139 && true_regnum (operands[0]) != true_regnum (operands[1])"
5141 (plus:DI (match_dup 1)
5145 (define_insn "*adddi_2_rex64"
5146 [(set (reg FLAGS_REG)
5148 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5149 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5151 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5152 (plus:DI (match_dup 1) (match_dup 2)))]
5153 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5154 && ix86_binary_operator_ok (PLUS, DImode, operands)
5155 /* Current assemblers are broken and do not allow @GOTOFF in
5156 ought but a memory context. */
5157 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5159 switch (get_attr_type (insn))
5162 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5163 if (operands[2] == const1_rtx)
5164 return "inc{q}\t%0";
5167 gcc_assert (operands[2] == constm1_rtx);
5168 return "dec{q}\t%0";
5172 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5173 /* ???? We ought to handle there the 32bit case too
5174 - do we need new constraint? */
5175 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5176 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5177 if (GET_CODE (operands[2]) == CONST_INT
5178 /* Avoid overflows. */
5179 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5180 && (INTVAL (operands[2]) == 128
5181 || (INTVAL (operands[2]) < 0
5182 && INTVAL (operands[2]) != -128)))
5184 operands[2] = GEN_INT (-INTVAL (operands[2]));
5185 return "sub{q}\t{%2, %0|%0, %2}";
5187 return "add{q}\t{%2, %0|%0, %2}";
5191 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5192 (const_string "incdec")
5193 (const_string "alu")))
5194 (set_attr "mode" "DI")])
5196 (define_insn "*adddi_3_rex64"
5197 [(set (reg FLAGS_REG)
5198 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5199 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5200 (clobber (match_scratch:DI 0 "=r"))]
5202 && ix86_match_ccmode (insn, CCZmode)
5203 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5204 /* Current assemblers are broken and do not allow @GOTOFF in
5205 ought but a memory context. */
5206 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5208 switch (get_attr_type (insn))
5211 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5212 if (operands[2] == const1_rtx)
5213 return "inc{q}\t%0";
5216 gcc_assert (operands[2] == constm1_rtx);
5217 return "dec{q}\t%0";
5221 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5222 /* ???? We ought to handle there the 32bit case too
5223 - do we need new constraint? */
5224 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5225 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5226 if (GET_CODE (operands[2]) == CONST_INT
5227 /* Avoid overflows. */
5228 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5229 && (INTVAL (operands[2]) == 128
5230 || (INTVAL (operands[2]) < 0
5231 && INTVAL (operands[2]) != -128)))
5233 operands[2] = GEN_INT (-INTVAL (operands[2]));
5234 return "sub{q}\t{%2, %0|%0, %2}";
5236 return "add{q}\t{%2, %0|%0, %2}";
5240 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5241 (const_string "incdec")
5242 (const_string "alu")))
5243 (set_attr "mode" "DI")])
5245 ; For comparisons against 1, -1 and 128, we may generate better code
5246 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5247 ; is matched then. We can't accept general immediate, because for
5248 ; case of overflows, the result is messed up.
5249 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5251 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5252 ; only for comparisons not depending on it.
5253 (define_insn "*adddi_4_rex64"
5254 [(set (reg FLAGS_REG)
5255 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5256 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5257 (clobber (match_scratch:DI 0 "=rm"))]
5259 && ix86_match_ccmode (insn, CCGCmode)"
5261 switch (get_attr_type (insn))
5264 if (operands[2] == constm1_rtx)
5265 return "inc{q}\t%0";
5268 gcc_assert (operands[2] == const1_rtx);
5269 return "dec{q}\t%0";
5273 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5274 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5275 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5276 if ((INTVAL (operands[2]) == -128
5277 || (INTVAL (operands[2]) > 0
5278 && INTVAL (operands[2]) != 128))
5279 /* Avoid overflows. */
5280 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5281 return "sub{q}\t{%2, %0|%0, %2}";
5282 operands[2] = GEN_INT (-INTVAL (operands[2]));
5283 return "add{q}\t{%2, %0|%0, %2}";
5287 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5288 (const_string "incdec")
5289 (const_string "alu")))
5290 (set_attr "mode" "DI")])
5292 (define_insn "*adddi_5_rex64"
5293 [(set (reg FLAGS_REG)
5295 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5296 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5298 (clobber (match_scratch:DI 0 "=r"))]
5300 && ix86_match_ccmode (insn, CCGOCmode)
5301 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5302 /* Current assemblers are broken and do not allow @GOTOFF in
5303 ought but a memory context. */
5304 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5306 switch (get_attr_type (insn))
5309 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5310 if (operands[2] == const1_rtx)
5311 return "inc{q}\t%0";
5314 gcc_assert (operands[2] == constm1_rtx);
5315 return "dec{q}\t%0";
5319 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5320 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5321 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5322 if (GET_CODE (operands[2]) == CONST_INT
5323 /* Avoid overflows. */
5324 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5325 && (INTVAL (operands[2]) == 128
5326 || (INTVAL (operands[2]) < 0
5327 && INTVAL (operands[2]) != -128)))
5329 operands[2] = GEN_INT (-INTVAL (operands[2]));
5330 return "sub{q}\t{%2, %0|%0, %2}";
5332 return "add{q}\t{%2, %0|%0, %2}";
5336 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5337 (const_string "incdec")
5338 (const_string "alu")))
5339 (set_attr "mode" "DI")])
5342 (define_insn "*addsi_1"
5343 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5344 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5345 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5346 (clobber (reg:CC FLAGS_REG))]
5347 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5349 switch (get_attr_type (insn))
5352 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5353 return "lea{l}\t{%a2, %0|%0, %a2}";
5356 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5357 if (operands[2] == const1_rtx)
5358 return "inc{l}\t%0";
5361 gcc_assert (operands[2] == constm1_rtx);
5362 return "dec{l}\t%0";
5366 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5368 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5369 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5370 if (GET_CODE (operands[2]) == CONST_INT
5371 && (INTVAL (operands[2]) == 128
5372 || (INTVAL (operands[2]) < 0
5373 && INTVAL (operands[2]) != -128)))
5375 operands[2] = GEN_INT (-INTVAL (operands[2]));
5376 return "sub{l}\t{%2, %0|%0, %2}";
5378 return "add{l}\t{%2, %0|%0, %2}";
5382 (cond [(eq_attr "alternative" "2")
5383 (const_string "lea")
5384 ; Current assemblers are broken and do not allow @GOTOFF in
5385 ; ought but a memory context.
5386 (match_operand:SI 2 "pic_symbolic_operand" "")
5387 (const_string "lea")
5388 (match_operand:SI 2 "incdec_operand" "")
5389 (const_string "incdec")
5391 (const_string "alu")))
5392 (set_attr "mode" "SI")])
5394 ;; Convert lea to the lea pattern to avoid flags dependency.
5396 [(set (match_operand 0 "register_operand" "")
5397 (plus (match_operand 1 "register_operand" "")
5398 (match_operand 2 "nonmemory_operand" "")))
5399 (clobber (reg:CC FLAGS_REG))]
5401 && true_regnum (operands[0]) != true_regnum (operands[1])"
5405 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5406 may confuse gen_lowpart. */
5407 if (GET_MODE (operands[0]) != Pmode)
5409 operands[1] = gen_lowpart (Pmode, operands[1]);
5410 operands[2] = gen_lowpart (Pmode, operands[2]);
5412 operands[0] = gen_lowpart (SImode, operands[0]);
5413 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5414 if (Pmode != SImode)
5415 pat = gen_rtx_SUBREG (SImode, pat, 0);
5416 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5420 ;; It may seem that nonimmediate operand is proper one for operand 1.
5421 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5422 ;; we take care in ix86_binary_operator_ok to not allow two memory
5423 ;; operands so proper swapping will be done in reload. This allow
5424 ;; patterns constructed from addsi_1 to match.
5425 (define_insn "addsi_1_zext"
5426 [(set (match_operand:DI 0 "register_operand" "=r,r")
5428 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5429 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5430 (clobber (reg:CC FLAGS_REG))]
5431 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5433 switch (get_attr_type (insn))
5436 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5437 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5440 if (operands[2] == const1_rtx)
5441 return "inc{l}\t%k0";
5444 gcc_assert (operands[2] == constm1_rtx);
5445 return "dec{l}\t%k0";
5449 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5450 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5451 if (GET_CODE (operands[2]) == CONST_INT
5452 && (INTVAL (operands[2]) == 128
5453 || (INTVAL (operands[2]) < 0
5454 && INTVAL (operands[2]) != -128)))
5456 operands[2] = GEN_INT (-INTVAL (operands[2]));
5457 return "sub{l}\t{%2, %k0|%k0, %2}";
5459 return "add{l}\t{%2, %k0|%k0, %2}";
5463 (cond [(eq_attr "alternative" "1")
5464 (const_string "lea")
5465 ; Current assemblers are broken and do not allow @GOTOFF in
5466 ; ought but a memory context.
5467 (match_operand:SI 2 "pic_symbolic_operand" "")
5468 (const_string "lea")
5469 (match_operand:SI 2 "incdec_operand" "")
5470 (const_string "incdec")
5472 (const_string "alu")))
5473 (set_attr "mode" "SI")])
5475 ;; Convert lea to the lea pattern to avoid flags dependency.
5477 [(set (match_operand:DI 0 "register_operand" "")
5479 (plus:SI (match_operand:SI 1 "register_operand" "")
5480 (match_operand:SI 2 "nonmemory_operand" ""))))
5481 (clobber (reg:CC FLAGS_REG))]
5482 "TARGET_64BIT && reload_completed
5483 && true_regnum (operands[0]) != true_regnum (operands[1])"
5485 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5487 operands[1] = gen_lowpart (Pmode, operands[1]);
5488 operands[2] = gen_lowpart (Pmode, operands[2]);
5491 (define_insn "*addsi_2"
5492 [(set (reg FLAGS_REG)
5494 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5495 (match_operand:SI 2 "general_operand" "rmni,rni"))
5497 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5498 (plus:SI (match_dup 1) (match_dup 2)))]
5499 "ix86_match_ccmode (insn, CCGOCmode)
5500 && ix86_binary_operator_ok (PLUS, SImode, operands)
5501 /* Current assemblers are broken and do not allow @GOTOFF in
5502 ought but a memory context. */
5503 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5505 switch (get_attr_type (insn))
5508 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5509 if (operands[2] == const1_rtx)
5510 return "inc{l}\t%0";
5513 gcc_assert (operands[2] == constm1_rtx);
5514 return "dec{l}\t%0";
5518 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5519 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5520 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5521 if (GET_CODE (operands[2]) == CONST_INT
5522 && (INTVAL (operands[2]) == 128
5523 || (INTVAL (operands[2]) < 0
5524 && INTVAL (operands[2]) != -128)))
5526 operands[2] = GEN_INT (-INTVAL (operands[2]));
5527 return "sub{l}\t{%2, %0|%0, %2}";
5529 return "add{l}\t{%2, %0|%0, %2}";
5533 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5534 (const_string "incdec")
5535 (const_string "alu")))
5536 (set_attr "mode" "SI")])
5538 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5539 (define_insn "*addsi_2_zext"
5540 [(set (reg FLAGS_REG)
5542 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5543 (match_operand:SI 2 "general_operand" "rmni"))
5545 (set (match_operand:DI 0 "register_operand" "=r")
5546 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5547 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5548 && ix86_binary_operator_ok (PLUS, SImode, operands)
5549 /* Current assemblers are broken and do not allow @GOTOFF in
5550 ought but a memory context. */
5551 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5553 switch (get_attr_type (insn))
5556 if (operands[2] == const1_rtx)
5557 return "inc{l}\t%k0";
5560 gcc_assert (operands[2] == constm1_rtx);
5561 return "dec{l}\t%k0";
5565 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5566 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5567 if (GET_CODE (operands[2]) == CONST_INT
5568 && (INTVAL (operands[2]) == 128
5569 || (INTVAL (operands[2]) < 0
5570 && INTVAL (operands[2]) != -128)))
5572 operands[2] = GEN_INT (-INTVAL (operands[2]));
5573 return "sub{l}\t{%2, %k0|%k0, %2}";
5575 return "add{l}\t{%2, %k0|%k0, %2}";
5579 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5580 (const_string "incdec")
5581 (const_string "alu")))
5582 (set_attr "mode" "SI")])
5584 (define_insn "*addsi_3"
5585 [(set (reg FLAGS_REG)
5586 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5587 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5588 (clobber (match_scratch:SI 0 "=r"))]
5589 "ix86_match_ccmode (insn, CCZmode)
5590 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5591 /* Current assemblers are broken and do not allow @GOTOFF in
5592 ought but a memory context. */
5593 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5595 switch (get_attr_type (insn))
5598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599 if (operands[2] == const1_rtx)
5600 return "inc{l}\t%0";
5603 gcc_assert (operands[2] == constm1_rtx);
5604 return "dec{l}\t%0";
5608 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5610 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5611 if (GET_CODE (operands[2]) == CONST_INT
5612 && (INTVAL (operands[2]) == 128
5613 || (INTVAL (operands[2]) < 0
5614 && INTVAL (operands[2]) != -128)))
5616 operands[2] = GEN_INT (-INTVAL (operands[2]));
5617 return "sub{l}\t{%2, %0|%0, %2}";
5619 return "add{l}\t{%2, %0|%0, %2}";
5623 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5624 (const_string "incdec")
5625 (const_string "alu")))
5626 (set_attr "mode" "SI")])
5628 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5629 (define_insn "*addsi_3_zext"
5630 [(set (reg FLAGS_REG)
5631 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5632 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5633 (set (match_operand:DI 0 "register_operand" "=r")
5634 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5635 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5636 && ix86_binary_operator_ok (PLUS, SImode, operands)
5637 /* Current assemblers are broken and do not allow @GOTOFF in
5638 ought but a memory context. */
5639 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5641 switch (get_attr_type (insn))
5644 if (operands[2] == const1_rtx)
5645 return "inc{l}\t%k0";
5648 gcc_assert (operands[2] == constm1_rtx);
5649 return "dec{l}\t%k0";
5653 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5654 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5655 if (GET_CODE (operands[2]) == CONST_INT
5656 && (INTVAL (operands[2]) == 128
5657 || (INTVAL (operands[2]) < 0
5658 && INTVAL (operands[2]) != -128)))
5660 operands[2] = GEN_INT (-INTVAL (operands[2]));
5661 return "sub{l}\t{%2, %k0|%k0, %2}";
5663 return "add{l}\t{%2, %k0|%k0, %2}";
5667 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5668 (const_string "incdec")
5669 (const_string "alu")))
5670 (set_attr "mode" "SI")])
5672 ; For comparisons against 1, -1 and 128, we may generate better code
5673 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5674 ; is matched then. We can't accept general immediate, because for
5675 ; case of overflows, the result is messed up.
5676 ; This pattern also don't hold of 0x80000000, since the value overflows
5678 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5679 ; only for comparisons not depending on it.
5680 (define_insn "*addsi_4"
5681 [(set (reg FLAGS_REG)
5682 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5683 (match_operand:SI 2 "const_int_operand" "n")))
5684 (clobber (match_scratch:SI 0 "=rm"))]
5685 "ix86_match_ccmode (insn, CCGCmode)
5686 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5688 switch (get_attr_type (insn))
5691 if (operands[2] == constm1_rtx)
5692 return "inc{l}\t%0";
5695 gcc_assert (operands[2] == const1_rtx);
5696 return "dec{l}\t%0";
5700 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5701 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5702 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5703 if ((INTVAL (operands[2]) == -128
5704 || (INTVAL (operands[2]) > 0
5705 && INTVAL (operands[2]) != 128)))
5706 return "sub{l}\t{%2, %0|%0, %2}";
5707 operands[2] = GEN_INT (-INTVAL (operands[2]));
5708 return "add{l}\t{%2, %0|%0, %2}";
5712 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5713 (const_string "incdec")
5714 (const_string "alu")))
5715 (set_attr "mode" "SI")])
5717 (define_insn "*addsi_5"
5718 [(set (reg FLAGS_REG)
5720 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5721 (match_operand:SI 2 "general_operand" "rmni"))
5723 (clobber (match_scratch:SI 0 "=r"))]
5724 "ix86_match_ccmode (insn, CCGOCmode)
5725 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5726 /* Current assemblers are broken and do not allow @GOTOFF in
5727 ought but a memory context. */
5728 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5730 switch (get_attr_type (insn))
5733 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5734 if (operands[2] == const1_rtx)
5735 return "inc{l}\t%0";
5738 gcc_assert (operands[2] == constm1_rtx);
5739 return "dec{l}\t%0";
5743 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5744 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5745 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5746 if (GET_CODE (operands[2]) == CONST_INT
5747 && (INTVAL (operands[2]) == 128
5748 || (INTVAL (operands[2]) < 0
5749 && INTVAL (operands[2]) != -128)))
5751 operands[2] = GEN_INT (-INTVAL (operands[2]));
5752 return "sub{l}\t{%2, %0|%0, %2}";
5754 return "add{l}\t{%2, %0|%0, %2}";
5758 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5759 (const_string "incdec")
5760 (const_string "alu")))
5761 (set_attr "mode" "SI")])
5763 (define_expand "addhi3"
5764 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5765 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5766 (match_operand:HI 2 "general_operand" "")))
5767 (clobber (reg:CC FLAGS_REG))])]
5768 "TARGET_HIMODE_MATH"
5769 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5771 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5772 ;; type optimizations enabled by define-splits. This is not important
5773 ;; for PII, and in fact harmful because of partial register stalls.
5775 (define_insn "*addhi_1_lea"
5776 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5777 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5778 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5779 (clobber (reg:CC FLAGS_REG))]
5780 "!TARGET_PARTIAL_REG_STALL
5781 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5783 switch (get_attr_type (insn))
5788 if (operands[2] == const1_rtx)
5789 return "inc{w}\t%0";
5792 gcc_assert (operands[2] == constm1_rtx);
5793 return "dec{w}\t%0";
5797 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5798 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5799 if (GET_CODE (operands[2]) == CONST_INT
5800 && (INTVAL (operands[2]) == 128
5801 || (INTVAL (operands[2]) < 0
5802 && INTVAL (operands[2]) != -128)))
5804 operands[2] = GEN_INT (-INTVAL (operands[2]));
5805 return "sub{w}\t{%2, %0|%0, %2}";
5807 return "add{w}\t{%2, %0|%0, %2}";
5811 (if_then_else (eq_attr "alternative" "2")
5812 (const_string "lea")
5813 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5814 (const_string "incdec")
5815 (const_string "alu"))))
5816 (set_attr "mode" "HI,HI,SI")])
5818 (define_insn "*addhi_1"
5819 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5820 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5821 (match_operand:HI 2 "general_operand" "ri,rm")))
5822 (clobber (reg:CC FLAGS_REG))]
5823 "TARGET_PARTIAL_REG_STALL
5824 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5826 switch (get_attr_type (insn))
5829 if (operands[2] == const1_rtx)
5830 return "inc{w}\t%0";
5833 gcc_assert (operands[2] == constm1_rtx);
5834 return "dec{w}\t%0";
5838 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5839 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5840 if (GET_CODE (operands[2]) == CONST_INT
5841 && (INTVAL (operands[2]) == 128
5842 || (INTVAL (operands[2]) < 0
5843 && INTVAL (operands[2]) != -128)))
5845 operands[2] = GEN_INT (-INTVAL (operands[2]));
5846 return "sub{w}\t{%2, %0|%0, %2}";
5848 return "add{w}\t{%2, %0|%0, %2}";
5852 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5853 (const_string "incdec")
5854 (const_string "alu")))
5855 (set_attr "mode" "HI")])
5857 (define_insn "*addhi_2"
5858 [(set (reg FLAGS_REG)
5860 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5861 (match_operand:HI 2 "general_operand" "rmni,rni"))
5863 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5864 (plus:HI (match_dup 1) (match_dup 2)))]
5865 "ix86_match_ccmode (insn, CCGOCmode)
5866 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5868 switch (get_attr_type (insn))
5871 if (operands[2] == const1_rtx)
5872 return "inc{w}\t%0";
5875 gcc_assert (operands[2] == constm1_rtx);
5876 return "dec{w}\t%0";
5880 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5881 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5882 if (GET_CODE (operands[2]) == CONST_INT
5883 && (INTVAL (operands[2]) == 128
5884 || (INTVAL (operands[2]) < 0
5885 && INTVAL (operands[2]) != -128)))
5887 operands[2] = GEN_INT (-INTVAL (operands[2]));
5888 return "sub{w}\t{%2, %0|%0, %2}";
5890 return "add{w}\t{%2, %0|%0, %2}";
5894 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5895 (const_string "incdec")
5896 (const_string "alu")))
5897 (set_attr "mode" "HI")])
5899 (define_insn "*addhi_3"
5900 [(set (reg FLAGS_REG)
5901 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5902 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5903 (clobber (match_scratch:HI 0 "=r"))]
5904 "ix86_match_ccmode (insn, CCZmode)
5905 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5907 switch (get_attr_type (insn))
5910 if (operands[2] == const1_rtx)
5911 return "inc{w}\t%0";
5914 gcc_assert (operands[2] == constm1_rtx);
5915 return "dec{w}\t%0";
5919 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5920 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5921 if (GET_CODE (operands[2]) == CONST_INT
5922 && (INTVAL (operands[2]) == 128
5923 || (INTVAL (operands[2]) < 0
5924 && INTVAL (operands[2]) != -128)))
5926 operands[2] = GEN_INT (-INTVAL (operands[2]));
5927 return "sub{w}\t{%2, %0|%0, %2}";
5929 return "add{w}\t{%2, %0|%0, %2}";
5933 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5934 (const_string "incdec")
5935 (const_string "alu")))
5936 (set_attr "mode" "HI")])
5938 ; See comments above addsi_4 for details.
5939 (define_insn "*addhi_4"
5940 [(set (reg FLAGS_REG)
5941 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5942 (match_operand:HI 2 "const_int_operand" "n")))
5943 (clobber (match_scratch:HI 0 "=rm"))]
5944 "ix86_match_ccmode (insn, CCGCmode)
5945 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5947 switch (get_attr_type (insn))
5950 if (operands[2] == constm1_rtx)
5951 return "inc{w}\t%0";
5954 gcc_assert (operands[2] == const1_rtx);
5955 return "dec{w}\t%0";
5959 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5960 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5962 if ((INTVAL (operands[2]) == -128
5963 || (INTVAL (operands[2]) > 0
5964 && INTVAL (operands[2]) != 128)))
5965 return "sub{w}\t{%2, %0|%0, %2}";
5966 operands[2] = GEN_INT (-INTVAL (operands[2]));
5967 return "add{w}\t{%2, %0|%0, %2}";
5971 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5972 (const_string "incdec")
5973 (const_string "alu")))
5974 (set_attr "mode" "SI")])
5977 (define_insn "*addhi_5"
5978 [(set (reg FLAGS_REG)
5980 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5981 (match_operand:HI 2 "general_operand" "rmni"))
5983 (clobber (match_scratch:HI 0 "=r"))]
5984 "ix86_match_ccmode (insn, CCGOCmode)
5985 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5987 switch (get_attr_type (insn))
5990 if (operands[2] == const1_rtx)
5991 return "inc{w}\t%0";
5994 gcc_assert (operands[2] == constm1_rtx);
5995 return "dec{w}\t%0";
5999 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6000 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6001 if (GET_CODE (operands[2]) == CONST_INT
6002 && (INTVAL (operands[2]) == 128
6003 || (INTVAL (operands[2]) < 0
6004 && INTVAL (operands[2]) != -128)))
6006 operands[2] = GEN_INT (-INTVAL (operands[2]));
6007 return "sub{w}\t{%2, %0|%0, %2}";
6009 return "add{w}\t{%2, %0|%0, %2}";
6013 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6014 (const_string "incdec")
6015 (const_string "alu")))
6016 (set_attr "mode" "HI")])
6018 (define_expand "addqi3"
6019 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6020 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6021 (match_operand:QI 2 "general_operand" "")))
6022 (clobber (reg:CC FLAGS_REG))])]
6023 "TARGET_QIMODE_MATH"
6024 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6026 ;; %%% Potential partial reg stall on alternative 2. What to do?
6027 (define_insn "*addqi_1_lea"
6028 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6029 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6030 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6031 (clobber (reg:CC FLAGS_REG))]
6032 "!TARGET_PARTIAL_REG_STALL
6033 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6035 int widen = (which_alternative == 2);
6036 switch (get_attr_type (insn))
6041 if (operands[2] == const1_rtx)
6042 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6045 gcc_assert (operands[2] == constm1_rtx);
6046 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6050 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6051 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6052 if (GET_CODE (operands[2]) == CONST_INT
6053 && (INTVAL (operands[2]) == 128
6054 || (INTVAL (operands[2]) < 0
6055 && INTVAL (operands[2]) != -128)))
6057 operands[2] = GEN_INT (-INTVAL (operands[2]));
6059 return "sub{l}\t{%2, %k0|%k0, %2}";
6061 return "sub{b}\t{%2, %0|%0, %2}";
6064 return "add{l}\t{%k2, %k0|%k0, %k2}";
6066 return "add{b}\t{%2, %0|%0, %2}";
6070 (if_then_else (eq_attr "alternative" "3")
6071 (const_string "lea")
6072 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6073 (const_string "incdec")
6074 (const_string "alu"))))
6075 (set_attr "mode" "QI,QI,SI,SI")])
6077 (define_insn "*addqi_1"
6078 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6079 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6080 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6081 (clobber (reg:CC FLAGS_REG))]
6082 "TARGET_PARTIAL_REG_STALL
6083 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6085 int widen = (which_alternative == 2);
6086 switch (get_attr_type (insn))
6089 if (operands[2] == const1_rtx)
6090 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6093 gcc_assert (operands[2] == constm1_rtx);
6094 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6098 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6099 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6100 if (GET_CODE (operands[2]) == CONST_INT
6101 && (INTVAL (operands[2]) == 128
6102 || (INTVAL (operands[2]) < 0
6103 && INTVAL (operands[2]) != -128)))
6105 operands[2] = GEN_INT (-INTVAL (operands[2]));
6107 return "sub{l}\t{%2, %k0|%k0, %2}";
6109 return "sub{b}\t{%2, %0|%0, %2}";
6112 return "add{l}\t{%k2, %k0|%k0, %k2}";
6114 return "add{b}\t{%2, %0|%0, %2}";
6118 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6119 (const_string "incdec")
6120 (const_string "alu")))
6121 (set_attr "mode" "QI,QI,SI")])
6123 (define_insn "*addqi_1_slp"
6124 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6125 (plus:QI (match_dup 0)
6126 (match_operand:QI 1 "general_operand" "qn,qnm")))
6127 (clobber (reg:CC FLAGS_REG))]
6128 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6129 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6131 switch (get_attr_type (insn))
6134 if (operands[1] == const1_rtx)
6135 return "inc{b}\t%0";
6138 gcc_assert (operands[1] == constm1_rtx);
6139 return "dec{b}\t%0";
6143 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6144 if (GET_CODE (operands[1]) == CONST_INT
6145 && INTVAL (operands[1]) < 0)
6147 operands[1] = GEN_INT (-INTVAL (operands[1]));
6148 return "sub{b}\t{%1, %0|%0, %1}";
6150 return "add{b}\t{%1, %0|%0, %1}";
6154 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6155 (const_string "incdec")
6156 (const_string "alu1")))
6157 (set (attr "memory")
6158 (if_then_else (match_operand 1 "memory_operand" "")
6159 (const_string "load")
6160 (const_string "none")))
6161 (set_attr "mode" "QI")])
6163 (define_insn "*addqi_2"
6164 [(set (reg FLAGS_REG)
6166 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6167 (match_operand:QI 2 "general_operand" "qmni,qni"))
6169 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6170 (plus:QI (match_dup 1) (match_dup 2)))]
6171 "ix86_match_ccmode (insn, CCGOCmode)
6172 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6174 switch (get_attr_type (insn))
6177 if (operands[2] == const1_rtx)
6178 return "inc{b}\t%0";
6181 gcc_assert (operands[2] == constm1_rtx
6182 || (GET_CODE (operands[2]) == CONST_INT
6183 && INTVAL (operands[2]) == 255));
6184 return "dec{b}\t%0";
6188 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6189 if (GET_CODE (operands[2]) == CONST_INT
6190 && INTVAL (operands[2]) < 0)
6192 operands[2] = GEN_INT (-INTVAL (operands[2]));
6193 return "sub{b}\t{%2, %0|%0, %2}";
6195 return "add{b}\t{%2, %0|%0, %2}";
6199 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6200 (const_string "incdec")
6201 (const_string "alu")))
6202 (set_attr "mode" "QI")])
6204 (define_insn "*addqi_3"
6205 [(set (reg FLAGS_REG)
6206 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6207 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6208 (clobber (match_scratch:QI 0 "=q"))]
6209 "ix86_match_ccmode (insn, CCZmode)
6210 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6212 switch (get_attr_type (insn))
6215 if (operands[2] == const1_rtx)
6216 return "inc{b}\t%0";
6219 gcc_assert (operands[2] == constm1_rtx
6220 || (GET_CODE (operands[2]) == CONST_INT
6221 && INTVAL (operands[2]) == 255));
6222 return "dec{b}\t%0";
6226 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6227 if (GET_CODE (operands[2]) == CONST_INT
6228 && INTVAL (operands[2]) < 0)
6230 operands[2] = GEN_INT (-INTVAL (operands[2]));
6231 return "sub{b}\t{%2, %0|%0, %2}";
6233 return "add{b}\t{%2, %0|%0, %2}";
6237 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6238 (const_string "incdec")
6239 (const_string "alu")))
6240 (set_attr "mode" "QI")])
6242 ; See comments above addsi_4 for details.
6243 (define_insn "*addqi_4"
6244 [(set (reg FLAGS_REG)
6245 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6246 (match_operand:QI 2 "const_int_operand" "n")))
6247 (clobber (match_scratch:QI 0 "=qm"))]
6248 "ix86_match_ccmode (insn, CCGCmode)
6249 && (INTVAL (operands[2]) & 0xff) != 0x80"
6251 switch (get_attr_type (insn))
6254 if (operands[2] == constm1_rtx
6255 || (GET_CODE (operands[2]) == CONST_INT
6256 && INTVAL (operands[2]) == 255))
6257 return "inc{b}\t%0";
6260 gcc_assert (operands[2] == const1_rtx);
6261 return "dec{b}\t%0";
6265 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6266 if (INTVAL (operands[2]) < 0)
6268 operands[2] = GEN_INT (-INTVAL (operands[2]));
6269 return "add{b}\t{%2, %0|%0, %2}";
6271 return "sub{b}\t{%2, %0|%0, %2}";
6275 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6276 (const_string "incdec")
6277 (const_string "alu")))
6278 (set_attr "mode" "QI")])
6281 (define_insn "*addqi_5"
6282 [(set (reg FLAGS_REG)
6284 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6285 (match_operand:QI 2 "general_operand" "qmni"))
6287 (clobber (match_scratch:QI 0 "=q"))]
6288 "ix86_match_ccmode (insn, CCGOCmode)
6289 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6291 switch (get_attr_type (insn))
6294 if (operands[2] == const1_rtx)
6295 return "inc{b}\t%0";
6298 gcc_assert (operands[2] == constm1_rtx
6299 || (GET_CODE (operands[2]) == CONST_INT
6300 && INTVAL (operands[2]) == 255));
6301 return "dec{b}\t%0";
6305 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6306 if (GET_CODE (operands[2]) == CONST_INT
6307 && INTVAL (operands[2]) < 0)
6309 operands[2] = GEN_INT (-INTVAL (operands[2]));
6310 return "sub{b}\t{%2, %0|%0, %2}";
6312 return "add{b}\t{%2, %0|%0, %2}";
6316 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6317 (const_string "incdec")
6318 (const_string "alu")))
6319 (set_attr "mode" "QI")])
6322 (define_insn "addqi_ext_1"
6323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6328 (match_operand 1 "ext_register_operand" "0")
6331 (match_operand:QI 2 "general_operand" "Qmn")))
6332 (clobber (reg:CC FLAGS_REG))]
6335 switch (get_attr_type (insn))
6338 if (operands[2] == const1_rtx)
6339 return "inc{b}\t%h0";
6342 gcc_assert (operands[2] == constm1_rtx
6343 || (GET_CODE (operands[2]) == CONST_INT
6344 && INTVAL (operands[2]) == 255));
6345 return "dec{b}\t%h0";
6349 return "add{b}\t{%2, %h0|%h0, %2}";
6353 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6354 (const_string "incdec")
6355 (const_string "alu")))
6356 (set_attr "mode" "QI")])
6358 (define_insn "*addqi_ext_1_rex64"
6359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6364 (match_operand 1 "ext_register_operand" "0")
6367 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6368 (clobber (reg:CC FLAGS_REG))]
6371 switch (get_attr_type (insn))
6374 if (operands[2] == const1_rtx)
6375 return "inc{b}\t%h0";
6378 gcc_assert (operands[2] == constm1_rtx
6379 || (GET_CODE (operands[2]) == CONST_INT
6380 && INTVAL (operands[2]) == 255));
6381 return "dec{b}\t%h0";
6385 return "add{b}\t{%2, %h0|%h0, %2}";
6389 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6390 (const_string "incdec")
6391 (const_string "alu")))
6392 (set_attr "mode" "QI")])
6394 (define_insn "*addqi_ext_2"
6395 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6400 (match_operand 1 "ext_register_operand" "%0")
6404 (match_operand 2 "ext_register_operand" "Q")
6407 (clobber (reg:CC FLAGS_REG))]
6409 "add{b}\t{%h2, %h0|%h0, %h2}"
6410 [(set_attr "type" "alu")
6411 (set_attr "mode" "QI")])
6413 ;; The patterns that match these are at the end of this file.
6415 (define_expand "addxf3"
6416 [(set (match_operand:XF 0 "register_operand" "")
6417 (plus:XF (match_operand:XF 1 "register_operand" "")
6418 (match_operand:XF 2 "register_operand" "")))]
6422 (define_expand "adddf3"
6423 [(set (match_operand:DF 0 "register_operand" "")
6424 (plus:DF (match_operand:DF 1 "register_operand" "")
6425 (match_operand:DF 2 "nonimmediate_operand" "")))]
6426 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6429 (define_expand "addsf3"
6430 [(set (match_operand:SF 0 "register_operand" "")
6431 (plus:SF (match_operand:SF 1 "register_operand" "")
6432 (match_operand:SF 2 "nonimmediate_operand" "")))]
6433 "TARGET_80387 || TARGET_SSE_MATH"
6436 ;; Subtract instructions
6438 ;; %%% splits for subditi3
6440 (define_expand "subti3"
6441 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6442 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6443 (match_operand:TI 2 "x86_64_general_operand" "")))
6444 (clobber (reg:CC FLAGS_REG))])]
6446 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6448 (define_insn "*subti3_1"
6449 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6450 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6451 (match_operand:TI 2 "general_operand" "roiF,riF")))
6452 (clobber (reg:CC FLAGS_REG))]
6453 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6457 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6458 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6459 (match_operand:TI 2 "general_operand" "")))
6460 (clobber (reg:CC FLAGS_REG))]
6461 "TARGET_64BIT && reload_completed"
6462 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6463 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6464 (parallel [(set (match_dup 3)
6465 (minus:DI (match_dup 4)
6466 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6468 (clobber (reg:CC FLAGS_REG))])]
6469 "split_ti (operands+0, 1, operands+0, operands+3);
6470 split_ti (operands+1, 1, operands+1, operands+4);
6471 split_ti (operands+2, 1, operands+2, operands+5);")
6473 ;; %%% splits for subsidi3
6475 (define_expand "subdi3"
6476 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6477 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6478 (match_operand:DI 2 "x86_64_general_operand" "")))
6479 (clobber (reg:CC FLAGS_REG))])]
6481 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6483 (define_insn "*subdi3_1"
6484 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6485 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:DI 2 "general_operand" "roiF,riF")))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6492 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6493 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6494 (match_operand:DI 2 "general_operand" "")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "!TARGET_64BIT && reload_completed"
6497 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6498 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6499 (parallel [(set (match_dup 3)
6500 (minus:SI (match_dup 4)
6501 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6503 (clobber (reg:CC FLAGS_REG))])]
6504 "split_di (operands+0, 1, operands+0, operands+3);
6505 split_di (operands+1, 1, operands+1, operands+4);
6506 split_di (operands+2, 1, operands+2, operands+5);")
6508 (define_insn "subdi3_carry_rex64"
6509 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6510 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6511 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6512 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6513 (clobber (reg:CC FLAGS_REG))]
6514 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6515 "sbb{q}\t{%2, %0|%0, %2}"
6516 [(set_attr "type" "alu")
6517 (set_attr "pent_pair" "pu")
6518 (set_attr "mode" "DI")])
6520 (define_insn "*subdi_1_rex64"
6521 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6522 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6523 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6524 (clobber (reg:CC FLAGS_REG))]
6525 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6526 "sub{q}\t{%2, %0|%0, %2}"
6527 [(set_attr "type" "alu")
6528 (set_attr "mode" "DI")])
6530 (define_insn "*subdi_2_rex64"
6531 [(set (reg FLAGS_REG)
6533 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6534 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6536 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6537 (minus:DI (match_dup 1) (match_dup 2)))]
6538 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6539 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6540 "sub{q}\t{%2, %0|%0, %2}"
6541 [(set_attr "type" "alu")
6542 (set_attr "mode" "DI")])
6544 (define_insn "*subdi_3_rex63"
6545 [(set (reg FLAGS_REG)
6546 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6547 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6548 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6549 (minus:DI (match_dup 1) (match_dup 2)))]
6550 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6551 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6552 "sub{q}\t{%2, %0|%0, %2}"
6553 [(set_attr "type" "alu")
6554 (set_attr "mode" "DI")])
6556 (define_insn "subqi3_carry"
6557 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6558 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6559 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6560 (match_operand:QI 2 "general_operand" "qi,qm"))))
6561 (clobber (reg:CC FLAGS_REG))]
6562 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6563 "sbb{b}\t{%2, %0|%0, %2}"
6564 [(set_attr "type" "alu")
6565 (set_attr "pent_pair" "pu")
6566 (set_attr "mode" "QI")])
6568 (define_insn "subhi3_carry"
6569 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6570 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6571 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6572 (match_operand:HI 2 "general_operand" "ri,rm"))))
6573 (clobber (reg:CC FLAGS_REG))]
6574 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6575 "sbb{w}\t{%2, %0|%0, %2}"
6576 [(set_attr "type" "alu")
6577 (set_attr "pent_pair" "pu")
6578 (set_attr "mode" "HI")])
6580 (define_insn "subsi3_carry"
6581 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6582 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6583 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6584 (match_operand:SI 2 "general_operand" "ri,rm"))))
6585 (clobber (reg:CC FLAGS_REG))]
6586 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6587 "sbb{l}\t{%2, %0|%0, %2}"
6588 [(set_attr "type" "alu")
6589 (set_attr "pent_pair" "pu")
6590 (set_attr "mode" "SI")])
6592 (define_insn "subsi3_carry_zext"
6593 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6595 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6596 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6597 (match_operand:SI 2 "general_operand" "ri,rm")))))
6598 (clobber (reg:CC FLAGS_REG))]
6599 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6600 "sbb{l}\t{%2, %k0|%k0, %2}"
6601 [(set_attr "type" "alu")
6602 (set_attr "pent_pair" "pu")
6603 (set_attr "mode" "SI")])
6605 (define_expand "subsi3"
6606 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6607 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6608 (match_operand:SI 2 "general_operand" "")))
6609 (clobber (reg:CC FLAGS_REG))])]
6611 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6613 (define_insn "*subsi_1"
6614 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6615 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6616 (match_operand:SI 2 "general_operand" "ri,rm")))
6617 (clobber (reg:CC FLAGS_REG))]
6618 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6619 "sub{l}\t{%2, %0|%0, %2}"
6620 [(set_attr "type" "alu")
6621 (set_attr "mode" "SI")])
6623 (define_insn "*subsi_1_zext"
6624 [(set (match_operand:DI 0 "register_operand" "=r")
6626 (minus:SI (match_operand:SI 1 "register_operand" "0")
6627 (match_operand:SI 2 "general_operand" "rim"))))
6628 (clobber (reg:CC FLAGS_REG))]
6629 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6630 "sub{l}\t{%2, %k0|%k0, %2}"
6631 [(set_attr "type" "alu")
6632 (set_attr "mode" "SI")])
6634 (define_insn "*subsi_2"
6635 [(set (reg FLAGS_REG)
6637 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6638 (match_operand:SI 2 "general_operand" "ri,rm"))
6640 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6641 (minus:SI (match_dup 1) (match_dup 2)))]
6642 "ix86_match_ccmode (insn, CCGOCmode)
6643 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6644 "sub{l}\t{%2, %0|%0, %2}"
6645 [(set_attr "type" "alu")
6646 (set_attr "mode" "SI")])
6648 (define_insn "*subsi_2_zext"
6649 [(set (reg FLAGS_REG)
6651 (minus:SI (match_operand:SI 1 "register_operand" "0")
6652 (match_operand:SI 2 "general_operand" "rim"))
6654 (set (match_operand:DI 0 "register_operand" "=r")
6656 (minus:SI (match_dup 1)
6658 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6659 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6660 "sub{l}\t{%2, %k0|%k0, %2}"
6661 [(set_attr "type" "alu")
6662 (set_attr "mode" "SI")])
6664 (define_insn "*subsi_3"
6665 [(set (reg FLAGS_REG)
6666 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6667 (match_operand:SI 2 "general_operand" "ri,rm")))
6668 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6669 (minus:SI (match_dup 1) (match_dup 2)))]
6670 "ix86_match_ccmode (insn, CCmode)
6671 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6672 "sub{l}\t{%2, %0|%0, %2}"
6673 [(set_attr "type" "alu")
6674 (set_attr "mode" "SI")])
6676 (define_insn "*subsi_3_zext"
6677 [(set (reg FLAGS_REG)
6678 (compare (match_operand:SI 1 "register_operand" "0")
6679 (match_operand:SI 2 "general_operand" "rim")))
6680 (set (match_operand:DI 0 "register_operand" "=r")
6682 (minus:SI (match_dup 1)
6684 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6685 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6686 "sub{q}\t{%2, %0|%0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "mode" "DI")])
6690 (define_expand "subhi3"
6691 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6692 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6693 (match_operand:HI 2 "general_operand" "")))
6694 (clobber (reg:CC FLAGS_REG))])]
6695 "TARGET_HIMODE_MATH"
6696 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6698 (define_insn "*subhi_1"
6699 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6700 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6701 (match_operand:HI 2 "general_operand" "ri,rm")))
6702 (clobber (reg:CC FLAGS_REG))]
6703 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6704 "sub{w}\t{%2, %0|%0, %2}"
6705 [(set_attr "type" "alu")
6706 (set_attr "mode" "HI")])
6708 (define_insn "*subhi_2"
6709 [(set (reg FLAGS_REG)
6711 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6712 (match_operand:HI 2 "general_operand" "ri,rm"))
6714 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6715 (minus:HI (match_dup 1) (match_dup 2)))]
6716 "ix86_match_ccmode (insn, CCGOCmode)
6717 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6718 "sub{w}\t{%2, %0|%0, %2}"
6719 [(set_attr "type" "alu")
6720 (set_attr "mode" "HI")])
6722 (define_insn "*subhi_3"
6723 [(set (reg FLAGS_REG)
6724 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6725 (match_operand:HI 2 "general_operand" "ri,rm")))
6726 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6727 (minus:HI (match_dup 1) (match_dup 2)))]
6728 "ix86_match_ccmode (insn, CCmode)
6729 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6730 "sub{w}\t{%2, %0|%0, %2}"
6731 [(set_attr "type" "alu")
6732 (set_attr "mode" "HI")])
6734 (define_expand "subqi3"
6735 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6736 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6737 (match_operand:QI 2 "general_operand" "")))
6738 (clobber (reg:CC FLAGS_REG))])]
6739 "TARGET_QIMODE_MATH"
6740 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6742 (define_insn "*subqi_1"
6743 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6744 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6745 (match_operand:QI 2 "general_operand" "qn,qmn")))
6746 (clobber (reg:CC FLAGS_REG))]
6747 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6748 "sub{b}\t{%2, %0|%0, %2}"
6749 [(set_attr "type" "alu")
6750 (set_attr "mode" "QI")])
6752 (define_insn "*subqi_1_slp"
6753 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6754 (minus:QI (match_dup 0)
6755 (match_operand:QI 1 "general_operand" "qn,qmn")))
6756 (clobber (reg:CC FLAGS_REG))]
6757 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6758 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6759 "sub{b}\t{%1, %0|%0, %1}"
6760 [(set_attr "type" "alu1")
6761 (set_attr "mode" "QI")])
6763 (define_insn "*subqi_2"
6764 [(set (reg FLAGS_REG)
6766 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6767 (match_operand:QI 2 "general_operand" "qi,qm"))
6769 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6770 (minus:HI (match_dup 1) (match_dup 2)))]
6771 "ix86_match_ccmode (insn, CCGOCmode)
6772 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6773 "sub{b}\t{%2, %0|%0, %2}"
6774 [(set_attr "type" "alu")
6775 (set_attr "mode" "QI")])
6777 (define_insn "*subqi_3"
6778 [(set (reg FLAGS_REG)
6779 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6780 (match_operand:QI 2 "general_operand" "qi,qm")))
6781 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6782 (minus:HI (match_dup 1) (match_dup 2)))]
6783 "ix86_match_ccmode (insn, CCmode)
6784 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6785 "sub{b}\t{%2, %0|%0, %2}"
6786 [(set_attr "type" "alu")
6787 (set_attr "mode" "QI")])
6789 ;; The patterns that match these are at the end of this file.
6791 (define_expand "subxf3"
6792 [(set (match_operand:XF 0 "register_operand" "")
6793 (minus:XF (match_operand:XF 1 "register_operand" "")
6794 (match_operand:XF 2 "register_operand" "")))]
6798 (define_expand "subdf3"
6799 [(set (match_operand:DF 0 "register_operand" "")
6800 (minus:DF (match_operand:DF 1 "register_operand" "")
6801 (match_operand:DF 2 "nonimmediate_operand" "")))]
6802 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6805 (define_expand "subsf3"
6806 [(set (match_operand:SF 0 "register_operand" "")
6807 (minus:SF (match_operand:SF 1 "register_operand" "")
6808 (match_operand:SF 2 "nonimmediate_operand" "")))]
6809 "TARGET_80387 || TARGET_SSE_MATH"
6812 ;; Multiply instructions
6814 (define_expand "muldi3"
6815 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6816 (mult:DI (match_operand:DI 1 "register_operand" "")
6817 (match_operand:DI 2 "x86_64_general_operand" "")))
6818 (clobber (reg:CC FLAGS_REG))])]
6822 (define_insn "*muldi3_1_rex64"
6823 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6824 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6825 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6826 (clobber (reg:CC FLAGS_REG))]
6828 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6830 imul{q}\t{%2, %1, %0|%0, %1, %2}
6831 imul{q}\t{%2, %1, %0|%0, %1, %2}
6832 imul{q}\t{%2, %0|%0, %2}"
6833 [(set_attr "type" "imul")
6834 (set_attr "prefix_0f" "0,0,1")
6835 (set (attr "athlon_decode")
6836 (cond [(eq_attr "cpu" "athlon")
6837 (const_string "vector")
6838 (eq_attr "alternative" "1")
6839 (const_string "vector")
6840 (and (eq_attr "alternative" "2")
6841 (match_operand 1 "memory_operand" ""))
6842 (const_string "vector")]
6843 (const_string "direct")))
6844 (set_attr "mode" "DI")])
6846 (define_expand "mulsi3"
6847 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6848 (mult:SI (match_operand:SI 1 "register_operand" "")
6849 (match_operand:SI 2 "general_operand" "")))
6850 (clobber (reg:CC FLAGS_REG))])]
6854 (define_insn "*mulsi3_1"
6855 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6856 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6857 (match_operand:SI 2 "general_operand" "K,i,mr")))
6858 (clobber (reg:CC FLAGS_REG))]
6859 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6861 imul{l}\t{%2, %1, %0|%0, %1, %2}
6862 imul{l}\t{%2, %1, %0|%0, %1, %2}
6863 imul{l}\t{%2, %0|%0, %2}"
6864 [(set_attr "type" "imul")
6865 (set_attr "prefix_0f" "0,0,1")
6866 (set (attr "athlon_decode")
6867 (cond [(eq_attr "cpu" "athlon")
6868 (const_string "vector")
6869 (eq_attr "alternative" "1")
6870 (const_string "vector")
6871 (and (eq_attr "alternative" "2")
6872 (match_operand 1 "memory_operand" ""))
6873 (const_string "vector")]
6874 (const_string "direct")))
6875 (set_attr "mode" "SI")])
6877 (define_insn "*mulsi3_1_zext"
6878 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6880 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6881 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6882 (clobber (reg:CC FLAGS_REG))]
6884 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6886 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6887 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6888 imul{l}\t{%2, %k0|%k0, %2}"
6889 [(set_attr "type" "imul")
6890 (set_attr "prefix_0f" "0,0,1")
6891 (set (attr "athlon_decode")
6892 (cond [(eq_attr "cpu" "athlon")
6893 (const_string "vector")
6894 (eq_attr "alternative" "1")
6895 (const_string "vector")
6896 (and (eq_attr "alternative" "2")
6897 (match_operand 1 "memory_operand" ""))
6898 (const_string "vector")]
6899 (const_string "direct")))
6900 (set_attr "mode" "SI")])
6902 (define_expand "mulhi3"
6903 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6904 (mult:HI (match_operand:HI 1 "register_operand" "")
6905 (match_operand:HI 2 "general_operand" "")))
6906 (clobber (reg:CC FLAGS_REG))])]
6907 "TARGET_HIMODE_MATH"
6910 (define_insn "*mulhi3_1"
6911 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6912 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6913 (match_operand:HI 2 "general_operand" "K,i,mr")))
6914 (clobber (reg:CC FLAGS_REG))]
6915 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6917 imul{w}\t{%2, %1, %0|%0, %1, %2}
6918 imul{w}\t{%2, %1, %0|%0, %1, %2}
6919 imul{w}\t{%2, %0|%0, %2}"
6920 [(set_attr "type" "imul")
6921 (set_attr "prefix_0f" "0,0,1")
6922 (set (attr "athlon_decode")
6923 (cond [(eq_attr "cpu" "athlon")
6924 (const_string "vector")
6925 (eq_attr "alternative" "1,2")
6926 (const_string "vector")]
6927 (const_string "direct")))
6928 (set_attr "mode" "HI")])
6930 (define_expand "mulqi3"
6931 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6932 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6933 (match_operand:QI 2 "register_operand" "")))
6934 (clobber (reg:CC FLAGS_REG))])]
6935 "TARGET_QIMODE_MATH"
6938 (define_insn "*mulqi3_1"
6939 [(set (match_operand:QI 0 "register_operand" "=a")
6940 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6941 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6942 (clobber (reg:CC FLAGS_REG))]
6944 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6946 [(set_attr "type" "imul")
6947 (set_attr "length_immediate" "0")
6948 (set (attr "athlon_decode")
6949 (if_then_else (eq_attr "cpu" "athlon")
6950 (const_string "vector")
6951 (const_string "direct")))
6952 (set_attr "mode" "QI")])
6954 (define_expand "umulqihi3"
6955 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6956 (mult:HI (zero_extend:HI
6957 (match_operand:QI 1 "nonimmediate_operand" ""))
6959 (match_operand:QI 2 "register_operand" ""))))
6960 (clobber (reg:CC FLAGS_REG))])]
6961 "TARGET_QIMODE_MATH"
6964 (define_insn "*umulqihi3_1"
6965 [(set (match_operand:HI 0 "register_operand" "=a")
6966 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6967 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6968 (clobber (reg:CC FLAGS_REG))]
6970 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6972 [(set_attr "type" "imul")
6973 (set_attr "length_immediate" "0")
6974 (set (attr "athlon_decode")
6975 (if_then_else (eq_attr "cpu" "athlon")
6976 (const_string "vector")
6977 (const_string "direct")))
6978 (set_attr "mode" "QI")])
6980 (define_expand "mulqihi3"
6981 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6982 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6983 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6984 (clobber (reg:CC FLAGS_REG))])]
6985 "TARGET_QIMODE_MATH"
6988 (define_insn "*mulqihi3_insn"
6989 [(set (match_operand:HI 0 "register_operand" "=a")
6990 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6991 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6992 (clobber (reg:CC FLAGS_REG))]
6994 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6996 [(set_attr "type" "imul")
6997 (set_attr "length_immediate" "0")
6998 (set (attr "athlon_decode")
6999 (if_then_else (eq_attr "cpu" "athlon")
7000 (const_string "vector")
7001 (const_string "direct")))
7002 (set_attr "mode" "QI")])
7004 (define_expand "umulditi3"
7005 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7006 (mult:TI (zero_extend:TI
7007 (match_operand:DI 1 "nonimmediate_operand" ""))
7009 (match_operand:DI 2 "register_operand" ""))))
7010 (clobber (reg:CC FLAGS_REG))])]
7014 (define_insn "*umulditi3_insn"
7015 [(set (match_operand:TI 0 "register_operand" "=A")
7016 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7017 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7018 (clobber (reg:CC FLAGS_REG))]
7020 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7022 [(set_attr "type" "imul")
7023 (set_attr "length_immediate" "0")
7024 (set (attr "athlon_decode")
7025 (if_then_else (eq_attr "cpu" "athlon")
7026 (const_string "vector")
7027 (const_string "double")))
7028 (set_attr "mode" "DI")])
7030 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7031 (define_expand "umulsidi3"
7032 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7033 (mult:DI (zero_extend:DI
7034 (match_operand:SI 1 "nonimmediate_operand" ""))
7036 (match_operand:SI 2 "register_operand" ""))))
7037 (clobber (reg:CC FLAGS_REG))])]
7041 (define_insn "*umulsidi3_insn"
7042 [(set (match_operand:DI 0 "register_operand" "=A")
7043 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7044 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7045 (clobber (reg:CC FLAGS_REG))]
7047 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7049 [(set_attr "type" "imul")
7050 (set_attr "length_immediate" "0")
7051 (set (attr "athlon_decode")
7052 (if_then_else (eq_attr "cpu" "athlon")
7053 (const_string "vector")
7054 (const_string "double")))
7055 (set_attr "mode" "SI")])
7057 (define_expand "mulditi3"
7058 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7059 (mult:TI (sign_extend:TI
7060 (match_operand:DI 1 "nonimmediate_operand" ""))
7062 (match_operand:DI 2 "register_operand" ""))))
7063 (clobber (reg:CC FLAGS_REG))])]
7067 (define_insn "*mulditi3_insn"
7068 [(set (match_operand:TI 0 "register_operand" "=A")
7069 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7070 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7071 (clobber (reg:CC FLAGS_REG))]
7073 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7075 [(set_attr "type" "imul")
7076 (set_attr "length_immediate" "0")
7077 (set (attr "athlon_decode")
7078 (if_then_else (eq_attr "cpu" "athlon")
7079 (const_string "vector")
7080 (const_string "double")))
7081 (set_attr "mode" "DI")])
7083 (define_expand "mulsidi3"
7084 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7085 (mult:DI (sign_extend:DI
7086 (match_operand:SI 1 "nonimmediate_operand" ""))
7088 (match_operand:SI 2 "register_operand" ""))))
7089 (clobber (reg:CC FLAGS_REG))])]
7093 (define_insn "*mulsidi3_insn"
7094 [(set (match_operand:DI 0 "register_operand" "=A")
7095 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7096 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7097 (clobber (reg:CC FLAGS_REG))]
7099 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7101 [(set_attr "type" "imul")
7102 (set_attr "length_immediate" "0")
7103 (set (attr "athlon_decode")
7104 (if_then_else (eq_attr "cpu" "athlon")
7105 (const_string "vector")
7106 (const_string "double")))
7107 (set_attr "mode" "SI")])
7109 (define_expand "umuldi3_highpart"
7110 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7113 (mult:TI (zero_extend:TI
7114 (match_operand:DI 1 "nonimmediate_operand" ""))
7116 (match_operand:DI 2 "register_operand" "")))
7118 (clobber (match_scratch:DI 3 ""))
7119 (clobber (reg:CC FLAGS_REG))])]
7123 (define_insn "*umuldi3_highpart_rex64"
7124 [(set (match_operand:DI 0 "register_operand" "=d")
7127 (mult:TI (zero_extend:TI
7128 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7130 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7132 (clobber (match_scratch:DI 3 "=1"))
7133 (clobber (reg:CC FLAGS_REG))]
7135 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7137 [(set_attr "type" "imul")
7138 (set_attr "length_immediate" "0")
7139 (set (attr "athlon_decode")
7140 (if_then_else (eq_attr "cpu" "athlon")
7141 (const_string "vector")
7142 (const_string "double")))
7143 (set_attr "mode" "DI")])
7145 (define_expand "umulsi3_highpart"
7146 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7149 (mult:DI (zero_extend:DI
7150 (match_operand:SI 1 "nonimmediate_operand" ""))
7152 (match_operand:SI 2 "register_operand" "")))
7154 (clobber (match_scratch:SI 3 ""))
7155 (clobber (reg:CC FLAGS_REG))])]
7159 (define_insn "*umulsi3_highpart_insn"
7160 [(set (match_operand:SI 0 "register_operand" "=d")
7163 (mult:DI (zero_extend:DI
7164 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7166 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7168 (clobber (match_scratch:SI 3 "=1"))
7169 (clobber (reg:CC FLAGS_REG))]
7170 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7172 [(set_attr "type" "imul")
7173 (set_attr "length_immediate" "0")
7174 (set (attr "athlon_decode")
7175 (if_then_else (eq_attr "cpu" "athlon")
7176 (const_string "vector")
7177 (const_string "double")))
7178 (set_attr "mode" "SI")])
7180 (define_insn "*umulsi3_highpart_zext"
7181 [(set (match_operand:DI 0 "register_operand" "=d")
7182 (zero_extend:DI (truncate:SI
7184 (mult:DI (zero_extend:DI
7185 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7187 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7189 (clobber (match_scratch:SI 3 "=1"))
7190 (clobber (reg:CC FLAGS_REG))]
7192 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7194 [(set_attr "type" "imul")
7195 (set_attr "length_immediate" "0")
7196 (set (attr "athlon_decode")
7197 (if_then_else (eq_attr "cpu" "athlon")
7198 (const_string "vector")
7199 (const_string "double")))
7200 (set_attr "mode" "SI")])
7202 (define_expand "smuldi3_highpart"
7203 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7206 (mult:TI (sign_extend:TI
7207 (match_operand:DI 1 "nonimmediate_operand" ""))
7209 (match_operand:DI 2 "register_operand" "")))
7211 (clobber (match_scratch:DI 3 ""))
7212 (clobber (reg:CC FLAGS_REG))])]
7216 (define_insn "*smuldi3_highpart_rex64"
7217 [(set (match_operand:DI 0 "register_operand" "=d")
7220 (mult:TI (sign_extend:TI
7221 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7223 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7225 (clobber (match_scratch:DI 3 "=1"))
7226 (clobber (reg:CC FLAGS_REG))]
7228 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7230 [(set_attr "type" "imul")
7231 (set (attr "athlon_decode")
7232 (if_then_else (eq_attr "cpu" "athlon")
7233 (const_string "vector")
7234 (const_string "double")))
7235 (set_attr "mode" "DI")])
7237 (define_expand "smulsi3_highpart"
7238 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7241 (mult:DI (sign_extend:DI
7242 (match_operand:SI 1 "nonimmediate_operand" ""))
7244 (match_operand:SI 2 "register_operand" "")))
7246 (clobber (match_scratch:SI 3 ""))
7247 (clobber (reg:CC FLAGS_REG))])]
7251 (define_insn "*smulsi3_highpart_insn"
7252 [(set (match_operand:SI 0 "register_operand" "=d")
7255 (mult:DI (sign_extend:DI
7256 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7258 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7260 (clobber (match_scratch:SI 3 "=1"))
7261 (clobber (reg:CC FLAGS_REG))]
7262 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7264 [(set_attr "type" "imul")
7265 (set (attr "athlon_decode")
7266 (if_then_else (eq_attr "cpu" "athlon")
7267 (const_string "vector")
7268 (const_string "double")))
7269 (set_attr "mode" "SI")])
7271 (define_insn "*smulsi3_highpart_zext"
7272 [(set (match_operand:DI 0 "register_operand" "=d")
7273 (zero_extend:DI (truncate:SI
7275 (mult:DI (sign_extend:DI
7276 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7278 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7280 (clobber (match_scratch:SI 3 "=1"))
7281 (clobber (reg:CC FLAGS_REG))]
7283 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7285 [(set_attr "type" "imul")
7286 (set (attr "athlon_decode")
7287 (if_then_else (eq_attr "cpu" "athlon")
7288 (const_string "vector")
7289 (const_string "double")))
7290 (set_attr "mode" "SI")])
7292 ;; The patterns that match these are at the end of this file.
7294 (define_expand "mulxf3"
7295 [(set (match_operand:XF 0 "register_operand" "")
7296 (mult:XF (match_operand:XF 1 "register_operand" "")
7297 (match_operand:XF 2 "register_operand" "")))]
7301 (define_expand "muldf3"
7302 [(set (match_operand:DF 0 "register_operand" "")
7303 (mult:DF (match_operand:DF 1 "register_operand" "")
7304 (match_operand:DF 2 "nonimmediate_operand" "")))]
7305 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7308 (define_expand "mulsf3"
7309 [(set (match_operand:SF 0 "register_operand" "")
7310 (mult:SF (match_operand:SF 1 "register_operand" "")
7311 (match_operand:SF 2 "nonimmediate_operand" "")))]
7312 "TARGET_80387 || TARGET_SSE_MATH"
7315 ;; Divide instructions
7317 (define_insn "divqi3"
7318 [(set (match_operand:QI 0 "register_operand" "=a")
7319 (div:QI (match_operand:HI 1 "register_operand" "0")
7320 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7321 (clobber (reg:CC FLAGS_REG))]
7322 "TARGET_QIMODE_MATH"
7324 [(set_attr "type" "idiv")
7325 (set_attr "mode" "QI")])
7327 (define_insn "udivqi3"
7328 [(set (match_operand:QI 0 "register_operand" "=a")
7329 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7330 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7331 (clobber (reg:CC FLAGS_REG))]
7332 "TARGET_QIMODE_MATH"
7334 [(set_attr "type" "idiv")
7335 (set_attr "mode" "QI")])
7337 ;; The patterns that match these are at the end of this file.
7339 (define_expand "divxf3"
7340 [(set (match_operand:XF 0 "register_operand" "")
7341 (div:XF (match_operand:XF 1 "register_operand" "")
7342 (match_operand:XF 2 "register_operand" "")))]
7346 (define_expand "divdf3"
7347 [(set (match_operand:DF 0 "register_operand" "")
7348 (div:DF (match_operand:DF 1 "register_operand" "")
7349 (match_operand:DF 2 "nonimmediate_operand" "")))]
7350 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7353 (define_expand "divsf3"
7354 [(set (match_operand:SF 0 "register_operand" "")
7355 (div:SF (match_operand:SF 1 "register_operand" "")
7356 (match_operand:SF 2 "nonimmediate_operand" "")))]
7357 "TARGET_80387 || TARGET_SSE_MATH"
7360 ;; Remainder instructions.
7362 (define_expand "divmoddi4"
7363 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7364 (div:DI (match_operand:DI 1 "register_operand" "")
7365 (match_operand:DI 2 "nonimmediate_operand" "")))
7366 (set (match_operand:DI 3 "register_operand" "")
7367 (mod:DI (match_dup 1) (match_dup 2)))
7368 (clobber (reg:CC FLAGS_REG))])]
7372 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7373 ;; Penalize eax case slightly because it results in worse scheduling
7375 (define_insn "*divmoddi4_nocltd_rex64"
7376 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7377 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7378 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7379 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7380 (mod:DI (match_dup 2) (match_dup 3)))
7381 (clobber (reg:CC FLAGS_REG))]
7382 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7384 [(set_attr "type" "multi")])
7386 (define_insn "*divmoddi4_cltd_rex64"
7387 [(set (match_operand:DI 0 "register_operand" "=a")
7388 (div:DI (match_operand:DI 2 "register_operand" "a")
7389 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7390 (set (match_operand:DI 1 "register_operand" "=&d")
7391 (mod:DI (match_dup 2) (match_dup 3)))
7392 (clobber (reg:CC FLAGS_REG))]
7393 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7395 [(set_attr "type" "multi")])
7397 (define_insn "*divmoddi_noext_rex64"
7398 [(set (match_operand:DI 0 "register_operand" "=a")
7399 (div:DI (match_operand:DI 1 "register_operand" "0")
7400 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7401 (set (match_operand:DI 3 "register_operand" "=d")
7402 (mod:DI (match_dup 1) (match_dup 2)))
7403 (use (match_operand:DI 4 "register_operand" "3"))
7404 (clobber (reg:CC FLAGS_REG))]
7407 [(set_attr "type" "idiv")
7408 (set_attr "mode" "DI")])
7411 [(set (match_operand:DI 0 "register_operand" "")
7412 (div:DI (match_operand:DI 1 "register_operand" "")
7413 (match_operand:DI 2 "nonimmediate_operand" "")))
7414 (set (match_operand:DI 3 "register_operand" "")
7415 (mod:DI (match_dup 1) (match_dup 2)))
7416 (clobber (reg:CC FLAGS_REG))]
7417 "TARGET_64BIT && reload_completed"
7418 [(parallel [(set (match_dup 3)
7419 (ashiftrt:DI (match_dup 4) (const_int 63)))
7420 (clobber (reg:CC FLAGS_REG))])
7421 (parallel [(set (match_dup 0)
7422 (div:DI (reg:DI 0) (match_dup 2)))
7424 (mod:DI (reg:DI 0) (match_dup 2)))
7426 (clobber (reg:CC FLAGS_REG))])]
7428 /* Avoid use of cltd in favor of a mov+shift. */
7429 if (!TARGET_USE_CLTD && !optimize_size)
7431 if (true_regnum (operands[1]))
7432 emit_move_insn (operands[0], operands[1]);
7434 emit_move_insn (operands[3], operands[1]);
7435 operands[4] = operands[3];
7439 gcc_assert (!true_regnum (operands[1]));
7440 operands[4] = operands[1];
7445 (define_expand "divmodsi4"
7446 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7447 (div:SI (match_operand:SI 1 "register_operand" "")
7448 (match_operand:SI 2 "nonimmediate_operand" "")))
7449 (set (match_operand:SI 3 "register_operand" "")
7450 (mod:SI (match_dup 1) (match_dup 2)))
7451 (clobber (reg:CC FLAGS_REG))])]
7455 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7456 ;; Penalize eax case slightly because it results in worse scheduling
7458 (define_insn "*divmodsi4_nocltd"
7459 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7460 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7461 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7462 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7463 (mod:SI (match_dup 2) (match_dup 3)))
7464 (clobber (reg:CC FLAGS_REG))]
7465 "!optimize_size && !TARGET_USE_CLTD"
7467 [(set_attr "type" "multi")])
7469 (define_insn "*divmodsi4_cltd"
7470 [(set (match_operand:SI 0 "register_operand" "=a")
7471 (div:SI (match_operand:SI 2 "register_operand" "a")
7472 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7473 (set (match_operand:SI 1 "register_operand" "=&d")
7474 (mod:SI (match_dup 2) (match_dup 3)))
7475 (clobber (reg:CC FLAGS_REG))]
7476 "optimize_size || TARGET_USE_CLTD"
7478 [(set_attr "type" "multi")])
7480 (define_insn "*divmodsi_noext"
7481 [(set (match_operand:SI 0 "register_operand" "=a")
7482 (div:SI (match_operand:SI 1 "register_operand" "0")
7483 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7484 (set (match_operand:SI 3 "register_operand" "=d")
7485 (mod:SI (match_dup 1) (match_dup 2)))
7486 (use (match_operand:SI 4 "register_operand" "3"))
7487 (clobber (reg:CC FLAGS_REG))]
7490 [(set_attr "type" "idiv")
7491 (set_attr "mode" "SI")])
7494 [(set (match_operand:SI 0 "register_operand" "")
7495 (div:SI (match_operand:SI 1 "register_operand" "")
7496 (match_operand:SI 2 "nonimmediate_operand" "")))
7497 (set (match_operand:SI 3 "register_operand" "")
7498 (mod:SI (match_dup 1) (match_dup 2)))
7499 (clobber (reg:CC FLAGS_REG))]
7501 [(parallel [(set (match_dup 3)
7502 (ashiftrt:SI (match_dup 4) (const_int 31)))
7503 (clobber (reg:CC FLAGS_REG))])
7504 (parallel [(set (match_dup 0)
7505 (div:SI (reg:SI 0) (match_dup 2)))
7507 (mod:SI (reg:SI 0) (match_dup 2)))
7509 (clobber (reg:CC FLAGS_REG))])]
7511 /* Avoid use of cltd in favor of a mov+shift. */
7512 if (!TARGET_USE_CLTD && !optimize_size)
7514 if (true_regnum (operands[1]))
7515 emit_move_insn (operands[0], operands[1]);
7517 emit_move_insn (operands[3], operands[1]);
7518 operands[4] = operands[3];
7522 gcc_assert (!true_regnum (operands[1]));
7523 operands[4] = operands[1];
7527 (define_insn "divmodhi4"
7528 [(set (match_operand:HI 0 "register_operand" "=a")
7529 (div:HI (match_operand:HI 1 "register_operand" "0")
7530 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7531 (set (match_operand:HI 3 "register_operand" "=&d")
7532 (mod:HI (match_dup 1) (match_dup 2)))
7533 (clobber (reg:CC FLAGS_REG))]
7534 "TARGET_HIMODE_MATH"
7536 [(set_attr "type" "multi")
7537 (set_attr "length_immediate" "0")
7538 (set_attr "mode" "SI")])
7540 (define_insn "udivmoddi4"
7541 [(set (match_operand:DI 0 "register_operand" "=a")
7542 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7543 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7544 (set (match_operand:DI 3 "register_operand" "=&d")
7545 (umod:DI (match_dup 1) (match_dup 2)))
7546 (clobber (reg:CC FLAGS_REG))]
7548 "xor{q}\t%3, %3\;div{q}\t%2"
7549 [(set_attr "type" "multi")
7550 (set_attr "length_immediate" "0")
7551 (set_attr "mode" "DI")])
7553 (define_insn "*udivmoddi4_noext"
7554 [(set (match_operand:DI 0 "register_operand" "=a")
7555 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7556 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7557 (set (match_operand:DI 3 "register_operand" "=d")
7558 (umod:DI (match_dup 1) (match_dup 2)))
7560 (clobber (reg:CC FLAGS_REG))]
7563 [(set_attr "type" "idiv")
7564 (set_attr "mode" "DI")])
7567 [(set (match_operand:DI 0 "register_operand" "")
7568 (udiv:DI (match_operand:DI 1 "register_operand" "")
7569 (match_operand:DI 2 "nonimmediate_operand" "")))
7570 (set (match_operand:DI 3 "register_operand" "")
7571 (umod:DI (match_dup 1) (match_dup 2)))
7572 (clobber (reg:CC FLAGS_REG))]
7573 "TARGET_64BIT && reload_completed"
7574 [(set (match_dup 3) (const_int 0))
7575 (parallel [(set (match_dup 0)
7576 (udiv:DI (match_dup 1) (match_dup 2)))
7578 (umod:DI (match_dup 1) (match_dup 2)))
7580 (clobber (reg:CC FLAGS_REG))])]
7583 (define_insn "udivmodsi4"
7584 [(set (match_operand:SI 0 "register_operand" "=a")
7585 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7586 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7587 (set (match_operand:SI 3 "register_operand" "=&d")
7588 (umod:SI (match_dup 1) (match_dup 2)))
7589 (clobber (reg:CC FLAGS_REG))]
7591 "xor{l}\t%3, %3\;div{l}\t%2"
7592 [(set_attr "type" "multi")
7593 (set_attr "length_immediate" "0")
7594 (set_attr "mode" "SI")])
7596 (define_insn "*udivmodsi4_noext"
7597 [(set (match_operand:SI 0 "register_operand" "=a")
7598 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7599 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7600 (set (match_operand:SI 3 "register_operand" "=d")
7601 (umod:SI (match_dup 1) (match_dup 2)))
7603 (clobber (reg:CC FLAGS_REG))]
7606 [(set_attr "type" "idiv")
7607 (set_attr "mode" "SI")])
7610 [(set (match_operand:SI 0 "register_operand" "")
7611 (udiv:SI (match_operand:SI 1 "register_operand" "")
7612 (match_operand:SI 2 "nonimmediate_operand" "")))
7613 (set (match_operand:SI 3 "register_operand" "")
7614 (umod:SI (match_dup 1) (match_dup 2)))
7615 (clobber (reg:CC FLAGS_REG))]
7617 [(set (match_dup 3) (const_int 0))
7618 (parallel [(set (match_dup 0)
7619 (udiv:SI (match_dup 1) (match_dup 2)))
7621 (umod:SI (match_dup 1) (match_dup 2)))
7623 (clobber (reg:CC FLAGS_REG))])]
7626 (define_expand "udivmodhi4"
7627 [(set (match_dup 4) (const_int 0))
7628 (parallel [(set (match_operand:HI 0 "register_operand" "")
7629 (udiv:HI (match_operand:HI 1 "register_operand" "")
7630 (match_operand:HI 2 "nonimmediate_operand" "")))
7631 (set (match_operand:HI 3 "register_operand" "")
7632 (umod:HI (match_dup 1) (match_dup 2)))
7634 (clobber (reg:CC FLAGS_REG))])]
7635 "TARGET_HIMODE_MATH"
7636 "operands[4] = gen_reg_rtx (HImode);")
7638 (define_insn "*udivmodhi_noext"
7639 [(set (match_operand:HI 0 "register_operand" "=a")
7640 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7641 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7642 (set (match_operand:HI 3 "register_operand" "=d")
7643 (umod:HI (match_dup 1) (match_dup 2)))
7644 (use (match_operand:HI 4 "register_operand" "3"))
7645 (clobber (reg:CC FLAGS_REG))]
7648 [(set_attr "type" "idiv")
7649 (set_attr "mode" "HI")])
7651 ;; We cannot use div/idiv for double division, because it causes
7652 ;; "division by zero" on the overflow and that's not what we expect
7653 ;; from truncate. Because true (non truncating) double division is
7654 ;; never generated, we can't create this insn anyway.
7657 ; [(set (match_operand:SI 0 "register_operand" "=a")
7659 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7661 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7662 ; (set (match_operand:SI 3 "register_operand" "=d")
7664 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7665 ; (clobber (reg:CC FLAGS_REG))]
7667 ; "div{l}\t{%2, %0|%0, %2}"
7668 ; [(set_attr "type" "idiv")])
7670 ;;- Logical AND instructions
7672 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7673 ;; Note that this excludes ah.
7675 (define_insn "*testdi_1_rex64"
7676 [(set (reg FLAGS_REG)
7678 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7679 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7681 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7682 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7684 test{l}\t{%k1, %k0|%k0, %k1}
7685 test{l}\t{%k1, %k0|%k0, %k1}
7686 test{q}\t{%1, %0|%0, %1}
7687 test{q}\t{%1, %0|%0, %1}
7688 test{q}\t{%1, %0|%0, %1}"
7689 [(set_attr "type" "test")
7690 (set_attr "modrm" "0,1,0,1,1")
7691 (set_attr "mode" "SI,SI,DI,DI,DI")
7692 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7694 (define_insn "testsi_1"
7695 [(set (reg FLAGS_REG)
7697 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7698 (match_operand:SI 1 "general_operand" "in,in,rin"))
7700 "ix86_match_ccmode (insn, CCNOmode)
7701 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7702 "test{l}\t{%1, %0|%0, %1}"
7703 [(set_attr "type" "test")
7704 (set_attr "modrm" "0,1,1")
7705 (set_attr "mode" "SI")
7706 (set_attr "pent_pair" "uv,np,uv")])
7708 (define_expand "testsi_ccno_1"
7709 [(set (reg:CCNO FLAGS_REG)
7711 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7712 (match_operand:SI 1 "nonmemory_operand" ""))
7717 (define_insn "*testhi_1"
7718 [(set (reg FLAGS_REG)
7719 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7720 (match_operand:HI 1 "general_operand" "n,n,rn"))
7722 "ix86_match_ccmode (insn, CCNOmode)
7723 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7724 "test{w}\t{%1, %0|%0, %1}"
7725 [(set_attr "type" "test")
7726 (set_attr "modrm" "0,1,1")
7727 (set_attr "mode" "HI")
7728 (set_attr "pent_pair" "uv,np,uv")])
7730 (define_expand "testqi_ccz_1"
7731 [(set (reg:CCZ FLAGS_REG)
7732 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7733 (match_operand:QI 1 "nonmemory_operand" ""))
7738 (define_insn "*testqi_1_maybe_si"
7739 [(set (reg FLAGS_REG)
7742 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7743 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7745 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7746 && ix86_match_ccmode (insn,
7747 GET_CODE (operands[1]) == CONST_INT
7748 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7750 if (which_alternative == 3)
7752 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7753 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7754 return "test{l}\t{%1, %k0|%k0, %1}";
7756 return "test{b}\t{%1, %0|%0, %1}";
7758 [(set_attr "type" "test")
7759 (set_attr "modrm" "0,1,1,1")
7760 (set_attr "mode" "QI,QI,QI,SI")
7761 (set_attr "pent_pair" "uv,np,uv,np")])
7763 (define_insn "*testqi_1"
7764 [(set (reg FLAGS_REG)
7767 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7768 (match_operand:QI 1 "general_operand" "n,n,qn"))
7770 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7771 && ix86_match_ccmode (insn, CCNOmode)"
7772 "test{b}\t{%1, %0|%0, %1}"
7773 [(set_attr "type" "test")
7774 (set_attr "modrm" "0,1,1")
7775 (set_attr "mode" "QI")
7776 (set_attr "pent_pair" "uv,np,uv")])
7778 (define_expand "testqi_ext_ccno_0"
7779 [(set (reg:CCNO FLAGS_REG)
7783 (match_operand 0 "ext_register_operand" "")
7786 (match_operand 1 "const_int_operand" ""))
7791 (define_insn "*testqi_ext_0"
7792 [(set (reg FLAGS_REG)
7796 (match_operand 0 "ext_register_operand" "Q")
7799 (match_operand 1 "const_int_operand" "n"))
7801 "ix86_match_ccmode (insn, CCNOmode)"
7802 "test{b}\t{%1, %h0|%h0, %1}"
7803 [(set_attr "type" "test")
7804 (set_attr "mode" "QI")
7805 (set_attr "length_immediate" "1")
7806 (set_attr "pent_pair" "np")])
7808 (define_insn "*testqi_ext_1"
7809 [(set (reg FLAGS_REG)
7813 (match_operand 0 "ext_register_operand" "Q")
7817 (match_operand:QI 1 "general_operand" "Qm")))
7819 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7820 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7821 "test{b}\t{%1, %h0|%h0, %1}"
7822 [(set_attr "type" "test")
7823 (set_attr "mode" "QI")])
7825 (define_insn "*testqi_ext_1_rex64"
7826 [(set (reg FLAGS_REG)
7830 (match_operand 0 "ext_register_operand" "Q")
7834 (match_operand:QI 1 "register_operand" "Q")))
7836 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7837 "test{b}\t{%1, %h0|%h0, %1}"
7838 [(set_attr "type" "test")
7839 (set_attr "mode" "QI")])
7841 (define_insn "*testqi_ext_2"
7842 [(set (reg FLAGS_REG)
7846 (match_operand 0 "ext_register_operand" "Q")
7850 (match_operand 1 "ext_register_operand" "Q")
7854 "ix86_match_ccmode (insn, CCNOmode)"
7855 "test{b}\t{%h1, %h0|%h0, %h1}"
7856 [(set_attr "type" "test")
7857 (set_attr "mode" "QI")])
7859 ;; Combine likes to form bit extractions for some tests. Humor it.
7860 (define_insn "*testqi_ext_3"
7861 [(set (reg FLAGS_REG)
7862 (compare (zero_extract:SI
7863 (match_operand 0 "nonimmediate_operand" "rm")
7864 (match_operand:SI 1 "const_int_operand" "")
7865 (match_operand:SI 2 "const_int_operand" ""))
7867 "ix86_match_ccmode (insn, CCNOmode)
7868 && (GET_MODE (operands[0]) == SImode
7869 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7870 || GET_MODE (operands[0]) == HImode
7871 || GET_MODE (operands[0]) == QImode)"
7874 (define_insn "*testqi_ext_3_rex64"
7875 [(set (reg FLAGS_REG)
7876 (compare (zero_extract:DI
7877 (match_operand 0 "nonimmediate_operand" "rm")
7878 (match_operand:DI 1 "const_int_operand" "")
7879 (match_operand:DI 2 "const_int_operand" ""))
7882 && ix86_match_ccmode (insn, CCNOmode)
7883 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7884 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7885 /* Ensure that resulting mask is zero or sign extended operand. */
7886 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7887 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7888 && INTVAL (operands[1]) > 32))
7889 && (GET_MODE (operands[0]) == SImode
7890 || GET_MODE (operands[0]) == DImode
7891 || GET_MODE (operands[0]) == HImode
7892 || GET_MODE (operands[0]) == QImode)"
7896 [(set (match_operand 0 "flags_reg_operand" "")
7897 (match_operator 1 "compare_operator"
7899 (match_operand 2 "nonimmediate_operand" "")
7900 (match_operand 3 "const_int_operand" "")
7901 (match_operand 4 "const_int_operand" ""))
7903 "ix86_match_ccmode (insn, CCNOmode)"
7904 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7906 rtx val = operands[2];
7907 HOST_WIDE_INT len = INTVAL (operands[3]);
7908 HOST_WIDE_INT pos = INTVAL (operands[4]);
7910 enum machine_mode mode, submode;
7912 mode = GET_MODE (val);
7913 if (GET_CODE (val) == MEM)
7915 /* ??? Combine likes to put non-volatile mem extractions in QImode
7916 no matter the size of the test. So find a mode that works. */
7917 if (! MEM_VOLATILE_P (val))
7919 mode = smallest_mode_for_size (pos + len, MODE_INT);
7920 val = adjust_address (val, mode, 0);
7923 else if (GET_CODE (val) == SUBREG
7924 && (submode = GET_MODE (SUBREG_REG (val)),
7925 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7926 && pos + len <= GET_MODE_BITSIZE (submode))
7928 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7930 val = SUBREG_REG (val);
7932 else if (mode == HImode && pos + len <= 8)
7934 /* Small HImode tests can be converted to QImode. */
7936 val = gen_lowpart (QImode, val);
7939 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7940 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7942 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7945 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7946 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7947 ;; this is relatively important trick.
7948 ;; Do the conversion only post-reload to avoid limiting of the register class
7951 [(set (match_operand 0 "flags_reg_operand" "")
7952 (match_operator 1 "compare_operator"
7953 [(and (match_operand 2 "register_operand" "")
7954 (match_operand 3 "const_int_operand" ""))
7957 && QI_REG_P (operands[2])
7958 && GET_MODE (operands[2]) != QImode
7959 && ((ix86_match_ccmode (insn, CCZmode)
7960 && !(INTVAL (operands[3]) & ~(255 << 8)))
7961 || (ix86_match_ccmode (insn, CCNOmode)
7962 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7965 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7968 "operands[2] = gen_lowpart (SImode, operands[2]);
7969 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7972 [(set (match_operand 0 "flags_reg_operand" "")
7973 (match_operator 1 "compare_operator"
7974 [(and (match_operand 2 "nonimmediate_operand" "")
7975 (match_operand 3 "const_int_operand" ""))
7978 && GET_MODE (operands[2]) != QImode
7979 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7980 && ((ix86_match_ccmode (insn, CCZmode)
7981 && !(INTVAL (operands[3]) & ~255))
7982 || (ix86_match_ccmode (insn, CCNOmode)
7983 && !(INTVAL (operands[3]) & ~127)))"
7985 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7987 "operands[2] = gen_lowpart (QImode, operands[2]);
7988 operands[3] = gen_lowpart (QImode, operands[3]);")
7991 ;; %%% This used to optimize known byte-wide and operations to memory,
7992 ;; and sometimes to QImode registers. If this is considered useful,
7993 ;; it should be done with splitters.
7995 (define_expand "anddi3"
7996 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7997 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7998 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7999 (clobber (reg:CC FLAGS_REG))]
8001 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8003 (define_insn "*anddi_1_rex64"
8004 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8005 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8006 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8007 (clobber (reg:CC FLAGS_REG))]
8008 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8010 switch (get_attr_type (insn))
8014 enum machine_mode mode;
8016 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8017 if (INTVAL (operands[2]) == 0xff)
8021 gcc_assert (INTVAL (operands[2]) == 0xffff);
8025 operands[1] = gen_lowpart (mode, operands[1]);
8027 return "movz{bq|x}\t{%1,%0|%0, %1}";
8029 return "movz{wq|x}\t{%1,%0|%0, %1}";
8033 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8034 if (get_attr_mode (insn) == MODE_SI)
8035 return "and{l}\t{%k2, %k0|%k0, %k2}";
8037 return "and{q}\t{%2, %0|%0, %2}";
8040 [(set_attr "type" "alu,alu,alu,imovx")
8041 (set_attr "length_immediate" "*,*,*,0")
8042 (set_attr "mode" "SI,DI,DI,DI")])
8044 (define_insn "*anddi_2"
8045 [(set (reg FLAGS_REG)
8046 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8047 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8049 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8050 (and:DI (match_dup 1) (match_dup 2)))]
8051 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8052 && ix86_binary_operator_ok (AND, DImode, operands)"
8054 and{l}\t{%k2, %k0|%k0, %k2}
8055 and{q}\t{%2, %0|%0, %2}
8056 and{q}\t{%2, %0|%0, %2}"
8057 [(set_attr "type" "alu")
8058 (set_attr "mode" "SI,DI,DI")])
8060 (define_expand "andsi3"
8061 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8062 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8063 (match_operand:SI 2 "general_operand" "")))
8064 (clobber (reg:CC FLAGS_REG))]
8066 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8068 (define_insn "*andsi_1"
8069 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8070 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8071 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8072 (clobber (reg:CC FLAGS_REG))]
8073 "ix86_binary_operator_ok (AND, SImode, operands)"
8075 switch (get_attr_type (insn))
8079 enum machine_mode mode;
8081 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8082 if (INTVAL (operands[2]) == 0xff)
8086 gcc_assert (INTVAL (operands[2]) == 0xffff);
8090 operands[1] = gen_lowpart (mode, operands[1]);
8092 return "movz{bl|x}\t{%1,%0|%0, %1}";
8094 return "movz{wl|x}\t{%1,%0|%0, %1}";
8098 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8099 return "and{l}\t{%2, %0|%0, %2}";
8102 [(set_attr "type" "alu,alu,imovx")
8103 (set_attr "length_immediate" "*,*,0")
8104 (set_attr "mode" "SI")])
8107 [(set (match_operand 0 "register_operand" "")
8109 (const_int -65536)))
8110 (clobber (reg:CC FLAGS_REG))]
8111 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8112 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8113 "operands[1] = gen_lowpart (HImode, operands[0]);")
8116 [(set (match_operand 0 "ext_register_operand" "")
8119 (clobber (reg:CC FLAGS_REG))]
8120 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8121 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8122 "operands[1] = gen_lowpart (QImode, operands[0]);")
8125 [(set (match_operand 0 "ext_register_operand" "")
8127 (const_int -65281)))
8128 (clobber (reg:CC FLAGS_REG))]
8129 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8130 [(parallel [(set (zero_extract:SI (match_dup 0)
8134 (zero_extract:SI (match_dup 0)
8137 (zero_extract:SI (match_dup 0)
8140 (clobber (reg:CC FLAGS_REG))])]
8141 "operands[0] = gen_lowpart (SImode, operands[0]);")
8143 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8144 (define_insn "*andsi_1_zext"
8145 [(set (match_operand:DI 0 "register_operand" "=r")
8147 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8148 (match_operand:SI 2 "general_operand" "rim"))))
8149 (clobber (reg:CC FLAGS_REG))]
8150 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8151 "and{l}\t{%2, %k0|%k0, %2}"
8152 [(set_attr "type" "alu")
8153 (set_attr "mode" "SI")])
8155 (define_insn "*andsi_2"
8156 [(set (reg FLAGS_REG)
8157 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8158 (match_operand:SI 2 "general_operand" "rim,ri"))
8160 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8161 (and:SI (match_dup 1) (match_dup 2)))]
8162 "ix86_match_ccmode (insn, CCNOmode)
8163 && ix86_binary_operator_ok (AND, SImode, operands)"
8164 "and{l}\t{%2, %0|%0, %2}"
8165 [(set_attr "type" "alu")
8166 (set_attr "mode" "SI")])
8168 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8169 (define_insn "*andsi_2_zext"
8170 [(set (reg FLAGS_REG)
8171 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8172 (match_operand:SI 2 "general_operand" "rim"))
8174 (set (match_operand:DI 0 "register_operand" "=r")
8175 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8176 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8177 && ix86_binary_operator_ok (AND, SImode, operands)"
8178 "and{l}\t{%2, %k0|%k0, %2}"
8179 [(set_attr "type" "alu")
8180 (set_attr "mode" "SI")])
8182 (define_expand "andhi3"
8183 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8184 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8185 (match_operand:HI 2 "general_operand" "")))
8186 (clobber (reg:CC FLAGS_REG))]
8187 "TARGET_HIMODE_MATH"
8188 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8190 (define_insn "*andhi_1"
8191 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8192 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8193 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 "ix86_binary_operator_ok (AND, HImode, operands)"
8197 switch (get_attr_type (insn))
8200 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8201 gcc_assert (INTVAL (operands[2]) == 0xff);
8202 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8205 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8207 return "and{w}\t{%2, %0|%0, %2}";
8210 [(set_attr "type" "alu,alu,imovx")
8211 (set_attr "length_immediate" "*,*,0")
8212 (set_attr "mode" "HI,HI,SI")])
8214 (define_insn "*andhi_2"
8215 [(set (reg FLAGS_REG)
8216 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8217 (match_operand:HI 2 "general_operand" "rim,ri"))
8219 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8220 (and:HI (match_dup 1) (match_dup 2)))]
8221 "ix86_match_ccmode (insn, CCNOmode)
8222 && ix86_binary_operator_ok (AND, HImode, operands)"
8223 "and{w}\t{%2, %0|%0, %2}"
8224 [(set_attr "type" "alu")
8225 (set_attr "mode" "HI")])
8227 (define_expand "andqi3"
8228 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8229 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8230 (match_operand:QI 2 "general_operand" "")))
8231 (clobber (reg:CC FLAGS_REG))]
8232 "TARGET_QIMODE_MATH"
8233 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8235 ;; %%% Potential partial reg stall on alternative 2. What to do?
8236 (define_insn "*andqi_1"
8237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8238 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8239 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8240 (clobber (reg:CC FLAGS_REG))]
8241 "ix86_binary_operator_ok (AND, QImode, operands)"
8243 and{b}\t{%2, %0|%0, %2}
8244 and{b}\t{%2, %0|%0, %2}
8245 and{l}\t{%k2, %k0|%k0, %k2}"
8246 [(set_attr "type" "alu")
8247 (set_attr "mode" "QI,QI,SI")])
8249 (define_insn "*andqi_1_slp"
8250 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8251 (and:QI (match_dup 0)
8252 (match_operand:QI 1 "general_operand" "qi,qmi")))
8253 (clobber (reg:CC FLAGS_REG))]
8254 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8255 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8256 "and{b}\t{%1, %0|%0, %1}"
8257 [(set_attr "type" "alu1")
8258 (set_attr "mode" "QI")])
8260 (define_insn "*andqi_2_maybe_si"
8261 [(set (reg FLAGS_REG)
8263 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8264 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8266 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8267 (and:QI (match_dup 1) (match_dup 2)))]
8268 "ix86_binary_operator_ok (AND, QImode, operands)
8269 && ix86_match_ccmode (insn,
8270 GET_CODE (operands[2]) == CONST_INT
8271 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8273 if (which_alternative == 2)
8275 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8276 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8277 return "and{l}\t{%2, %k0|%k0, %2}";
8279 return "and{b}\t{%2, %0|%0, %2}";
8281 [(set_attr "type" "alu")
8282 (set_attr "mode" "QI,QI,SI")])
8284 (define_insn "*andqi_2"
8285 [(set (reg FLAGS_REG)
8287 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8288 (match_operand:QI 2 "general_operand" "qim,qi"))
8290 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8291 (and:QI (match_dup 1) (match_dup 2)))]
8292 "ix86_match_ccmode (insn, CCNOmode)
8293 && ix86_binary_operator_ok (AND, QImode, operands)"
8294 "and{b}\t{%2, %0|%0, %2}"
8295 [(set_attr "type" "alu")
8296 (set_attr "mode" "QI")])
8298 (define_insn "*andqi_2_slp"
8299 [(set (reg FLAGS_REG)
8301 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8302 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8304 (set (strict_low_part (match_dup 0))
8305 (and:QI (match_dup 0) (match_dup 1)))]
8306 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8307 && ix86_match_ccmode (insn, CCNOmode)
8308 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8309 "and{b}\t{%1, %0|%0, %1}"
8310 [(set_attr "type" "alu1")
8311 (set_attr "mode" "QI")])
8313 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8314 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8315 ;; for a QImode operand, which of course failed.
8317 (define_insn "andqi_ext_0"
8318 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8323 (match_operand 1 "ext_register_operand" "0")
8326 (match_operand 2 "const_int_operand" "n")))
8327 (clobber (reg:CC FLAGS_REG))]
8329 "and{b}\t{%2, %h0|%h0, %2}"
8330 [(set_attr "type" "alu")
8331 (set_attr "length_immediate" "1")
8332 (set_attr "mode" "QI")])
8334 ;; Generated by peephole translating test to and. This shows up
8335 ;; often in fp comparisons.
8337 (define_insn "*andqi_ext_0_cc"
8338 [(set (reg FLAGS_REG)
8342 (match_operand 1 "ext_register_operand" "0")
8345 (match_operand 2 "const_int_operand" "n"))
8347 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8356 "ix86_match_ccmode (insn, CCNOmode)"
8357 "and{b}\t{%2, %h0|%h0, %2}"
8358 [(set_attr "type" "alu")
8359 (set_attr "length_immediate" "1")
8360 (set_attr "mode" "QI")])
8362 (define_insn "*andqi_ext_1"
8363 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8368 (match_operand 1 "ext_register_operand" "0")
8372 (match_operand:QI 2 "general_operand" "Qm"))))
8373 (clobber (reg:CC FLAGS_REG))]
8375 "and{b}\t{%2, %h0|%h0, %2}"
8376 [(set_attr "type" "alu")
8377 (set_attr "length_immediate" "0")
8378 (set_attr "mode" "QI")])
8380 (define_insn "*andqi_ext_1_rex64"
8381 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8386 (match_operand 1 "ext_register_operand" "0")
8390 (match_operand 2 "ext_register_operand" "Q"))))
8391 (clobber (reg:CC FLAGS_REG))]
8393 "and{b}\t{%2, %h0|%h0, %2}"
8394 [(set_attr "type" "alu")
8395 (set_attr "length_immediate" "0")
8396 (set_attr "mode" "QI")])
8398 (define_insn "*andqi_ext_2"
8399 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8404 (match_operand 1 "ext_register_operand" "%0")
8408 (match_operand 2 "ext_register_operand" "Q")
8411 (clobber (reg:CC FLAGS_REG))]
8413 "and{b}\t{%h2, %h0|%h0, %h2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "length_immediate" "0")
8416 (set_attr "mode" "QI")])
8418 ;; Convert wide AND instructions with immediate operand to shorter QImode
8419 ;; equivalents when possible.
8420 ;; Don't do the splitting with memory operands, since it introduces risk
8421 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8422 ;; for size, but that can (should?) be handled by generic code instead.
8424 [(set (match_operand 0 "register_operand" "")
8425 (and (match_operand 1 "register_operand" "")
8426 (match_operand 2 "const_int_operand" "")))
8427 (clobber (reg:CC FLAGS_REG))]
8429 && QI_REG_P (operands[0])
8430 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8431 && !(~INTVAL (operands[2]) & ~(255 << 8))
8432 && GET_MODE (operands[0]) != QImode"
8433 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8434 (and:SI (zero_extract:SI (match_dup 1)
8435 (const_int 8) (const_int 8))
8437 (clobber (reg:CC FLAGS_REG))])]
8438 "operands[0] = gen_lowpart (SImode, operands[0]);
8439 operands[1] = gen_lowpart (SImode, operands[1]);
8440 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8442 ;; Since AND can be encoded with sign extended immediate, this is only
8443 ;; profitable when 7th bit is not set.
8445 [(set (match_operand 0 "register_operand" "")
8446 (and (match_operand 1 "general_operand" "")
8447 (match_operand 2 "const_int_operand" "")))
8448 (clobber (reg:CC FLAGS_REG))]
8450 && ANY_QI_REG_P (operands[0])
8451 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8452 && !(~INTVAL (operands[2]) & ~255)
8453 && !(INTVAL (operands[2]) & 128)
8454 && GET_MODE (operands[0]) != QImode"
8455 [(parallel [(set (strict_low_part (match_dup 0))
8456 (and:QI (match_dup 1)
8458 (clobber (reg:CC FLAGS_REG))])]
8459 "operands[0] = gen_lowpart (QImode, operands[0]);
8460 operands[1] = gen_lowpart (QImode, operands[1]);
8461 operands[2] = gen_lowpart (QImode, operands[2]);")
8463 ;; Logical inclusive OR instructions
8465 ;; %%% This used to optimize known byte-wide and operations to memory.
8466 ;; If this is considered useful, it should be done with splitters.
8468 (define_expand "iordi3"
8469 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8470 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8471 (match_operand:DI 2 "x86_64_general_operand" "")))
8472 (clobber (reg:CC FLAGS_REG))]
8474 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8476 (define_insn "*iordi_1_rex64"
8477 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8478 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8479 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8480 (clobber (reg:CC FLAGS_REG))]
8482 && ix86_binary_operator_ok (IOR, DImode, operands)"
8483 "or{q}\t{%2, %0|%0, %2}"
8484 [(set_attr "type" "alu")
8485 (set_attr "mode" "DI")])
8487 (define_insn "*iordi_2_rex64"
8488 [(set (reg FLAGS_REG)
8489 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8490 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8492 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8493 (ior:DI (match_dup 1) (match_dup 2)))]
8495 && ix86_match_ccmode (insn, CCNOmode)
8496 && ix86_binary_operator_ok (IOR, DImode, operands)"
8497 "or{q}\t{%2, %0|%0, %2}"
8498 [(set_attr "type" "alu")
8499 (set_attr "mode" "DI")])
8501 (define_insn "*iordi_3_rex64"
8502 [(set (reg FLAGS_REG)
8503 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8504 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8506 (clobber (match_scratch:DI 0 "=r"))]
8508 && ix86_match_ccmode (insn, CCNOmode)
8509 && ix86_binary_operator_ok (IOR, DImode, operands)"
8510 "or{q}\t{%2, %0|%0, %2}"
8511 [(set_attr "type" "alu")
8512 (set_attr "mode" "DI")])
8515 (define_expand "iorsi3"
8516 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8517 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8518 (match_operand:SI 2 "general_operand" "")))
8519 (clobber (reg:CC FLAGS_REG))]
8521 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8523 (define_insn "*iorsi_1"
8524 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8525 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8526 (match_operand:SI 2 "general_operand" "ri,rmi")))
8527 (clobber (reg:CC FLAGS_REG))]
8528 "ix86_binary_operator_ok (IOR, SImode, operands)"
8529 "or{l}\t{%2, %0|%0, %2}"
8530 [(set_attr "type" "alu")
8531 (set_attr "mode" "SI")])
8533 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8534 (define_insn "*iorsi_1_zext"
8535 [(set (match_operand:DI 0 "register_operand" "=rm")
8537 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8538 (match_operand:SI 2 "general_operand" "rim"))))
8539 (clobber (reg:CC FLAGS_REG))]
8540 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8541 "or{l}\t{%2, %k0|%k0, %2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "mode" "SI")])
8545 (define_insn "*iorsi_1_zext_imm"
8546 [(set (match_operand:DI 0 "register_operand" "=rm")
8547 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8548 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8549 (clobber (reg:CC FLAGS_REG))]
8551 "or{l}\t{%2, %k0|%k0, %2}"
8552 [(set_attr "type" "alu")
8553 (set_attr "mode" "SI")])
8555 (define_insn "*iorsi_2"
8556 [(set (reg FLAGS_REG)
8557 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8558 (match_operand:SI 2 "general_operand" "rim,ri"))
8560 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8561 (ior:SI (match_dup 1) (match_dup 2)))]
8562 "ix86_match_ccmode (insn, CCNOmode)
8563 && ix86_binary_operator_ok (IOR, SImode, operands)"
8564 "or{l}\t{%2, %0|%0, %2}"
8565 [(set_attr "type" "alu")
8566 (set_attr "mode" "SI")])
8568 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8569 ;; ??? Special case for immediate operand is missing - it is tricky.
8570 (define_insn "*iorsi_2_zext"
8571 [(set (reg FLAGS_REG)
8572 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8573 (match_operand:SI 2 "general_operand" "rim"))
8575 (set (match_operand:DI 0 "register_operand" "=r")
8576 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8577 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8578 && ix86_binary_operator_ok (IOR, SImode, operands)"
8579 "or{l}\t{%2, %k0|%k0, %2}"
8580 [(set_attr "type" "alu")
8581 (set_attr "mode" "SI")])
8583 (define_insn "*iorsi_2_zext_imm"
8584 [(set (reg FLAGS_REG)
8585 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8586 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8588 (set (match_operand:DI 0 "register_operand" "=r")
8589 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8590 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8591 && ix86_binary_operator_ok (IOR, SImode, operands)"
8592 "or{l}\t{%2, %k0|%k0, %2}"
8593 [(set_attr "type" "alu")
8594 (set_attr "mode" "SI")])
8596 (define_insn "*iorsi_3"
8597 [(set (reg FLAGS_REG)
8598 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8599 (match_operand:SI 2 "general_operand" "rim"))
8601 (clobber (match_scratch:SI 0 "=r"))]
8602 "ix86_match_ccmode (insn, CCNOmode)
8603 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8604 "or{l}\t{%2, %0|%0, %2}"
8605 [(set_attr "type" "alu")
8606 (set_attr "mode" "SI")])
8608 (define_expand "iorhi3"
8609 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8610 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8611 (match_operand:HI 2 "general_operand" "")))
8612 (clobber (reg:CC FLAGS_REG))]
8613 "TARGET_HIMODE_MATH"
8614 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8616 (define_insn "*iorhi_1"
8617 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8618 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8619 (match_operand:HI 2 "general_operand" "rmi,ri")))
8620 (clobber (reg:CC FLAGS_REG))]
8621 "ix86_binary_operator_ok (IOR, HImode, operands)"
8622 "or{w}\t{%2, %0|%0, %2}"
8623 [(set_attr "type" "alu")
8624 (set_attr "mode" "HI")])
8626 (define_insn "*iorhi_2"
8627 [(set (reg FLAGS_REG)
8628 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8629 (match_operand:HI 2 "general_operand" "rim,ri"))
8631 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8632 (ior:HI (match_dup 1) (match_dup 2)))]
8633 "ix86_match_ccmode (insn, CCNOmode)
8634 && ix86_binary_operator_ok (IOR, HImode, operands)"
8635 "or{w}\t{%2, %0|%0, %2}"
8636 [(set_attr "type" "alu")
8637 (set_attr "mode" "HI")])
8639 (define_insn "*iorhi_3"
8640 [(set (reg FLAGS_REG)
8641 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8642 (match_operand:HI 2 "general_operand" "rim"))
8644 (clobber (match_scratch:HI 0 "=r"))]
8645 "ix86_match_ccmode (insn, CCNOmode)
8646 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8647 "or{w}\t{%2, %0|%0, %2}"
8648 [(set_attr "type" "alu")
8649 (set_attr "mode" "HI")])
8651 (define_expand "iorqi3"
8652 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8653 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8654 (match_operand:QI 2 "general_operand" "")))
8655 (clobber (reg:CC FLAGS_REG))]
8656 "TARGET_QIMODE_MATH"
8657 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8659 ;; %%% Potential partial reg stall on alternative 2. What to do?
8660 (define_insn "*iorqi_1"
8661 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8662 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8663 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8664 (clobber (reg:CC FLAGS_REG))]
8665 "ix86_binary_operator_ok (IOR, QImode, operands)"
8667 or{b}\t{%2, %0|%0, %2}
8668 or{b}\t{%2, %0|%0, %2}
8669 or{l}\t{%k2, %k0|%k0, %k2}"
8670 [(set_attr "type" "alu")
8671 (set_attr "mode" "QI,QI,SI")])
8673 (define_insn "*iorqi_1_slp"
8674 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8675 (ior:QI (match_dup 0)
8676 (match_operand:QI 1 "general_operand" "qmi,qi")))
8677 (clobber (reg:CC FLAGS_REG))]
8678 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8679 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8680 "or{b}\t{%1, %0|%0, %1}"
8681 [(set_attr "type" "alu1")
8682 (set_attr "mode" "QI")])
8684 (define_insn "*iorqi_2"
8685 [(set (reg FLAGS_REG)
8686 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8687 (match_operand:QI 2 "general_operand" "qim,qi"))
8689 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8690 (ior:QI (match_dup 1) (match_dup 2)))]
8691 "ix86_match_ccmode (insn, CCNOmode)
8692 && ix86_binary_operator_ok (IOR, QImode, operands)"
8693 "or{b}\t{%2, %0|%0, %2}"
8694 [(set_attr "type" "alu")
8695 (set_attr "mode" "QI")])
8697 (define_insn "*iorqi_2_slp"
8698 [(set (reg FLAGS_REG)
8699 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8700 (match_operand:QI 1 "general_operand" "qim,qi"))
8702 (set (strict_low_part (match_dup 0))
8703 (ior:QI (match_dup 0) (match_dup 1)))]
8704 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8705 && ix86_match_ccmode (insn, CCNOmode)
8706 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8707 "or{b}\t{%1, %0|%0, %1}"
8708 [(set_attr "type" "alu1")
8709 (set_attr "mode" "QI")])
8711 (define_insn "*iorqi_3"
8712 [(set (reg FLAGS_REG)
8713 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8714 (match_operand:QI 2 "general_operand" "qim"))
8716 (clobber (match_scratch:QI 0 "=q"))]
8717 "ix86_match_ccmode (insn, CCNOmode)
8718 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8719 "or{b}\t{%2, %0|%0, %2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "mode" "QI")])
8723 (define_insn "iorqi_ext_0"
8724 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8729 (match_operand 1 "ext_register_operand" "0")
8732 (match_operand 2 "const_int_operand" "n")))
8733 (clobber (reg:CC FLAGS_REG))]
8734 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8735 "or{b}\t{%2, %h0|%h0, %2}"
8736 [(set_attr "type" "alu")
8737 (set_attr "length_immediate" "1")
8738 (set_attr "mode" "QI")])
8740 (define_insn "*iorqi_ext_1"
8741 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8746 (match_operand 1 "ext_register_operand" "0")
8750 (match_operand:QI 2 "general_operand" "Qm"))))
8751 (clobber (reg:CC FLAGS_REG))]
8753 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8754 "or{b}\t{%2, %h0|%h0, %2}"
8755 [(set_attr "type" "alu")
8756 (set_attr "length_immediate" "0")
8757 (set_attr "mode" "QI")])
8759 (define_insn "*iorqi_ext_1_rex64"
8760 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8765 (match_operand 1 "ext_register_operand" "0")
8769 (match_operand 2 "ext_register_operand" "Q"))))
8770 (clobber (reg:CC FLAGS_REG))]
8772 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8773 "or{b}\t{%2, %h0|%h0, %2}"
8774 [(set_attr "type" "alu")
8775 (set_attr "length_immediate" "0")
8776 (set_attr "mode" "QI")])
8778 (define_insn "*iorqi_ext_2"
8779 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8783 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8786 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8789 (clobber (reg:CC FLAGS_REG))]
8790 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8791 "ior{b}\t{%h2, %h0|%h0, %h2}"
8792 [(set_attr "type" "alu")
8793 (set_attr "length_immediate" "0")
8794 (set_attr "mode" "QI")])
8797 [(set (match_operand 0 "register_operand" "")
8798 (ior (match_operand 1 "register_operand" "")
8799 (match_operand 2 "const_int_operand" "")))
8800 (clobber (reg:CC FLAGS_REG))]
8802 && QI_REG_P (operands[0])
8803 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8804 && !(INTVAL (operands[2]) & ~(255 << 8))
8805 && GET_MODE (operands[0]) != QImode"
8806 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8807 (ior:SI (zero_extract:SI (match_dup 1)
8808 (const_int 8) (const_int 8))
8810 (clobber (reg:CC FLAGS_REG))])]
8811 "operands[0] = gen_lowpart (SImode, operands[0]);
8812 operands[1] = gen_lowpart (SImode, operands[1]);
8813 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8815 ;; Since OR can be encoded with sign extended immediate, this is only
8816 ;; profitable when 7th bit is set.
8818 [(set (match_operand 0 "register_operand" "")
8819 (ior (match_operand 1 "general_operand" "")
8820 (match_operand 2 "const_int_operand" "")))
8821 (clobber (reg:CC FLAGS_REG))]
8823 && ANY_QI_REG_P (operands[0])
8824 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8825 && !(INTVAL (operands[2]) & ~255)
8826 && (INTVAL (operands[2]) & 128)
8827 && GET_MODE (operands[0]) != QImode"
8828 [(parallel [(set (strict_low_part (match_dup 0))
8829 (ior:QI (match_dup 1)
8831 (clobber (reg:CC FLAGS_REG))])]
8832 "operands[0] = gen_lowpart (QImode, operands[0]);
8833 operands[1] = gen_lowpart (QImode, operands[1]);
8834 operands[2] = gen_lowpart (QImode, operands[2]);")
8836 ;; Logical XOR instructions
8838 ;; %%% This used to optimize known byte-wide and operations to memory.
8839 ;; If this is considered useful, it should be done with splitters.
8841 (define_expand "xordi3"
8842 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8843 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8844 (match_operand:DI 2 "x86_64_general_operand" "")))
8845 (clobber (reg:CC FLAGS_REG))]
8847 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8849 (define_insn "*xordi_1_rex64"
8850 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8851 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8852 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8853 (clobber (reg:CC FLAGS_REG))]
8855 && ix86_binary_operator_ok (XOR, DImode, operands)"
8857 xor{q}\t{%2, %0|%0, %2}
8858 xor{q}\t{%2, %0|%0, %2}"
8859 [(set_attr "type" "alu")
8860 (set_attr "mode" "DI,DI")])
8862 (define_insn "*xordi_2_rex64"
8863 [(set (reg FLAGS_REG)
8864 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8865 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8867 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8868 (xor:DI (match_dup 1) (match_dup 2)))]
8870 && ix86_match_ccmode (insn, CCNOmode)
8871 && ix86_binary_operator_ok (XOR, DImode, operands)"
8873 xor{q}\t{%2, %0|%0, %2}
8874 xor{q}\t{%2, %0|%0, %2}"
8875 [(set_attr "type" "alu")
8876 (set_attr "mode" "DI,DI")])
8878 (define_insn "*xordi_3_rex64"
8879 [(set (reg FLAGS_REG)
8880 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8881 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8883 (clobber (match_scratch:DI 0 "=r"))]
8885 && ix86_match_ccmode (insn, CCNOmode)
8886 && ix86_binary_operator_ok (XOR, DImode, operands)"
8887 "xor{q}\t{%2, %0|%0, %2}"
8888 [(set_attr "type" "alu")
8889 (set_attr "mode" "DI")])
8891 (define_expand "xorsi3"
8892 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8893 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8894 (match_operand:SI 2 "general_operand" "")))
8895 (clobber (reg:CC FLAGS_REG))]
8897 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8899 (define_insn "*xorsi_1"
8900 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8901 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8902 (match_operand:SI 2 "general_operand" "ri,rm")))
8903 (clobber (reg:CC FLAGS_REG))]
8904 "ix86_binary_operator_ok (XOR, SImode, operands)"
8905 "xor{l}\t{%2, %0|%0, %2}"
8906 [(set_attr "type" "alu")
8907 (set_attr "mode" "SI")])
8909 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8910 ;; Add speccase for immediates
8911 (define_insn "*xorsi_1_zext"
8912 [(set (match_operand:DI 0 "register_operand" "=r")
8914 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8915 (match_operand:SI 2 "general_operand" "rim"))))
8916 (clobber (reg:CC FLAGS_REG))]
8917 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8918 "xor{l}\t{%2, %k0|%k0, %2}"
8919 [(set_attr "type" "alu")
8920 (set_attr "mode" "SI")])
8922 (define_insn "*xorsi_1_zext_imm"
8923 [(set (match_operand:DI 0 "register_operand" "=r")
8924 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8925 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8926 (clobber (reg:CC FLAGS_REG))]
8927 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8928 "xor{l}\t{%2, %k0|%k0, %2}"
8929 [(set_attr "type" "alu")
8930 (set_attr "mode" "SI")])
8932 (define_insn "*xorsi_2"
8933 [(set (reg FLAGS_REG)
8934 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8935 (match_operand:SI 2 "general_operand" "rim,ri"))
8937 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8938 (xor:SI (match_dup 1) (match_dup 2)))]
8939 "ix86_match_ccmode (insn, CCNOmode)
8940 && ix86_binary_operator_ok (XOR, SImode, operands)"
8941 "xor{l}\t{%2, %0|%0, %2}"
8942 [(set_attr "type" "alu")
8943 (set_attr "mode" "SI")])
8945 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8946 ;; ??? Special case for immediate operand is missing - it is tricky.
8947 (define_insn "*xorsi_2_zext"
8948 [(set (reg FLAGS_REG)
8949 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8950 (match_operand:SI 2 "general_operand" "rim"))
8952 (set (match_operand:DI 0 "register_operand" "=r")
8953 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8954 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8955 && ix86_binary_operator_ok (XOR, SImode, operands)"
8956 "xor{l}\t{%2, %k0|%k0, %2}"
8957 [(set_attr "type" "alu")
8958 (set_attr "mode" "SI")])
8960 (define_insn "*xorsi_2_zext_imm"
8961 [(set (reg FLAGS_REG)
8962 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8963 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8965 (set (match_operand:DI 0 "register_operand" "=r")
8966 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8967 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8968 && ix86_binary_operator_ok (XOR, SImode, operands)"
8969 "xor{l}\t{%2, %k0|%k0, %2}"
8970 [(set_attr "type" "alu")
8971 (set_attr "mode" "SI")])
8973 (define_insn "*xorsi_3"
8974 [(set (reg FLAGS_REG)
8975 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8976 (match_operand:SI 2 "general_operand" "rim"))
8978 (clobber (match_scratch:SI 0 "=r"))]
8979 "ix86_match_ccmode (insn, CCNOmode)
8980 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8981 "xor{l}\t{%2, %0|%0, %2}"
8982 [(set_attr "type" "alu")
8983 (set_attr "mode" "SI")])
8985 (define_expand "xorhi3"
8986 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8987 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8988 (match_operand:HI 2 "general_operand" "")))
8989 (clobber (reg:CC FLAGS_REG))]
8990 "TARGET_HIMODE_MATH"
8991 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8993 (define_insn "*xorhi_1"
8994 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8995 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8996 (match_operand:HI 2 "general_operand" "rmi,ri")))
8997 (clobber (reg:CC FLAGS_REG))]
8998 "ix86_binary_operator_ok (XOR, HImode, operands)"
8999 "xor{w}\t{%2, %0|%0, %2}"
9000 [(set_attr "type" "alu")
9001 (set_attr "mode" "HI")])
9003 (define_insn "*xorhi_2"
9004 [(set (reg FLAGS_REG)
9005 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9006 (match_operand:HI 2 "general_operand" "rim,ri"))
9008 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9009 (xor:HI (match_dup 1) (match_dup 2)))]
9010 "ix86_match_ccmode (insn, CCNOmode)
9011 && ix86_binary_operator_ok (XOR, HImode, operands)"
9012 "xor{w}\t{%2, %0|%0, %2}"
9013 [(set_attr "type" "alu")
9014 (set_attr "mode" "HI")])
9016 (define_insn "*xorhi_3"
9017 [(set (reg FLAGS_REG)
9018 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9019 (match_operand:HI 2 "general_operand" "rim"))
9021 (clobber (match_scratch:HI 0 "=r"))]
9022 "ix86_match_ccmode (insn, CCNOmode)
9023 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9024 "xor{w}\t{%2, %0|%0, %2}"
9025 [(set_attr "type" "alu")
9026 (set_attr "mode" "HI")])
9028 (define_expand "xorqi3"
9029 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9030 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9031 (match_operand:QI 2 "general_operand" "")))
9032 (clobber (reg:CC FLAGS_REG))]
9033 "TARGET_QIMODE_MATH"
9034 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9036 ;; %%% Potential partial reg stall on alternative 2. What to do?
9037 (define_insn "*xorqi_1"
9038 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9039 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9040 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9041 (clobber (reg:CC FLAGS_REG))]
9042 "ix86_binary_operator_ok (XOR, QImode, operands)"
9044 xor{b}\t{%2, %0|%0, %2}
9045 xor{b}\t{%2, %0|%0, %2}
9046 xor{l}\t{%k2, %k0|%k0, %k2}"
9047 [(set_attr "type" "alu")
9048 (set_attr "mode" "QI,QI,SI")])
9050 (define_insn "*xorqi_1_slp"
9051 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9052 (xor:QI (match_dup 0)
9053 (match_operand:QI 1 "general_operand" "qi,qmi")))
9054 (clobber (reg:CC FLAGS_REG))]
9055 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9056 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9057 "xor{b}\t{%1, %0|%0, %1}"
9058 [(set_attr "type" "alu1")
9059 (set_attr "mode" "QI")])
9061 (define_insn "xorqi_ext_0"
9062 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9067 (match_operand 1 "ext_register_operand" "0")
9070 (match_operand 2 "const_int_operand" "n")))
9071 (clobber (reg:CC FLAGS_REG))]
9072 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9073 "xor{b}\t{%2, %h0|%h0, %2}"
9074 [(set_attr "type" "alu")
9075 (set_attr "length_immediate" "1")
9076 (set_attr "mode" "QI")])
9078 (define_insn "*xorqi_ext_1"
9079 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9084 (match_operand 1 "ext_register_operand" "0")
9088 (match_operand:QI 2 "general_operand" "Qm"))))
9089 (clobber (reg:CC FLAGS_REG))]
9091 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9092 "xor{b}\t{%2, %h0|%h0, %2}"
9093 [(set_attr "type" "alu")
9094 (set_attr "length_immediate" "0")
9095 (set_attr "mode" "QI")])
9097 (define_insn "*xorqi_ext_1_rex64"
9098 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9103 (match_operand 1 "ext_register_operand" "0")
9107 (match_operand 2 "ext_register_operand" "Q"))))
9108 (clobber (reg:CC FLAGS_REG))]
9110 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9111 "xor{b}\t{%2, %h0|%h0, %2}"
9112 [(set_attr "type" "alu")
9113 (set_attr "length_immediate" "0")
9114 (set_attr "mode" "QI")])
9116 (define_insn "*xorqi_ext_2"
9117 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9121 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9124 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9127 (clobber (reg:CC FLAGS_REG))]
9128 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9129 "xor{b}\t{%h2, %h0|%h0, %h2}"
9130 [(set_attr "type" "alu")
9131 (set_attr "length_immediate" "0")
9132 (set_attr "mode" "QI")])
9134 (define_insn "*xorqi_cc_1"
9135 [(set (reg FLAGS_REG)
9137 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9138 (match_operand:QI 2 "general_operand" "qim,qi"))
9140 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9141 (xor:QI (match_dup 1) (match_dup 2)))]
9142 "ix86_match_ccmode (insn, CCNOmode)
9143 && ix86_binary_operator_ok (XOR, QImode, operands)"
9144 "xor{b}\t{%2, %0|%0, %2}"
9145 [(set_attr "type" "alu")
9146 (set_attr "mode" "QI")])
9148 (define_insn "*xorqi_2_slp"
9149 [(set (reg FLAGS_REG)
9150 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9151 (match_operand:QI 1 "general_operand" "qim,qi"))
9153 (set (strict_low_part (match_dup 0))
9154 (xor:QI (match_dup 0) (match_dup 1)))]
9155 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9156 && ix86_match_ccmode (insn, CCNOmode)
9157 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9158 "xor{b}\t{%1, %0|%0, %1}"
9159 [(set_attr "type" "alu1")
9160 (set_attr "mode" "QI")])
9162 (define_insn "*xorqi_cc_2"
9163 [(set (reg FLAGS_REG)
9165 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9166 (match_operand:QI 2 "general_operand" "qim"))
9168 (clobber (match_scratch:QI 0 "=q"))]
9169 "ix86_match_ccmode (insn, CCNOmode)
9170 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9171 "xor{b}\t{%2, %0|%0, %2}"
9172 [(set_attr "type" "alu")
9173 (set_attr "mode" "QI")])
9175 (define_insn "*xorqi_cc_ext_1"
9176 [(set (reg FLAGS_REG)
9180 (match_operand 1 "ext_register_operand" "0")
9183 (match_operand:QI 2 "general_operand" "qmn"))
9185 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9189 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9191 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9192 "xor{b}\t{%2, %h0|%h0, %2}"
9193 [(set_attr "type" "alu")
9194 (set_attr "mode" "QI")])
9196 (define_insn "*xorqi_cc_ext_1_rex64"
9197 [(set (reg FLAGS_REG)
9201 (match_operand 1 "ext_register_operand" "0")
9204 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9206 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9210 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9212 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9213 "xor{b}\t{%2, %h0|%h0, %2}"
9214 [(set_attr "type" "alu")
9215 (set_attr "mode" "QI")])
9217 (define_expand "xorqi_cc_ext_1"
9219 (set (reg:CCNO FLAGS_REG)
9223 (match_operand 1 "ext_register_operand" "")
9226 (match_operand:QI 2 "general_operand" ""))
9228 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9232 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9238 [(set (match_operand 0 "register_operand" "")
9239 (xor (match_operand 1 "register_operand" "")
9240 (match_operand 2 "const_int_operand" "")))
9241 (clobber (reg:CC FLAGS_REG))]
9243 && QI_REG_P (operands[0])
9244 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9245 && !(INTVAL (operands[2]) & ~(255 << 8))
9246 && GET_MODE (operands[0]) != QImode"
9247 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9248 (xor:SI (zero_extract:SI (match_dup 1)
9249 (const_int 8) (const_int 8))
9251 (clobber (reg:CC FLAGS_REG))])]
9252 "operands[0] = gen_lowpart (SImode, operands[0]);
9253 operands[1] = gen_lowpart (SImode, operands[1]);
9254 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9256 ;; Since XOR can be encoded with sign extended immediate, this is only
9257 ;; profitable when 7th bit is set.
9259 [(set (match_operand 0 "register_operand" "")
9260 (xor (match_operand 1 "general_operand" "")
9261 (match_operand 2 "const_int_operand" "")))
9262 (clobber (reg:CC FLAGS_REG))]
9264 && ANY_QI_REG_P (operands[0])
9265 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9266 && !(INTVAL (operands[2]) & ~255)
9267 && (INTVAL (operands[2]) & 128)
9268 && GET_MODE (operands[0]) != QImode"
9269 [(parallel [(set (strict_low_part (match_dup 0))
9270 (xor:QI (match_dup 1)
9272 (clobber (reg:CC FLAGS_REG))])]
9273 "operands[0] = gen_lowpart (QImode, operands[0]);
9274 operands[1] = gen_lowpart (QImode, operands[1]);
9275 operands[2] = gen_lowpart (QImode, operands[2]);")
9277 ;; Negation instructions
9279 (define_expand "negti2"
9280 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9281 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9282 (clobber (reg:CC FLAGS_REG))])]
9284 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9286 (define_insn "*negti2_1"
9287 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9288 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9289 (clobber (reg:CC FLAGS_REG))]
9291 && ix86_unary_operator_ok (NEG, TImode, operands)"
9295 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9296 (neg:TI (match_operand:TI 1 "general_operand" "")))
9297 (clobber (reg:CC FLAGS_REG))]
9298 "TARGET_64BIT && reload_completed"
9300 [(set (reg:CCZ FLAGS_REG)
9301 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9302 (set (match_dup 0) (neg:DI (match_dup 2)))])
9305 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9308 (clobber (reg:CC FLAGS_REG))])
9311 (neg:DI (match_dup 1)))
9312 (clobber (reg:CC FLAGS_REG))])]
9313 "split_ti (operands+1, 1, operands+2, operands+3);
9314 split_ti (operands+0, 1, operands+0, operands+1);")
9316 (define_expand "negdi2"
9317 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9318 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9319 (clobber (reg:CC FLAGS_REG))])]
9321 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9323 (define_insn "*negdi2_1"
9324 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9325 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9326 (clobber (reg:CC FLAGS_REG))]
9328 && ix86_unary_operator_ok (NEG, DImode, operands)"
9332 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9333 (neg:DI (match_operand:DI 1 "general_operand" "")))
9334 (clobber (reg:CC FLAGS_REG))]
9335 "!TARGET_64BIT && reload_completed"
9337 [(set (reg:CCZ FLAGS_REG)
9338 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9339 (set (match_dup 0) (neg:SI (match_dup 2)))])
9342 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9345 (clobber (reg:CC FLAGS_REG))])
9348 (neg:SI (match_dup 1)))
9349 (clobber (reg:CC FLAGS_REG))])]
9350 "split_di (operands+1, 1, operands+2, operands+3);
9351 split_di (operands+0, 1, operands+0, operands+1);")
9353 (define_insn "*negdi2_1_rex64"
9354 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9355 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9356 (clobber (reg:CC FLAGS_REG))]
9357 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9359 [(set_attr "type" "negnot")
9360 (set_attr "mode" "DI")])
9362 ;; The problem with neg is that it does not perform (compare x 0),
9363 ;; it really performs (compare 0 x), which leaves us with the zero
9364 ;; flag being the only useful item.
9366 (define_insn "*negdi2_cmpz_rex64"
9367 [(set (reg:CCZ FLAGS_REG)
9368 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9370 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9371 (neg:DI (match_dup 1)))]
9372 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9374 [(set_attr "type" "negnot")
9375 (set_attr "mode" "DI")])
9378 (define_expand "negsi2"
9379 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9380 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9381 (clobber (reg:CC FLAGS_REG))])]
9383 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9385 (define_insn "*negsi2_1"
9386 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9387 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9388 (clobber (reg:CC FLAGS_REG))]
9389 "ix86_unary_operator_ok (NEG, SImode, operands)"
9391 [(set_attr "type" "negnot")
9392 (set_attr "mode" "SI")])
9394 ;; Combine is quite creative about this pattern.
9395 (define_insn "*negsi2_1_zext"
9396 [(set (match_operand:DI 0 "register_operand" "=r")
9397 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9400 (clobber (reg:CC FLAGS_REG))]
9401 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9403 [(set_attr "type" "negnot")
9404 (set_attr "mode" "SI")])
9406 ;; The problem with neg is that it does not perform (compare x 0),
9407 ;; it really performs (compare 0 x), which leaves us with the zero
9408 ;; flag being the only useful item.
9410 (define_insn "*negsi2_cmpz"
9411 [(set (reg:CCZ FLAGS_REG)
9412 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9414 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9415 (neg:SI (match_dup 1)))]
9416 "ix86_unary_operator_ok (NEG, SImode, operands)"
9418 [(set_attr "type" "negnot")
9419 (set_attr "mode" "SI")])
9421 (define_insn "*negsi2_cmpz_zext"
9422 [(set (reg:CCZ FLAGS_REG)
9423 (compare:CCZ (lshiftrt:DI
9425 (match_operand:DI 1 "register_operand" "0")
9429 (set (match_operand:DI 0 "register_operand" "=r")
9430 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9433 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9435 [(set_attr "type" "negnot")
9436 (set_attr "mode" "SI")])
9438 (define_expand "neghi2"
9439 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9440 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9441 (clobber (reg:CC FLAGS_REG))])]
9442 "TARGET_HIMODE_MATH"
9443 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9445 (define_insn "*neghi2_1"
9446 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9447 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9448 (clobber (reg:CC FLAGS_REG))]
9449 "ix86_unary_operator_ok (NEG, HImode, operands)"
9451 [(set_attr "type" "negnot")
9452 (set_attr "mode" "HI")])
9454 (define_insn "*neghi2_cmpz"
9455 [(set (reg:CCZ FLAGS_REG)
9456 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9458 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9459 (neg:HI (match_dup 1)))]
9460 "ix86_unary_operator_ok (NEG, HImode, operands)"
9462 [(set_attr "type" "negnot")
9463 (set_attr "mode" "HI")])
9465 (define_expand "negqi2"
9466 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9467 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9468 (clobber (reg:CC FLAGS_REG))])]
9469 "TARGET_QIMODE_MATH"
9470 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9472 (define_insn "*negqi2_1"
9473 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9474 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "ix86_unary_operator_ok (NEG, QImode, operands)"
9478 [(set_attr "type" "negnot")
9479 (set_attr "mode" "QI")])
9481 (define_insn "*negqi2_cmpz"
9482 [(set (reg:CCZ FLAGS_REG)
9483 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9485 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9486 (neg:QI (match_dup 1)))]
9487 "ix86_unary_operator_ok (NEG, QImode, operands)"
9489 [(set_attr "type" "negnot")
9490 (set_attr "mode" "QI")])
9492 ;; Changing of sign for FP values is doable using integer unit too.
9494 (define_expand "negsf2"
9495 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9496 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9497 "TARGET_80387 || TARGET_SSE_MATH"
9498 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9500 (define_expand "abssf2"
9501 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9502 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9503 "TARGET_80387 || TARGET_SSE_MATH"
9504 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9506 (define_insn "*absnegsf2_mixed"
9507 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9508 (match_operator:SF 3 "absneg_operator"
9509 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9510 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9511 (clobber (reg:CC FLAGS_REG))]
9512 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9513 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9516 (define_insn "*absnegsf2_sse"
9517 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9518 (match_operator:SF 3 "absneg_operator"
9519 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9520 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9521 (clobber (reg:CC FLAGS_REG))]
9523 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9526 (define_insn "*absnegsf2_i387"
9527 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9528 (match_operator:SF 3 "absneg_operator"
9529 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9530 (use (match_operand 2 "" ""))
9531 (clobber (reg:CC FLAGS_REG))]
9532 "TARGET_80387 && !TARGET_SSE_MATH
9533 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9536 (define_expand "copysignsf3"
9537 [(match_operand:SF 0 "register_operand" "")
9538 (match_operand:SF 1 "nonmemory_operand" "")
9539 (match_operand:SF 2 "register_operand" "")]
9542 ix86_expand_copysign (operands);
9546 (define_insn_and_split "copysignsf3_const"
9547 [(set (match_operand:SF 0 "register_operand" "=x")
9549 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9550 (match_operand:SF 2 "register_operand" "0")
9551 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9555 "&& reload_completed"
9558 ix86_split_copysign_const (operands);
9562 (define_insn "copysignsf3_var"
9563 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9565 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9566 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9567 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9568 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9570 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9575 [(set (match_operand:SF 0 "register_operand" "")
9577 [(match_operand:SF 2 "register_operand" "")
9578 (match_operand:SF 3 "register_operand" "")
9579 (match_operand:V4SF 4 "" "")
9580 (match_operand:V4SF 5 "" "")]
9582 (clobber (match_scratch:V4SF 1 ""))]
9583 "TARGET_SSE_MATH && reload_completed"
9586 ix86_split_copysign_var (operands);
9590 (define_expand "negdf2"
9591 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9592 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9593 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9594 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9596 (define_expand "absdf2"
9597 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9598 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9599 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9600 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9602 (define_insn "*absnegdf2_mixed"
9603 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9604 (match_operator:DF 3 "absneg_operator"
9605 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9606 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9607 (clobber (reg:CC FLAGS_REG))]
9608 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9609 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9612 (define_insn "*absnegdf2_sse"
9613 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9614 (match_operator:DF 3 "absneg_operator"
9615 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9616 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9617 (clobber (reg:CC FLAGS_REG))]
9618 "TARGET_SSE2 && TARGET_SSE_MATH
9619 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9622 (define_insn "*absnegdf2_i387"
9623 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9624 (match_operator:DF 3 "absneg_operator"
9625 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9626 (use (match_operand 2 "" ""))
9627 (clobber (reg:CC FLAGS_REG))]
9628 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9629 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9632 (define_expand "copysigndf3"
9633 [(match_operand:DF 0 "register_operand" "")
9634 (match_operand:DF 1 "nonmemory_operand" "")
9635 (match_operand:DF 2 "register_operand" "")]
9636 "TARGET_SSE2 && TARGET_SSE_MATH"
9638 ix86_expand_copysign (operands);
9642 (define_insn_and_split "copysigndf3_const"
9643 [(set (match_operand:DF 0 "register_operand" "=x")
9645 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9646 (match_operand:DF 2 "register_operand" "0")
9647 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9649 "TARGET_SSE2 && TARGET_SSE_MATH"
9651 "&& reload_completed"
9654 ix86_split_copysign_const (operands);
9658 (define_insn "copysigndf3_var"
9659 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9661 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9662 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9663 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9664 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9666 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9667 "TARGET_SSE2 && TARGET_SSE_MATH"
9671 [(set (match_operand:DF 0 "register_operand" "")
9673 [(match_operand:DF 2 "register_operand" "")
9674 (match_operand:DF 3 "register_operand" "")
9675 (match_operand:V2DF 4 "" "")
9676 (match_operand:V2DF 5 "" "")]
9678 (clobber (match_scratch:V2DF 1 ""))]
9679 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9682 ix86_split_copysign_var (operands);
9686 (define_expand "negxf2"
9687 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9688 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9690 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9692 (define_expand "absxf2"
9693 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9694 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9696 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9698 (define_insn "*absnegxf2_i387"
9699 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9700 (match_operator:XF 3 "absneg_operator"
9701 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9702 (use (match_operand 2 "" ""))
9703 (clobber (reg:CC FLAGS_REG))]
9705 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9708 ;; Splitters for fp abs and neg.
9711 [(set (match_operand 0 "fp_register_operand" "")
9712 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9713 (use (match_operand 2 "" ""))
9714 (clobber (reg:CC FLAGS_REG))]
9716 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9719 [(set (match_operand 0 "register_operand" "")
9720 (match_operator 3 "absneg_operator"
9721 [(match_operand 1 "register_operand" "")]))
9722 (use (match_operand 2 "nonimmediate_operand" ""))
9723 (clobber (reg:CC FLAGS_REG))]
9724 "reload_completed && SSE_REG_P (operands[0])"
9725 [(set (match_dup 0) (match_dup 3))]
9727 enum machine_mode mode = GET_MODE (operands[0]);
9728 enum machine_mode vmode = GET_MODE (operands[2]);
9731 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9732 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9733 if (operands_match_p (operands[0], operands[2]))
9736 operands[1] = operands[2];
9739 if (GET_CODE (operands[3]) == ABS)
9740 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9742 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9747 [(set (match_operand:SF 0 "register_operand" "")
9748 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9749 (use (match_operand:V4SF 2 "" ""))
9750 (clobber (reg:CC FLAGS_REG))]
9752 [(parallel [(set (match_dup 0) (match_dup 1))
9753 (clobber (reg:CC FLAGS_REG))])]
9756 operands[0] = gen_lowpart (SImode, operands[0]);
9757 if (GET_CODE (operands[1]) == ABS)
9759 tmp = gen_int_mode (0x7fffffff, SImode);
9760 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9764 tmp = gen_int_mode (0x80000000, SImode);
9765 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9771 [(set (match_operand:DF 0 "register_operand" "")
9772 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9773 (use (match_operand 2 "" ""))
9774 (clobber (reg:CC FLAGS_REG))]
9776 [(parallel [(set (match_dup 0) (match_dup 1))
9777 (clobber (reg:CC FLAGS_REG))])]
9782 tmp = gen_lowpart (DImode, operands[0]);
9783 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9786 if (GET_CODE (operands[1]) == ABS)
9789 tmp = gen_rtx_NOT (DImode, tmp);
9793 operands[0] = gen_highpart (SImode, operands[0]);
9794 if (GET_CODE (operands[1]) == ABS)
9796 tmp = gen_int_mode (0x7fffffff, SImode);
9797 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9801 tmp = gen_int_mode (0x80000000, SImode);
9802 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9809 [(set (match_operand:XF 0 "register_operand" "")
9810 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9811 (use (match_operand 2 "" ""))
9812 (clobber (reg:CC FLAGS_REG))]
9814 [(parallel [(set (match_dup 0) (match_dup 1))
9815 (clobber (reg:CC FLAGS_REG))])]
9818 operands[0] = gen_rtx_REG (SImode,
9819 true_regnum (operands[0])
9820 + (TARGET_64BIT ? 1 : 2));
9821 if (GET_CODE (operands[1]) == ABS)
9823 tmp = GEN_INT (0x7fff);
9824 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9828 tmp = GEN_INT (0x8000);
9829 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9835 [(set (match_operand 0 "memory_operand" "")
9836 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9837 (use (match_operand 2 "" ""))
9838 (clobber (reg:CC FLAGS_REG))]
9840 [(parallel [(set (match_dup 0) (match_dup 1))
9841 (clobber (reg:CC FLAGS_REG))])]
9843 enum machine_mode mode = GET_MODE (operands[0]);
9844 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9847 operands[0] = adjust_address (operands[0], QImode, size - 1);
9848 if (GET_CODE (operands[1]) == ABS)
9850 tmp = gen_int_mode (0x7f, QImode);
9851 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9855 tmp = gen_int_mode (0x80, QImode);
9856 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9861 ;; Conditionalize these after reload. If they match before reload, we
9862 ;; lose the clobber and ability to use integer instructions.
9864 (define_insn "*negsf2_1"
9865 [(set (match_operand:SF 0 "register_operand" "=f")
9866 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9867 "TARGET_80387 && reload_completed"
9869 [(set_attr "type" "fsgn")
9870 (set_attr "mode" "SF")])
9872 (define_insn "*negdf2_1"
9873 [(set (match_operand:DF 0 "register_operand" "=f")
9874 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9875 "TARGET_80387 && reload_completed"
9877 [(set_attr "type" "fsgn")
9878 (set_attr "mode" "DF")])
9880 (define_insn "*negxf2_1"
9881 [(set (match_operand:XF 0 "register_operand" "=f")
9882 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9883 "TARGET_80387 && reload_completed"
9885 [(set_attr "type" "fsgn")
9886 (set_attr "mode" "XF")])
9888 (define_insn "*abssf2_1"
9889 [(set (match_operand:SF 0 "register_operand" "=f")
9890 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9891 "TARGET_80387 && reload_completed"
9893 [(set_attr "type" "fsgn")
9894 (set_attr "mode" "SF")])
9896 (define_insn "*absdf2_1"
9897 [(set (match_operand:DF 0 "register_operand" "=f")
9898 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9899 "TARGET_80387 && reload_completed"
9901 [(set_attr "type" "fsgn")
9902 (set_attr "mode" "DF")])
9904 (define_insn "*absxf2_1"
9905 [(set (match_operand:XF 0 "register_operand" "=f")
9906 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9907 "TARGET_80387 && reload_completed"
9909 [(set_attr "type" "fsgn")
9910 (set_attr "mode" "DF")])
9912 (define_insn "*negextendsfdf2"
9913 [(set (match_operand:DF 0 "register_operand" "=f")
9914 (neg:DF (float_extend:DF
9915 (match_operand:SF 1 "register_operand" "0"))))]
9916 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9918 [(set_attr "type" "fsgn")
9919 (set_attr "mode" "DF")])
9921 (define_insn "*negextenddfxf2"
9922 [(set (match_operand:XF 0 "register_operand" "=f")
9923 (neg:XF (float_extend:XF
9924 (match_operand:DF 1 "register_operand" "0"))))]
9927 [(set_attr "type" "fsgn")
9928 (set_attr "mode" "XF")])
9930 (define_insn "*negextendsfxf2"
9931 [(set (match_operand:XF 0 "register_operand" "=f")
9932 (neg:XF (float_extend:XF
9933 (match_operand:SF 1 "register_operand" "0"))))]
9936 [(set_attr "type" "fsgn")
9937 (set_attr "mode" "XF")])
9939 (define_insn "*absextendsfdf2"
9940 [(set (match_operand:DF 0 "register_operand" "=f")
9941 (abs:DF (float_extend:DF
9942 (match_operand:SF 1 "register_operand" "0"))))]
9943 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9945 [(set_attr "type" "fsgn")
9946 (set_attr "mode" "DF")])
9948 (define_insn "*absextenddfxf2"
9949 [(set (match_operand:XF 0 "register_operand" "=f")
9950 (abs:XF (float_extend:XF
9951 (match_operand:DF 1 "register_operand" "0"))))]
9954 [(set_attr "type" "fsgn")
9955 (set_attr "mode" "XF")])
9957 (define_insn "*absextendsfxf2"
9958 [(set (match_operand:XF 0 "register_operand" "=f")
9959 (abs:XF (float_extend:XF
9960 (match_operand:SF 1 "register_operand" "0"))))]
9963 [(set_attr "type" "fsgn")
9964 (set_attr "mode" "XF")])
9966 ;; One complement instructions
9968 (define_expand "one_cmpldi2"
9969 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9970 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9972 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9974 (define_insn "*one_cmpldi2_1_rex64"
9975 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9976 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9977 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9979 [(set_attr "type" "negnot")
9980 (set_attr "mode" "DI")])
9982 (define_insn "*one_cmpldi2_2_rex64"
9983 [(set (reg FLAGS_REG)
9984 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9986 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9987 (not:DI (match_dup 1)))]
9988 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9989 && ix86_unary_operator_ok (NOT, DImode, operands)"
9991 [(set_attr "type" "alu1")
9992 (set_attr "mode" "DI")])
9995 [(set (match_operand 0 "flags_reg_operand" "")
9996 (match_operator 2 "compare_operator"
9997 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9999 (set (match_operand:DI 1 "nonimmediate_operand" "")
10000 (not:DI (match_dup 3)))]
10001 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10002 [(parallel [(set (match_dup 0)
10004 [(xor:DI (match_dup 3) (const_int -1))
10007 (xor:DI (match_dup 3) (const_int -1)))])]
10010 (define_expand "one_cmplsi2"
10011 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10012 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10014 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10016 (define_insn "*one_cmplsi2_1"
10017 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10018 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10019 "ix86_unary_operator_ok (NOT, SImode, operands)"
10021 [(set_attr "type" "negnot")
10022 (set_attr "mode" "SI")])
10024 ;; ??? Currently never generated - xor is used instead.
10025 (define_insn "*one_cmplsi2_1_zext"
10026 [(set (match_operand:DI 0 "register_operand" "=r")
10027 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10028 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10030 [(set_attr "type" "negnot")
10031 (set_attr "mode" "SI")])
10033 (define_insn "*one_cmplsi2_2"
10034 [(set (reg FLAGS_REG)
10035 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10037 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10038 (not:SI (match_dup 1)))]
10039 "ix86_match_ccmode (insn, CCNOmode)
10040 && ix86_unary_operator_ok (NOT, SImode, operands)"
10042 [(set_attr "type" "alu1")
10043 (set_attr "mode" "SI")])
10046 [(set (match_operand 0 "flags_reg_operand" "")
10047 (match_operator 2 "compare_operator"
10048 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10050 (set (match_operand:SI 1 "nonimmediate_operand" "")
10051 (not:SI (match_dup 3)))]
10052 "ix86_match_ccmode (insn, CCNOmode)"
10053 [(parallel [(set (match_dup 0)
10054 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10057 (xor:SI (match_dup 3) (const_int -1)))])]
10060 ;; ??? Currently never generated - xor is used instead.
10061 (define_insn "*one_cmplsi2_2_zext"
10062 [(set (reg FLAGS_REG)
10063 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10065 (set (match_operand:DI 0 "register_operand" "=r")
10066 (zero_extend:DI (not:SI (match_dup 1))))]
10067 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10068 && ix86_unary_operator_ok (NOT, SImode, operands)"
10070 [(set_attr "type" "alu1")
10071 (set_attr "mode" "SI")])
10074 [(set (match_operand 0 "flags_reg_operand" "")
10075 (match_operator 2 "compare_operator"
10076 [(not:SI (match_operand:SI 3 "register_operand" ""))
10078 (set (match_operand:DI 1 "register_operand" "")
10079 (zero_extend:DI (not:SI (match_dup 3))))]
10080 "ix86_match_ccmode (insn, CCNOmode)"
10081 [(parallel [(set (match_dup 0)
10082 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10085 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10088 (define_expand "one_cmplhi2"
10089 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10090 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10091 "TARGET_HIMODE_MATH"
10092 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10094 (define_insn "*one_cmplhi2_1"
10095 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10096 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10097 "ix86_unary_operator_ok (NOT, HImode, operands)"
10099 [(set_attr "type" "negnot")
10100 (set_attr "mode" "HI")])
10102 (define_insn "*one_cmplhi2_2"
10103 [(set (reg FLAGS_REG)
10104 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10106 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10107 (not:HI (match_dup 1)))]
10108 "ix86_match_ccmode (insn, CCNOmode)
10109 && ix86_unary_operator_ok (NEG, HImode, operands)"
10111 [(set_attr "type" "alu1")
10112 (set_attr "mode" "HI")])
10115 [(set (match_operand 0 "flags_reg_operand" "")
10116 (match_operator 2 "compare_operator"
10117 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10119 (set (match_operand:HI 1 "nonimmediate_operand" "")
10120 (not:HI (match_dup 3)))]
10121 "ix86_match_ccmode (insn, CCNOmode)"
10122 [(parallel [(set (match_dup 0)
10123 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10126 (xor:HI (match_dup 3) (const_int -1)))])]
10129 ;; %%% Potential partial reg stall on alternative 1. What to do?
10130 (define_expand "one_cmplqi2"
10131 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10132 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10133 "TARGET_QIMODE_MATH"
10134 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10136 (define_insn "*one_cmplqi2_1"
10137 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10138 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10139 "ix86_unary_operator_ok (NOT, QImode, operands)"
10143 [(set_attr "type" "negnot")
10144 (set_attr "mode" "QI,SI")])
10146 (define_insn "*one_cmplqi2_2"
10147 [(set (reg FLAGS_REG)
10148 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10150 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10151 (not:QI (match_dup 1)))]
10152 "ix86_match_ccmode (insn, CCNOmode)
10153 && ix86_unary_operator_ok (NOT, QImode, operands)"
10155 [(set_attr "type" "alu1")
10156 (set_attr "mode" "QI")])
10159 [(set (match_operand 0 "flags_reg_operand" "")
10160 (match_operator 2 "compare_operator"
10161 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10163 (set (match_operand:QI 1 "nonimmediate_operand" "")
10164 (not:QI (match_dup 3)))]
10165 "ix86_match_ccmode (insn, CCNOmode)"
10166 [(parallel [(set (match_dup 0)
10167 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10170 (xor:QI (match_dup 3) (const_int -1)))])]
10173 ;; Arithmetic shift instructions
10175 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10176 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10177 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10178 ;; from the assembler input.
10180 ;; This instruction shifts the target reg/mem as usual, but instead of
10181 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10182 ;; is a left shift double, bits are taken from the high order bits of
10183 ;; reg, else if the insn is a shift right double, bits are taken from the
10184 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10185 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10187 ;; Since sh[lr]d does not change the `reg' operand, that is done
10188 ;; separately, making all shifts emit pairs of shift double and normal
10189 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10190 ;; support a 63 bit shift, each shift where the count is in a reg expands
10191 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10193 ;; If the shift count is a constant, we need never emit more than one
10194 ;; shift pair, instead using moves and sign extension for counts greater
10197 (define_expand "ashlti3"
10198 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10199 (ashift:TI (match_operand:TI 1 "register_operand" "")
10200 (match_operand:QI 2 "nonmemory_operand" "")))
10201 (clobber (reg:CC FLAGS_REG))])]
10204 if (! immediate_operand (operands[2], QImode))
10206 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10209 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10213 (define_insn "ashlti3_1"
10214 [(set (match_operand:TI 0 "register_operand" "=r")
10215 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10216 (match_operand:QI 2 "register_operand" "c")))
10217 (clobber (match_scratch:DI 3 "=&r"))
10218 (clobber (reg:CC FLAGS_REG))]
10221 [(set_attr "type" "multi")])
10223 (define_insn "*ashlti3_2"
10224 [(set (match_operand:TI 0 "register_operand" "=r")
10225 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10226 (match_operand:QI 2 "immediate_operand" "O")))
10227 (clobber (reg:CC FLAGS_REG))]
10230 [(set_attr "type" "multi")])
10233 [(set (match_operand:TI 0 "register_operand" "")
10234 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10235 (match_operand:QI 2 "register_operand" "")))
10236 (clobber (match_scratch:DI 3 ""))
10237 (clobber (reg:CC FLAGS_REG))]
10238 "TARGET_64BIT && reload_completed"
10240 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10243 [(set (match_operand:TI 0 "register_operand" "")
10244 (ashift:TI (match_operand:TI 1 "register_operand" "")
10245 (match_operand:QI 2 "immediate_operand" "")))
10246 (clobber (reg:CC FLAGS_REG))]
10247 "TARGET_64BIT && reload_completed"
10249 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10251 (define_insn "x86_64_shld"
10252 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10253 (ior:DI (ashift:DI (match_dup 0)
10254 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10255 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10256 (minus:QI (const_int 64) (match_dup 2)))))
10257 (clobber (reg:CC FLAGS_REG))]
10260 shld{q}\t{%2, %1, %0|%0, %1, %2}
10261 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10262 [(set_attr "type" "ishift")
10263 (set_attr "prefix_0f" "1")
10264 (set_attr "mode" "DI")
10265 (set_attr "athlon_decode" "vector")])
10267 (define_expand "x86_64_shift_adj"
10268 [(set (reg:CCZ FLAGS_REG)
10269 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10272 (set (match_operand:DI 0 "register_operand" "")
10273 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10274 (match_operand:DI 1 "register_operand" "")
10277 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10278 (match_operand:DI 3 "register_operand" "r")
10283 (define_expand "ashldi3"
10284 [(set (match_operand:DI 0 "shiftdi_operand" "")
10285 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10286 (match_operand:QI 2 "nonmemory_operand" "")))]
10288 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10290 (define_insn "*ashldi3_1_rex64"
10291 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10292 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10293 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10294 (clobber (reg:CC FLAGS_REG))]
10295 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10297 switch (get_attr_type (insn))
10300 gcc_assert (operands[2] == const1_rtx);
10301 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10302 return "add{q}\t{%0, %0|%0, %0}";
10305 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10306 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10307 operands[1] = gen_rtx_MULT (DImode, operands[1],
10308 GEN_INT (1 << INTVAL (operands[2])));
10309 return "lea{q}\t{%a1, %0|%0, %a1}";
10312 if (REG_P (operands[2]))
10313 return "sal{q}\t{%b2, %0|%0, %b2}";
10314 else if (operands[2] == const1_rtx
10315 && (TARGET_SHIFT1 || optimize_size))
10316 return "sal{q}\t%0";
10318 return "sal{q}\t{%2, %0|%0, %2}";
10321 [(set (attr "type")
10322 (cond [(eq_attr "alternative" "1")
10323 (const_string "lea")
10324 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10326 (match_operand 0 "register_operand" ""))
10327 (match_operand 2 "const1_operand" ""))
10328 (const_string "alu")
10330 (const_string "ishift")))
10331 (set_attr "mode" "DI")])
10333 ;; Convert lea to the lea pattern to avoid flags dependency.
10335 [(set (match_operand:DI 0 "register_operand" "")
10336 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10337 (match_operand:QI 2 "immediate_operand" "")))
10338 (clobber (reg:CC FLAGS_REG))]
10339 "TARGET_64BIT && reload_completed
10340 && true_regnum (operands[0]) != true_regnum (operands[1])"
10341 [(set (match_dup 0)
10342 (mult:DI (match_dup 1)
10344 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10346 ;; This pattern can't accept a variable shift count, since shifts by
10347 ;; zero don't affect the flags. We assume that shifts by constant
10348 ;; zero are optimized away.
10349 (define_insn "*ashldi3_cmp_rex64"
10350 [(set (reg FLAGS_REG)
10352 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10353 (match_operand:QI 2 "immediate_operand" "e"))
10355 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10356 (ashift:DI (match_dup 1) (match_dup 2)))]
10357 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10358 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10360 switch (get_attr_type (insn))
10363 gcc_assert (operands[2] == const1_rtx);
10364 return "add{q}\t{%0, %0|%0, %0}";
10367 if (REG_P (operands[2]))
10368 return "sal{q}\t{%b2, %0|%0, %b2}";
10369 else if (operands[2] == const1_rtx
10370 && (TARGET_SHIFT1 || optimize_size))
10371 return "sal{q}\t%0";
10373 return "sal{q}\t{%2, %0|%0, %2}";
10376 [(set (attr "type")
10377 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10379 (match_operand 0 "register_operand" ""))
10380 (match_operand 2 "const1_operand" ""))
10381 (const_string "alu")
10383 (const_string "ishift")))
10384 (set_attr "mode" "DI")])
10386 (define_insn "*ashldi3_1"
10387 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10388 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10389 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10390 (clobber (reg:CC FLAGS_REG))]
10393 [(set_attr "type" "multi")])
10395 ;; By default we don't ask for a scratch register, because when DImode
10396 ;; values are manipulated, registers are already at a premium. But if
10397 ;; we have one handy, we won't turn it away.
10399 [(match_scratch:SI 3 "r")
10400 (parallel [(set (match_operand:DI 0 "register_operand" "")
10401 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10402 (match_operand:QI 2 "nonmemory_operand" "")))
10403 (clobber (reg:CC FLAGS_REG))])
10405 "!TARGET_64BIT && TARGET_CMOVE"
10407 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10410 [(set (match_operand:DI 0 "register_operand" "")
10411 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10412 (match_operand:QI 2 "nonmemory_operand" "")))
10413 (clobber (reg:CC FLAGS_REG))]
10414 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10415 ? flow2_completed : reload_completed)"
10417 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10419 (define_insn "x86_shld_1"
10420 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10421 (ior:SI (ashift:SI (match_dup 0)
10422 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10423 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10424 (minus:QI (const_int 32) (match_dup 2)))))
10425 (clobber (reg:CC FLAGS_REG))]
10428 shld{l}\t{%2, %1, %0|%0, %1, %2}
10429 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10430 [(set_attr "type" "ishift")
10431 (set_attr "prefix_0f" "1")
10432 (set_attr "mode" "SI")
10433 (set_attr "pent_pair" "np")
10434 (set_attr "athlon_decode" "vector")])
10436 (define_expand "x86_shift_adj_1"
10437 [(set (reg:CCZ FLAGS_REG)
10438 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10441 (set (match_operand:SI 0 "register_operand" "")
10442 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10443 (match_operand:SI 1 "register_operand" "")
10446 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10447 (match_operand:SI 3 "register_operand" "r")
10452 (define_expand "x86_shift_adj_2"
10453 [(use (match_operand:SI 0 "register_operand" ""))
10454 (use (match_operand:SI 1 "register_operand" ""))
10455 (use (match_operand:QI 2 "register_operand" ""))]
10458 rtx label = gen_label_rtx ();
10461 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10463 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10464 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10465 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10466 gen_rtx_LABEL_REF (VOIDmode, label),
10468 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10469 JUMP_LABEL (tmp) = label;
10471 emit_move_insn (operands[0], operands[1]);
10472 ix86_expand_clear (operands[1]);
10474 emit_label (label);
10475 LABEL_NUSES (label) = 1;
10480 (define_expand "ashlsi3"
10481 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10482 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10483 (match_operand:QI 2 "nonmemory_operand" "")))
10484 (clobber (reg:CC FLAGS_REG))]
10486 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10488 (define_insn "*ashlsi3_1"
10489 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10490 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10491 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10492 (clobber (reg:CC FLAGS_REG))]
10493 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10495 switch (get_attr_type (insn))
10498 gcc_assert (operands[2] == const1_rtx);
10499 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10500 return "add{l}\t{%0, %0|%0, %0}";
10506 if (REG_P (operands[2]))
10507 return "sal{l}\t{%b2, %0|%0, %b2}";
10508 else if (operands[2] == const1_rtx
10509 && (TARGET_SHIFT1 || optimize_size))
10510 return "sal{l}\t%0";
10512 return "sal{l}\t{%2, %0|%0, %2}";
10515 [(set (attr "type")
10516 (cond [(eq_attr "alternative" "1")
10517 (const_string "lea")
10518 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10520 (match_operand 0 "register_operand" ""))
10521 (match_operand 2 "const1_operand" ""))
10522 (const_string "alu")
10524 (const_string "ishift")))
10525 (set_attr "mode" "SI")])
10527 ;; Convert lea to the lea pattern to avoid flags dependency.
10529 [(set (match_operand 0 "register_operand" "")
10530 (ashift (match_operand 1 "index_register_operand" "")
10531 (match_operand:QI 2 "const_int_operand" "")))
10532 (clobber (reg:CC FLAGS_REG))]
10534 && true_regnum (operands[0]) != true_regnum (operands[1])
10535 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10539 enum machine_mode mode = GET_MODE (operands[0]);
10541 if (GET_MODE_SIZE (mode) < 4)
10542 operands[0] = gen_lowpart (SImode, operands[0]);
10544 operands[1] = gen_lowpart (Pmode, operands[1]);
10545 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10547 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10548 if (Pmode != SImode)
10549 pat = gen_rtx_SUBREG (SImode, pat, 0);
10550 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10554 ;; Rare case of shifting RSP is handled by generating move and shift
10556 [(set (match_operand 0 "register_operand" "")
10557 (ashift (match_operand 1 "register_operand" "")
10558 (match_operand:QI 2 "const_int_operand" "")))
10559 (clobber (reg:CC FLAGS_REG))]
10561 && true_regnum (operands[0]) != true_regnum (operands[1])"
10565 emit_move_insn (operands[1], operands[0]);
10566 pat = gen_rtx_SET (VOIDmode, operands[0],
10567 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10568 operands[0], operands[2]));
10569 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10570 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10574 (define_insn "*ashlsi3_1_zext"
10575 [(set (match_operand:DI 0 "register_operand" "=r,r")
10576 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10577 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10578 (clobber (reg:CC FLAGS_REG))]
10579 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10581 switch (get_attr_type (insn))
10584 gcc_assert (operands[2] == const1_rtx);
10585 return "add{l}\t{%k0, %k0|%k0, %k0}";
10591 if (REG_P (operands[2]))
10592 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10593 else if (operands[2] == const1_rtx
10594 && (TARGET_SHIFT1 || optimize_size))
10595 return "sal{l}\t%k0";
10597 return "sal{l}\t{%2, %k0|%k0, %2}";
10600 [(set (attr "type")
10601 (cond [(eq_attr "alternative" "1")
10602 (const_string "lea")
10603 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10605 (match_operand 2 "const1_operand" ""))
10606 (const_string "alu")
10608 (const_string "ishift")))
10609 (set_attr "mode" "SI")])
10611 ;; Convert lea to the lea pattern to avoid flags dependency.
10613 [(set (match_operand:DI 0 "register_operand" "")
10614 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10615 (match_operand:QI 2 "const_int_operand" ""))))
10616 (clobber (reg:CC FLAGS_REG))]
10617 "TARGET_64BIT && reload_completed
10618 && true_regnum (operands[0]) != true_regnum (operands[1])"
10619 [(set (match_dup 0) (zero_extend:DI
10620 (subreg:SI (mult:SI (match_dup 1)
10621 (match_dup 2)) 0)))]
10623 operands[1] = gen_lowpart (Pmode, operands[1]);
10624 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10627 ;; This pattern can't accept a variable shift count, since shifts by
10628 ;; zero don't affect the flags. We assume that shifts by constant
10629 ;; zero are optimized away.
10630 (define_insn "*ashlsi3_cmp"
10631 [(set (reg FLAGS_REG)
10633 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10634 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10636 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10637 (ashift:SI (match_dup 1) (match_dup 2)))]
10638 "ix86_match_ccmode (insn, CCGOCmode)
10639 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10641 switch (get_attr_type (insn))
10644 gcc_assert (operands[2] == const1_rtx);
10645 return "add{l}\t{%0, %0|%0, %0}";
10648 if (REG_P (operands[2]))
10649 return "sal{l}\t{%b2, %0|%0, %b2}";
10650 else if (operands[2] == const1_rtx
10651 && (TARGET_SHIFT1 || optimize_size))
10652 return "sal{l}\t%0";
10654 return "sal{l}\t{%2, %0|%0, %2}";
10657 [(set (attr "type")
10658 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10660 (match_operand 0 "register_operand" ""))
10661 (match_operand 2 "const1_operand" ""))
10662 (const_string "alu")
10664 (const_string "ishift")))
10665 (set_attr "mode" "SI")])
10667 (define_insn "*ashlsi3_cmp_zext"
10668 [(set (reg FLAGS_REG)
10670 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10671 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10673 (set (match_operand:DI 0 "register_operand" "=r")
10674 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10675 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10676 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10678 switch (get_attr_type (insn))
10681 gcc_assert (operands[2] == const1_rtx);
10682 return "add{l}\t{%k0, %k0|%k0, %k0}";
10685 if (REG_P (operands[2]))
10686 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10687 else if (operands[2] == const1_rtx
10688 && (TARGET_SHIFT1 || optimize_size))
10689 return "sal{l}\t%k0";
10691 return "sal{l}\t{%2, %k0|%k0, %2}";
10694 [(set (attr "type")
10695 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10697 (match_operand 2 "const1_operand" ""))
10698 (const_string "alu")
10700 (const_string "ishift")))
10701 (set_attr "mode" "SI")])
10703 (define_expand "ashlhi3"
10704 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10705 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10706 (match_operand:QI 2 "nonmemory_operand" "")))
10707 (clobber (reg:CC FLAGS_REG))]
10708 "TARGET_HIMODE_MATH"
10709 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10711 (define_insn "*ashlhi3_1_lea"
10712 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10713 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10714 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10715 (clobber (reg:CC FLAGS_REG))]
10716 "!TARGET_PARTIAL_REG_STALL
10717 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10719 switch (get_attr_type (insn))
10724 gcc_assert (operands[2] == const1_rtx);
10725 return "add{w}\t{%0, %0|%0, %0}";
10728 if (REG_P (operands[2]))
10729 return "sal{w}\t{%b2, %0|%0, %b2}";
10730 else if (operands[2] == const1_rtx
10731 && (TARGET_SHIFT1 || optimize_size))
10732 return "sal{w}\t%0";
10734 return "sal{w}\t{%2, %0|%0, %2}";
10737 [(set (attr "type")
10738 (cond [(eq_attr "alternative" "1")
10739 (const_string "lea")
10740 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10742 (match_operand 0 "register_operand" ""))
10743 (match_operand 2 "const1_operand" ""))
10744 (const_string "alu")
10746 (const_string "ishift")))
10747 (set_attr "mode" "HI,SI")])
10749 (define_insn "*ashlhi3_1"
10750 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10751 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10752 (match_operand:QI 2 "nonmemory_operand" "cI")))
10753 (clobber (reg:CC FLAGS_REG))]
10754 "TARGET_PARTIAL_REG_STALL
10755 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10757 switch (get_attr_type (insn))
10760 gcc_assert (operands[2] == const1_rtx);
10761 return "add{w}\t{%0, %0|%0, %0}";
10764 if (REG_P (operands[2]))
10765 return "sal{w}\t{%b2, %0|%0, %b2}";
10766 else if (operands[2] == const1_rtx
10767 && (TARGET_SHIFT1 || optimize_size))
10768 return "sal{w}\t%0";
10770 return "sal{w}\t{%2, %0|%0, %2}";
10773 [(set (attr "type")
10774 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10776 (match_operand 0 "register_operand" ""))
10777 (match_operand 2 "const1_operand" ""))
10778 (const_string "alu")
10780 (const_string "ishift")))
10781 (set_attr "mode" "HI")])
10783 ;; This pattern can't accept a variable shift count, since shifts by
10784 ;; zero don't affect the flags. We assume that shifts by constant
10785 ;; zero are optimized away.
10786 (define_insn "*ashlhi3_cmp"
10787 [(set (reg FLAGS_REG)
10789 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10790 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10792 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10793 (ashift:HI (match_dup 1) (match_dup 2)))]
10794 "ix86_match_ccmode (insn, CCGOCmode)
10795 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10797 switch (get_attr_type (insn))
10800 gcc_assert (operands[2] == const1_rtx);
10801 return "add{w}\t{%0, %0|%0, %0}";
10804 if (REG_P (operands[2]))
10805 return "sal{w}\t{%b2, %0|%0, %b2}";
10806 else if (operands[2] == const1_rtx
10807 && (TARGET_SHIFT1 || optimize_size))
10808 return "sal{w}\t%0";
10810 return "sal{w}\t{%2, %0|%0, %2}";
10813 [(set (attr "type")
10814 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10816 (match_operand 0 "register_operand" ""))
10817 (match_operand 2 "const1_operand" ""))
10818 (const_string "alu")
10820 (const_string "ishift")))
10821 (set_attr "mode" "HI")])
10823 (define_expand "ashlqi3"
10824 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10825 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10826 (match_operand:QI 2 "nonmemory_operand" "")))
10827 (clobber (reg:CC FLAGS_REG))]
10828 "TARGET_QIMODE_MATH"
10829 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10831 ;; %%% Potential partial reg stall on alternative 2. What to do?
10833 (define_insn "*ashlqi3_1_lea"
10834 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10835 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10836 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10837 (clobber (reg:CC FLAGS_REG))]
10838 "!TARGET_PARTIAL_REG_STALL
10839 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10841 switch (get_attr_type (insn))
10846 gcc_assert (operands[2] == const1_rtx);
10847 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10848 return "add{l}\t{%k0, %k0|%k0, %k0}";
10850 return "add{b}\t{%0, %0|%0, %0}";
10853 if (REG_P (operands[2]))
10855 if (get_attr_mode (insn) == MODE_SI)
10856 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10858 return "sal{b}\t{%b2, %0|%0, %b2}";
10860 else if (operands[2] == const1_rtx
10861 && (TARGET_SHIFT1 || optimize_size))
10863 if (get_attr_mode (insn) == MODE_SI)
10864 return "sal{l}\t%0";
10866 return "sal{b}\t%0";
10870 if (get_attr_mode (insn) == MODE_SI)
10871 return "sal{l}\t{%2, %k0|%k0, %2}";
10873 return "sal{b}\t{%2, %0|%0, %2}";
10877 [(set (attr "type")
10878 (cond [(eq_attr "alternative" "2")
10879 (const_string "lea")
10880 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10882 (match_operand 0 "register_operand" ""))
10883 (match_operand 2 "const1_operand" ""))
10884 (const_string "alu")
10886 (const_string "ishift")))
10887 (set_attr "mode" "QI,SI,SI")])
10889 (define_insn "*ashlqi3_1"
10890 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10891 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10892 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10893 (clobber (reg:CC FLAGS_REG))]
10894 "TARGET_PARTIAL_REG_STALL
10895 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10897 switch (get_attr_type (insn))
10900 gcc_assert (operands[2] == const1_rtx);
10901 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10902 return "add{l}\t{%k0, %k0|%k0, %k0}";
10904 return "add{b}\t{%0, %0|%0, %0}";
10907 if (REG_P (operands[2]))
10909 if (get_attr_mode (insn) == MODE_SI)
10910 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10912 return "sal{b}\t{%b2, %0|%0, %b2}";
10914 else if (operands[2] == const1_rtx
10915 && (TARGET_SHIFT1 || optimize_size))
10917 if (get_attr_mode (insn) == MODE_SI)
10918 return "sal{l}\t%0";
10920 return "sal{b}\t%0";
10924 if (get_attr_mode (insn) == MODE_SI)
10925 return "sal{l}\t{%2, %k0|%k0, %2}";
10927 return "sal{b}\t{%2, %0|%0, %2}";
10931 [(set (attr "type")
10932 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10934 (match_operand 0 "register_operand" ""))
10935 (match_operand 2 "const1_operand" ""))
10936 (const_string "alu")
10938 (const_string "ishift")))
10939 (set_attr "mode" "QI,SI")])
10941 ;; This pattern can't accept a variable shift count, since shifts by
10942 ;; zero don't affect the flags. We assume that shifts by constant
10943 ;; zero are optimized away.
10944 (define_insn "*ashlqi3_cmp"
10945 [(set (reg FLAGS_REG)
10947 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10950 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10951 (ashift:QI (match_dup 1) (match_dup 2)))]
10952 "ix86_match_ccmode (insn, CCGOCmode)
10953 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10955 switch (get_attr_type (insn))
10958 gcc_assert (operands[2] == const1_rtx);
10959 return "add{b}\t{%0, %0|%0, %0}";
10962 if (REG_P (operands[2]))
10963 return "sal{b}\t{%b2, %0|%0, %b2}";
10964 else if (operands[2] == const1_rtx
10965 && (TARGET_SHIFT1 || optimize_size))
10966 return "sal{b}\t%0";
10968 return "sal{b}\t{%2, %0|%0, %2}";
10971 [(set (attr "type")
10972 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10974 (match_operand 0 "register_operand" ""))
10975 (match_operand 2 "const1_operand" ""))
10976 (const_string "alu")
10978 (const_string "ishift")))
10979 (set_attr "mode" "QI")])
10981 ;; See comment above `ashldi3' about how this works.
10983 (define_expand "ashrti3"
10984 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10985 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10986 (match_operand:QI 2 "nonmemory_operand" "")))
10987 (clobber (reg:CC FLAGS_REG))])]
10990 if (! immediate_operand (operands[2], QImode))
10992 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
10995 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
10999 (define_insn "ashrti3_1"
11000 [(set (match_operand:TI 0 "register_operand" "=r")
11001 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11002 (match_operand:QI 2 "register_operand" "c")))
11003 (clobber (match_scratch:DI 3 "=&r"))
11004 (clobber (reg:CC FLAGS_REG))]
11007 [(set_attr "type" "multi")])
11009 (define_insn "*ashrti3_2"
11010 [(set (match_operand:TI 0 "register_operand" "=r")
11011 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11012 (match_operand:QI 2 "immediate_operand" "O")))
11013 (clobber (reg:CC FLAGS_REG))]
11016 [(set_attr "type" "multi")])
11019 [(set (match_operand:TI 0 "register_operand" "")
11020 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11021 (match_operand:QI 2 "register_operand" "")))
11022 (clobber (match_scratch:DI 3 ""))
11023 (clobber (reg:CC FLAGS_REG))]
11024 "TARGET_64BIT && reload_completed"
11026 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11029 [(set (match_operand:TI 0 "register_operand" "")
11030 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11031 (match_operand:QI 2 "immediate_operand" "")))
11032 (clobber (reg:CC FLAGS_REG))]
11033 "TARGET_64BIT && reload_completed"
11035 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11037 (define_insn "x86_64_shrd"
11038 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11039 (ior:DI (ashiftrt:DI (match_dup 0)
11040 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11041 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11042 (minus:QI (const_int 64) (match_dup 2)))))
11043 (clobber (reg:CC FLAGS_REG))]
11046 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11047 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11048 [(set_attr "type" "ishift")
11049 (set_attr "prefix_0f" "1")
11050 (set_attr "mode" "DI")
11051 (set_attr "athlon_decode" "vector")])
11053 (define_expand "ashrdi3"
11054 [(set (match_operand:DI 0 "shiftdi_operand" "")
11055 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11056 (match_operand:QI 2 "nonmemory_operand" "")))]
11058 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11060 (define_insn "*ashrdi3_63_rex64"
11061 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11062 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11063 (match_operand:DI 2 "const_int_operand" "i,i")))
11064 (clobber (reg:CC FLAGS_REG))]
11065 "TARGET_64BIT && INTVAL (operands[2]) == 63
11066 && (TARGET_USE_CLTD || optimize_size)
11067 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11070 sar{q}\t{%2, %0|%0, %2}"
11071 [(set_attr "type" "imovx,ishift")
11072 (set_attr "prefix_0f" "0,*")
11073 (set_attr "length_immediate" "0,*")
11074 (set_attr "modrm" "0,1")
11075 (set_attr "mode" "DI")])
11077 (define_insn "*ashrdi3_1_one_bit_rex64"
11078 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11079 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11080 (match_operand:QI 2 "const1_operand" "")))
11081 (clobber (reg:CC FLAGS_REG))]
11082 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11083 && (TARGET_SHIFT1 || optimize_size)"
11085 [(set_attr "type" "ishift")
11086 (set (attr "length")
11087 (if_then_else (match_operand:DI 0 "register_operand" "")
11089 (const_string "*")))])
11091 (define_insn "*ashrdi3_1_rex64"
11092 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11093 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11094 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11095 (clobber (reg:CC FLAGS_REG))]
11096 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11098 sar{q}\t{%2, %0|%0, %2}
11099 sar{q}\t{%b2, %0|%0, %b2}"
11100 [(set_attr "type" "ishift")
11101 (set_attr "mode" "DI")])
11103 ;; This pattern can't accept a variable shift count, since shifts by
11104 ;; zero don't affect the flags. We assume that shifts by constant
11105 ;; zero are optimized away.
11106 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11107 [(set (reg FLAGS_REG)
11109 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11110 (match_operand:QI 2 "const1_operand" ""))
11112 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11113 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11114 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11115 && (TARGET_SHIFT1 || optimize_size)
11116 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11118 [(set_attr "type" "ishift")
11119 (set (attr "length")
11120 (if_then_else (match_operand:DI 0 "register_operand" "")
11122 (const_string "*")))])
11124 ;; This pattern can't accept a variable shift count, since shifts by
11125 ;; zero don't affect the flags. We assume that shifts by constant
11126 ;; zero are optimized away.
11127 (define_insn "*ashrdi3_cmp_rex64"
11128 [(set (reg FLAGS_REG)
11130 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11131 (match_operand:QI 2 "const_int_operand" "n"))
11133 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11134 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11135 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11136 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11137 "sar{q}\t{%2, %0|%0, %2}"
11138 [(set_attr "type" "ishift")
11139 (set_attr "mode" "DI")])
11141 (define_insn "*ashrdi3_1"
11142 [(set (match_operand:DI 0 "register_operand" "=r")
11143 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11144 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11145 (clobber (reg:CC FLAGS_REG))]
11148 [(set_attr "type" "multi")])
11150 ;; By default we don't ask for a scratch register, because when DImode
11151 ;; values are manipulated, registers are already at a premium. But if
11152 ;; we have one handy, we won't turn it away.
11154 [(match_scratch:SI 3 "r")
11155 (parallel [(set (match_operand:DI 0 "register_operand" "")
11156 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11157 (match_operand:QI 2 "nonmemory_operand" "")))
11158 (clobber (reg:CC FLAGS_REG))])
11160 "!TARGET_64BIT && TARGET_CMOVE"
11162 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11165 [(set (match_operand:DI 0 "register_operand" "")
11166 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11167 (match_operand:QI 2 "nonmemory_operand" "")))
11168 (clobber (reg:CC FLAGS_REG))]
11169 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11170 ? flow2_completed : reload_completed)"
11172 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11174 (define_insn "x86_shrd_1"
11175 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11176 (ior:SI (ashiftrt:SI (match_dup 0)
11177 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11178 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11179 (minus:QI (const_int 32) (match_dup 2)))))
11180 (clobber (reg:CC FLAGS_REG))]
11183 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11184 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11185 [(set_attr "type" "ishift")
11186 (set_attr "prefix_0f" "1")
11187 (set_attr "pent_pair" "np")
11188 (set_attr "mode" "SI")])
11190 (define_expand "x86_shift_adj_3"
11191 [(use (match_operand:SI 0 "register_operand" ""))
11192 (use (match_operand:SI 1 "register_operand" ""))
11193 (use (match_operand:QI 2 "register_operand" ""))]
11196 rtx label = gen_label_rtx ();
11199 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11201 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11202 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11203 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11204 gen_rtx_LABEL_REF (VOIDmode, label),
11206 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11207 JUMP_LABEL (tmp) = label;
11209 emit_move_insn (operands[0], operands[1]);
11210 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11212 emit_label (label);
11213 LABEL_NUSES (label) = 1;
11218 (define_insn "ashrsi3_31"
11219 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11220 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11221 (match_operand:SI 2 "const_int_operand" "i,i")))
11222 (clobber (reg:CC FLAGS_REG))]
11223 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11224 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11227 sar{l}\t{%2, %0|%0, %2}"
11228 [(set_attr "type" "imovx,ishift")
11229 (set_attr "prefix_0f" "0,*")
11230 (set_attr "length_immediate" "0,*")
11231 (set_attr "modrm" "0,1")
11232 (set_attr "mode" "SI")])
11234 (define_insn "*ashrsi3_31_zext"
11235 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11236 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11237 (match_operand:SI 2 "const_int_operand" "i,i"))))
11238 (clobber (reg:CC FLAGS_REG))]
11239 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11240 && INTVAL (operands[2]) == 31
11241 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11244 sar{l}\t{%2, %k0|%k0, %2}"
11245 [(set_attr "type" "imovx,ishift")
11246 (set_attr "prefix_0f" "0,*")
11247 (set_attr "length_immediate" "0,*")
11248 (set_attr "modrm" "0,1")
11249 (set_attr "mode" "SI")])
11251 (define_expand "ashrsi3"
11252 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11253 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11254 (match_operand:QI 2 "nonmemory_operand" "")))
11255 (clobber (reg:CC FLAGS_REG))]
11257 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11259 (define_insn "*ashrsi3_1_one_bit"
11260 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11261 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11262 (match_operand:QI 2 "const1_operand" "")))
11263 (clobber (reg:CC FLAGS_REG))]
11264 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11265 && (TARGET_SHIFT1 || optimize_size)"
11267 [(set_attr "type" "ishift")
11268 (set (attr "length")
11269 (if_then_else (match_operand:SI 0 "register_operand" "")
11271 (const_string "*")))])
11273 (define_insn "*ashrsi3_1_one_bit_zext"
11274 [(set (match_operand:DI 0 "register_operand" "=r")
11275 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11276 (match_operand:QI 2 "const1_operand" ""))))
11277 (clobber (reg:CC FLAGS_REG))]
11278 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11279 && (TARGET_SHIFT1 || optimize_size)"
11281 [(set_attr "type" "ishift")
11282 (set_attr "length" "2")])
11284 (define_insn "*ashrsi3_1"
11285 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11286 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11287 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11288 (clobber (reg:CC FLAGS_REG))]
11289 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11291 sar{l}\t{%2, %0|%0, %2}
11292 sar{l}\t{%b2, %0|%0, %b2}"
11293 [(set_attr "type" "ishift")
11294 (set_attr "mode" "SI")])
11296 (define_insn "*ashrsi3_1_zext"
11297 [(set (match_operand:DI 0 "register_operand" "=r,r")
11298 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11299 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11300 (clobber (reg:CC FLAGS_REG))]
11301 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11303 sar{l}\t{%2, %k0|%k0, %2}
11304 sar{l}\t{%b2, %k0|%k0, %b2}"
11305 [(set_attr "type" "ishift")
11306 (set_attr "mode" "SI")])
11308 ;; This pattern can't accept a variable shift count, since shifts by
11309 ;; zero don't affect the flags. We assume that shifts by constant
11310 ;; zero are optimized away.
11311 (define_insn "*ashrsi3_one_bit_cmp"
11312 [(set (reg FLAGS_REG)
11314 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11315 (match_operand:QI 2 "const1_operand" ""))
11317 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11318 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11319 "ix86_match_ccmode (insn, CCGOCmode)
11320 && (TARGET_SHIFT1 || optimize_size)
11321 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11323 [(set_attr "type" "ishift")
11324 (set (attr "length")
11325 (if_then_else (match_operand:SI 0 "register_operand" "")
11327 (const_string "*")))])
11329 (define_insn "*ashrsi3_one_bit_cmp_zext"
11330 [(set (reg FLAGS_REG)
11332 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11333 (match_operand:QI 2 "const1_operand" ""))
11335 (set (match_operand:DI 0 "register_operand" "=r")
11336 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11337 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11338 && (TARGET_SHIFT1 || optimize_size)
11339 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11341 [(set_attr "type" "ishift")
11342 (set_attr "length" "2")])
11344 ;; This pattern can't accept a variable shift count, since shifts by
11345 ;; zero don't affect the flags. We assume that shifts by constant
11346 ;; zero are optimized away.
11347 (define_insn "*ashrsi3_cmp"
11348 [(set (reg FLAGS_REG)
11350 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11351 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11353 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11354 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11355 "ix86_match_ccmode (insn, CCGOCmode)
11356 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11357 "sar{l}\t{%2, %0|%0, %2}"
11358 [(set_attr "type" "ishift")
11359 (set_attr "mode" "SI")])
11361 (define_insn "*ashrsi3_cmp_zext"
11362 [(set (reg FLAGS_REG)
11364 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11365 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11367 (set (match_operand:DI 0 "register_operand" "=r")
11368 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11369 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11370 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11371 "sar{l}\t{%2, %k0|%k0, %2}"
11372 [(set_attr "type" "ishift")
11373 (set_attr "mode" "SI")])
11375 (define_expand "ashrhi3"
11376 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11377 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11378 (match_operand:QI 2 "nonmemory_operand" "")))
11379 (clobber (reg:CC FLAGS_REG))]
11380 "TARGET_HIMODE_MATH"
11381 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11383 (define_insn "*ashrhi3_1_one_bit"
11384 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11385 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11386 (match_operand:QI 2 "const1_operand" "")))
11387 (clobber (reg:CC FLAGS_REG))]
11388 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11389 && (TARGET_SHIFT1 || optimize_size)"
11391 [(set_attr "type" "ishift")
11392 (set (attr "length")
11393 (if_then_else (match_operand 0 "register_operand" "")
11395 (const_string "*")))])
11397 (define_insn "*ashrhi3_1"
11398 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11399 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11400 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11401 (clobber (reg:CC FLAGS_REG))]
11402 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11404 sar{w}\t{%2, %0|%0, %2}
11405 sar{w}\t{%b2, %0|%0, %b2}"
11406 [(set_attr "type" "ishift")
11407 (set_attr "mode" "HI")])
11409 ;; This pattern can't accept a variable shift count, since shifts by
11410 ;; zero don't affect the flags. We assume that shifts by constant
11411 ;; zero are optimized away.
11412 (define_insn "*ashrhi3_one_bit_cmp"
11413 [(set (reg FLAGS_REG)
11415 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11416 (match_operand:QI 2 "const1_operand" ""))
11418 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11419 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11420 "ix86_match_ccmode (insn, CCGOCmode)
11421 && (TARGET_SHIFT1 || optimize_size)
11422 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11424 [(set_attr "type" "ishift")
11425 (set (attr "length")
11426 (if_then_else (match_operand 0 "register_operand" "")
11428 (const_string "*")))])
11430 ;; This pattern can't accept a variable shift count, since shifts by
11431 ;; zero don't affect the flags. We assume that shifts by constant
11432 ;; zero are optimized away.
11433 (define_insn "*ashrhi3_cmp"
11434 [(set (reg FLAGS_REG)
11436 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11437 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11439 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11440 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11441 "ix86_match_ccmode (insn, CCGOCmode)
11442 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11443 "sar{w}\t{%2, %0|%0, %2}"
11444 [(set_attr "type" "ishift")
11445 (set_attr "mode" "HI")])
11447 (define_expand "ashrqi3"
11448 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11449 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11450 (match_operand:QI 2 "nonmemory_operand" "")))
11451 (clobber (reg:CC FLAGS_REG))]
11452 "TARGET_QIMODE_MATH"
11453 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11455 (define_insn "*ashrqi3_1_one_bit"
11456 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11457 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11458 (match_operand:QI 2 "const1_operand" "")))
11459 (clobber (reg:CC FLAGS_REG))]
11460 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11461 && (TARGET_SHIFT1 || optimize_size)"
11463 [(set_attr "type" "ishift")
11464 (set (attr "length")
11465 (if_then_else (match_operand 0 "register_operand" "")
11467 (const_string "*")))])
11469 (define_insn "*ashrqi3_1_one_bit_slp"
11470 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11471 (ashiftrt:QI (match_dup 0)
11472 (match_operand:QI 1 "const1_operand" "")))
11473 (clobber (reg:CC FLAGS_REG))]
11474 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11475 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11476 && (TARGET_SHIFT1 || optimize_size)"
11478 [(set_attr "type" "ishift1")
11479 (set (attr "length")
11480 (if_then_else (match_operand 0 "register_operand" "")
11482 (const_string "*")))])
11484 (define_insn "*ashrqi3_1"
11485 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11486 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11487 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11488 (clobber (reg:CC FLAGS_REG))]
11489 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11491 sar{b}\t{%2, %0|%0, %2}
11492 sar{b}\t{%b2, %0|%0, %b2}"
11493 [(set_attr "type" "ishift")
11494 (set_attr "mode" "QI")])
11496 (define_insn "*ashrqi3_1_slp"
11497 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11498 (ashiftrt:QI (match_dup 0)
11499 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11500 (clobber (reg:CC FLAGS_REG))]
11501 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11502 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11504 sar{b}\t{%1, %0|%0, %1}
11505 sar{b}\t{%b1, %0|%0, %b1}"
11506 [(set_attr "type" "ishift1")
11507 (set_attr "mode" "QI")])
11509 ;; This pattern can't accept a variable shift count, since shifts by
11510 ;; zero don't affect the flags. We assume that shifts by constant
11511 ;; zero are optimized away.
11512 (define_insn "*ashrqi3_one_bit_cmp"
11513 [(set (reg FLAGS_REG)
11515 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11516 (match_operand:QI 2 "const1_operand" "I"))
11518 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11519 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11520 "ix86_match_ccmode (insn, CCGOCmode)
11521 && (TARGET_SHIFT1 || optimize_size)
11522 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11524 [(set_attr "type" "ishift")
11525 (set (attr "length")
11526 (if_then_else (match_operand 0 "register_operand" "")
11528 (const_string "*")))])
11530 ;; This pattern can't accept a variable shift count, since shifts by
11531 ;; zero don't affect the flags. We assume that shifts by constant
11532 ;; zero are optimized away.
11533 (define_insn "*ashrqi3_cmp"
11534 [(set (reg FLAGS_REG)
11536 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11537 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11539 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11540 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11541 "ix86_match_ccmode (insn, CCGOCmode)
11542 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11543 "sar{b}\t{%2, %0|%0, %2}"
11544 [(set_attr "type" "ishift")
11545 (set_attr "mode" "QI")])
11547 ;; Logical shift instructions
11549 ;; See comment above `ashldi3' about how this works.
11551 (define_expand "lshrti3"
11552 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11553 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11554 (match_operand:QI 2 "nonmemory_operand" "")))
11555 (clobber (reg:CC FLAGS_REG))])]
11558 if (! immediate_operand (operands[2], QImode))
11560 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11563 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11567 (define_insn "lshrti3_1"
11568 [(set (match_operand:TI 0 "register_operand" "=r")
11569 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11570 (match_operand:QI 2 "register_operand" "c")))
11571 (clobber (match_scratch:DI 3 "=&r"))
11572 (clobber (reg:CC FLAGS_REG))]
11575 [(set_attr "type" "multi")])
11577 (define_insn "*lshrti3_2"
11578 [(set (match_operand:TI 0 "register_operand" "=r")
11579 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11580 (match_operand:QI 2 "immediate_operand" "O")))
11581 (clobber (reg:CC FLAGS_REG))]
11584 [(set_attr "type" "multi")])
11587 [(set (match_operand:TI 0 "register_operand" "")
11588 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11589 (match_operand:QI 2 "register_operand" "")))
11590 (clobber (match_scratch:DI 3 ""))
11591 (clobber (reg:CC FLAGS_REG))]
11592 "TARGET_64BIT && reload_completed"
11594 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11597 [(set (match_operand:TI 0 "register_operand" "")
11598 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11599 (match_operand:QI 2 "immediate_operand" "")))
11600 (clobber (reg:CC FLAGS_REG))]
11601 "TARGET_64BIT && reload_completed"
11603 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11605 (define_expand "lshrdi3"
11606 [(set (match_operand:DI 0 "shiftdi_operand" "")
11607 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11608 (match_operand:QI 2 "nonmemory_operand" "")))]
11610 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11612 (define_insn "*lshrdi3_1_one_bit_rex64"
11613 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11614 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11615 (match_operand:QI 2 "const1_operand" "")))
11616 (clobber (reg:CC FLAGS_REG))]
11617 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11618 && (TARGET_SHIFT1 || optimize_size)"
11620 [(set_attr "type" "ishift")
11621 (set (attr "length")
11622 (if_then_else (match_operand:DI 0 "register_operand" "")
11624 (const_string "*")))])
11626 (define_insn "*lshrdi3_1_rex64"
11627 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11628 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11629 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11630 (clobber (reg:CC FLAGS_REG))]
11631 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11633 shr{q}\t{%2, %0|%0, %2}
11634 shr{q}\t{%b2, %0|%0, %b2}"
11635 [(set_attr "type" "ishift")
11636 (set_attr "mode" "DI")])
11638 ;; This pattern can't accept a variable shift count, since shifts by
11639 ;; zero don't affect the flags. We assume that shifts by constant
11640 ;; zero are optimized away.
11641 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11642 [(set (reg FLAGS_REG)
11644 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11645 (match_operand:QI 2 "const1_operand" ""))
11647 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11648 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11649 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11650 && (TARGET_SHIFT1 || optimize_size)
11651 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11653 [(set_attr "type" "ishift")
11654 (set (attr "length")
11655 (if_then_else (match_operand:DI 0 "register_operand" "")
11657 (const_string "*")))])
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags. We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*lshrdi3_cmp_rex64"
11663 [(set (reg FLAGS_REG)
11665 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11666 (match_operand:QI 2 "const_int_operand" "e"))
11668 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11669 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11670 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11671 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11672 "shr{q}\t{%2, %0|%0, %2}"
11673 [(set_attr "type" "ishift")
11674 (set_attr "mode" "DI")])
11676 (define_insn "*lshrdi3_1"
11677 [(set (match_operand:DI 0 "register_operand" "=r")
11678 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11679 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11680 (clobber (reg:CC FLAGS_REG))]
11683 [(set_attr "type" "multi")])
11685 ;; By default we don't ask for a scratch register, because when DImode
11686 ;; values are manipulated, registers are already at a premium. But if
11687 ;; we have one handy, we won't turn it away.
11689 [(match_scratch:SI 3 "r")
11690 (parallel [(set (match_operand:DI 0 "register_operand" "")
11691 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11692 (match_operand:QI 2 "nonmemory_operand" "")))
11693 (clobber (reg:CC FLAGS_REG))])
11695 "!TARGET_64BIT && TARGET_CMOVE"
11697 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11700 [(set (match_operand:DI 0 "register_operand" "")
11701 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11702 (match_operand:QI 2 "nonmemory_operand" "")))
11703 (clobber (reg:CC FLAGS_REG))]
11704 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11705 ? flow2_completed : reload_completed)"
11707 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11709 (define_expand "lshrsi3"
11710 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11711 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11712 (match_operand:QI 2 "nonmemory_operand" "")))
11713 (clobber (reg:CC FLAGS_REG))]
11715 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11717 (define_insn "*lshrsi3_1_one_bit"
11718 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11719 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11720 (match_operand:QI 2 "const1_operand" "")))
11721 (clobber (reg:CC FLAGS_REG))]
11722 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11723 && (TARGET_SHIFT1 || optimize_size)"
11725 [(set_attr "type" "ishift")
11726 (set (attr "length")
11727 (if_then_else (match_operand:SI 0 "register_operand" "")
11729 (const_string "*")))])
11731 (define_insn "*lshrsi3_1_one_bit_zext"
11732 [(set (match_operand:DI 0 "register_operand" "=r")
11733 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11734 (match_operand:QI 2 "const1_operand" "")))
11735 (clobber (reg:CC FLAGS_REG))]
11736 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11737 && (TARGET_SHIFT1 || optimize_size)"
11739 [(set_attr "type" "ishift")
11740 (set_attr "length" "2")])
11742 (define_insn "*lshrsi3_1"
11743 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11744 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11745 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11746 (clobber (reg:CC FLAGS_REG))]
11747 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11749 shr{l}\t{%2, %0|%0, %2}
11750 shr{l}\t{%b2, %0|%0, %b2}"
11751 [(set_attr "type" "ishift")
11752 (set_attr "mode" "SI")])
11754 (define_insn "*lshrsi3_1_zext"
11755 [(set (match_operand:DI 0 "register_operand" "=r,r")
11757 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11758 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11759 (clobber (reg:CC FLAGS_REG))]
11760 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11762 shr{l}\t{%2, %k0|%k0, %2}
11763 shr{l}\t{%b2, %k0|%k0, %b2}"
11764 [(set_attr "type" "ishift")
11765 (set_attr "mode" "SI")])
11767 ;; This pattern can't accept a variable shift count, since shifts by
11768 ;; zero don't affect the flags. We assume that shifts by constant
11769 ;; zero are optimized away.
11770 (define_insn "*lshrsi3_one_bit_cmp"
11771 [(set (reg FLAGS_REG)
11773 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11774 (match_operand:QI 2 "const1_operand" ""))
11776 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11777 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11778 "ix86_match_ccmode (insn, CCGOCmode)
11779 && (TARGET_SHIFT1 || optimize_size)
11780 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11782 [(set_attr "type" "ishift")
11783 (set (attr "length")
11784 (if_then_else (match_operand:SI 0 "register_operand" "")
11786 (const_string "*")))])
11788 (define_insn "*lshrsi3_cmp_one_bit_zext"
11789 [(set (reg FLAGS_REG)
11791 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11792 (match_operand:QI 2 "const1_operand" ""))
11794 (set (match_operand:DI 0 "register_operand" "=r")
11795 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11796 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11797 && (TARGET_SHIFT1 || optimize_size)
11798 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11800 [(set_attr "type" "ishift")
11801 (set_attr "length" "2")])
11803 ;; This pattern can't accept a variable shift count, since shifts by
11804 ;; zero don't affect the flags. We assume that shifts by constant
11805 ;; zero are optimized away.
11806 (define_insn "*lshrsi3_cmp"
11807 [(set (reg FLAGS_REG)
11809 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11810 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11812 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11813 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11814 "ix86_match_ccmode (insn, CCGOCmode)
11815 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11816 "shr{l}\t{%2, %0|%0, %2}"
11817 [(set_attr "type" "ishift")
11818 (set_attr "mode" "SI")])
11820 (define_insn "*lshrsi3_cmp_zext"
11821 [(set (reg FLAGS_REG)
11823 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11824 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11826 (set (match_operand:DI 0 "register_operand" "=r")
11827 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11828 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11829 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11830 "shr{l}\t{%2, %k0|%k0, %2}"
11831 [(set_attr "type" "ishift")
11832 (set_attr "mode" "SI")])
11834 (define_expand "lshrhi3"
11835 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11836 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11837 (match_operand:QI 2 "nonmemory_operand" "")))
11838 (clobber (reg:CC FLAGS_REG))]
11839 "TARGET_HIMODE_MATH"
11840 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11842 (define_insn "*lshrhi3_1_one_bit"
11843 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11844 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11845 (match_operand:QI 2 "const1_operand" "")))
11846 (clobber (reg:CC FLAGS_REG))]
11847 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11848 && (TARGET_SHIFT1 || optimize_size)"
11850 [(set_attr "type" "ishift")
11851 (set (attr "length")
11852 (if_then_else (match_operand 0 "register_operand" "")
11854 (const_string "*")))])
11856 (define_insn "*lshrhi3_1"
11857 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11858 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11859 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11860 (clobber (reg:CC FLAGS_REG))]
11861 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11863 shr{w}\t{%2, %0|%0, %2}
11864 shr{w}\t{%b2, %0|%0, %b2}"
11865 [(set_attr "type" "ishift")
11866 (set_attr "mode" "HI")])
11868 ;; This pattern can't accept a variable shift count, since shifts by
11869 ;; zero don't affect the flags. We assume that shifts by constant
11870 ;; zero are optimized away.
11871 (define_insn "*lshrhi3_one_bit_cmp"
11872 [(set (reg FLAGS_REG)
11874 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11875 (match_operand:QI 2 "const1_operand" ""))
11877 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11878 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11879 "ix86_match_ccmode (insn, CCGOCmode)
11880 && (TARGET_SHIFT1 || optimize_size)
11881 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11883 [(set_attr "type" "ishift")
11884 (set (attr "length")
11885 (if_then_else (match_operand:SI 0 "register_operand" "")
11887 (const_string "*")))])
11889 ;; This pattern can't accept a variable shift count, since shifts by
11890 ;; zero don't affect the flags. We assume that shifts by constant
11891 ;; zero are optimized away.
11892 (define_insn "*lshrhi3_cmp"
11893 [(set (reg FLAGS_REG)
11895 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11896 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11898 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11899 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11900 "ix86_match_ccmode (insn, CCGOCmode)
11901 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11902 "shr{w}\t{%2, %0|%0, %2}"
11903 [(set_attr "type" "ishift")
11904 (set_attr "mode" "HI")])
11906 (define_expand "lshrqi3"
11907 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11908 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11909 (match_operand:QI 2 "nonmemory_operand" "")))
11910 (clobber (reg:CC FLAGS_REG))]
11911 "TARGET_QIMODE_MATH"
11912 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11914 (define_insn "*lshrqi3_1_one_bit"
11915 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11916 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11917 (match_operand:QI 2 "const1_operand" "")))
11918 (clobber (reg:CC FLAGS_REG))]
11919 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11920 && (TARGET_SHIFT1 || optimize_size)"
11922 [(set_attr "type" "ishift")
11923 (set (attr "length")
11924 (if_then_else (match_operand 0 "register_operand" "")
11926 (const_string "*")))])
11928 (define_insn "*lshrqi3_1_one_bit_slp"
11929 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11930 (lshiftrt:QI (match_dup 0)
11931 (match_operand:QI 1 "const1_operand" "")))
11932 (clobber (reg:CC FLAGS_REG))]
11933 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11934 && (TARGET_SHIFT1 || optimize_size)"
11936 [(set_attr "type" "ishift1")
11937 (set (attr "length")
11938 (if_then_else (match_operand 0 "register_operand" "")
11940 (const_string "*")))])
11942 (define_insn "*lshrqi3_1"
11943 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11944 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11945 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11946 (clobber (reg:CC FLAGS_REG))]
11947 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11949 shr{b}\t{%2, %0|%0, %2}
11950 shr{b}\t{%b2, %0|%0, %b2}"
11951 [(set_attr "type" "ishift")
11952 (set_attr "mode" "QI")])
11954 (define_insn "*lshrqi3_1_slp"
11955 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11956 (lshiftrt:QI (match_dup 0)
11957 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11958 (clobber (reg:CC FLAGS_REG))]
11959 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11960 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11962 shr{b}\t{%1, %0|%0, %1}
11963 shr{b}\t{%b1, %0|%0, %b1}"
11964 [(set_attr "type" "ishift1")
11965 (set_attr "mode" "QI")])
11967 ;; This pattern can't accept a variable shift count, since shifts by
11968 ;; zero don't affect the flags. We assume that shifts by constant
11969 ;; zero are optimized away.
11970 (define_insn "*lshrqi2_one_bit_cmp"
11971 [(set (reg FLAGS_REG)
11973 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11974 (match_operand:QI 2 "const1_operand" ""))
11976 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11977 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11978 "ix86_match_ccmode (insn, CCGOCmode)
11979 && (TARGET_SHIFT1 || optimize_size)
11980 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11982 [(set_attr "type" "ishift")
11983 (set (attr "length")
11984 (if_then_else (match_operand:SI 0 "register_operand" "")
11986 (const_string "*")))])
11988 ;; This pattern can't accept a variable shift count, since shifts by
11989 ;; zero don't affect the flags. We assume that shifts by constant
11990 ;; zero are optimized away.
11991 (define_insn "*lshrqi2_cmp"
11992 [(set (reg FLAGS_REG)
11994 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11995 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11997 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11998 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11999 "ix86_match_ccmode (insn, CCGOCmode)
12000 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12001 "shr{b}\t{%2, %0|%0, %2}"
12002 [(set_attr "type" "ishift")
12003 (set_attr "mode" "QI")])
12005 ;; Rotate instructions
12007 (define_expand "rotldi3"
12008 [(set (match_operand:DI 0 "shiftdi_operand" "")
12009 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12010 (match_operand:QI 2 "nonmemory_operand" "")))
12011 (clobber (reg:CC FLAGS_REG))]
12016 ix86_expand_binary_operator (ROTATE, DImode, operands);
12019 if (!const_1_to_31_operand (operands[2], VOIDmode))
12021 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12025 ;; Implement rotation using two double-precision shift instructions
12026 ;; and a scratch register.
12027 (define_insn_and_split "ix86_rotldi3"
12028 [(set (match_operand:DI 0 "register_operand" "=r")
12029 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12030 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12031 (clobber (reg:CC FLAGS_REG))
12032 (clobber (match_scratch:SI 3 "=&r"))]
12035 "&& reload_completed"
12036 [(set (match_dup 3) (match_dup 4))
12038 [(set (match_dup 4)
12039 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12040 (lshiftrt:SI (match_dup 5)
12041 (minus:QI (const_int 32) (match_dup 2)))))
12042 (clobber (reg:CC FLAGS_REG))])
12044 [(set (match_dup 5)
12045 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12046 (lshiftrt:SI (match_dup 3)
12047 (minus:QI (const_int 32) (match_dup 2)))))
12048 (clobber (reg:CC FLAGS_REG))])]
12049 "split_di (operands, 1, operands + 4, operands + 5);")
12051 (define_insn "*rotlsi3_1_one_bit_rex64"
12052 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12053 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12054 (match_operand:QI 2 "const1_operand" "")))
12055 (clobber (reg:CC FLAGS_REG))]
12056 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12057 && (TARGET_SHIFT1 || optimize_size)"
12059 [(set_attr "type" "rotate")
12060 (set (attr "length")
12061 (if_then_else (match_operand:DI 0 "register_operand" "")
12063 (const_string "*")))])
12065 (define_insn "*rotldi3_1_rex64"
12066 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12067 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12068 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12069 (clobber (reg:CC FLAGS_REG))]
12070 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12072 rol{q}\t{%2, %0|%0, %2}
12073 rol{q}\t{%b2, %0|%0, %b2}"
12074 [(set_attr "type" "rotate")
12075 (set_attr "mode" "DI")])
12077 (define_expand "rotlsi3"
12078 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12079 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12080 (match_operand:QI 2 "nonmemory_operand" "")))
12081 (clobber (reg:CC FLAGS_REG))]
12083 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12085 (define_insn "*rotlsi3_1_one_bit"
12086 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12087 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12088 (match_operand:QI 2 "const1_operand" "")))
12089 (clobber (reg:CC FLAGS_REG))]
12090 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12091 && (TARGET_SHIFT1 || optimize_size)"
12093 [(set_attr "type" "rotate")
12094 (set (attr "length")
12095 (if_then_else (match_operand:SI 0 "register_operand" "")
12097 (const_string "*")))])
12099 (define_insn "*rotlsi3_1_one_bit_zext"
12100 [(set (match_operand:DI 0 "register_operand" "=r")
12102 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12103 (match_operand:QI 2 "const1_operand" ""))))
12104 (clobber (reg:CC FLAGS_REG))]
12105 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12106 && (TARGET_SHIFT1 || optimize_size)"
12108 [(set_attr "type" "rotate")
12109 (set_attr "length" "2")])
12111 (define_insn "*rotlsi3_1"
12112 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12113 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12114 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12115 (clobber (reg:CC FLAGS_REG))]
12116 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12118 rol{l}\t{%2, %0|%0, %2}
12119 rol{l}\t{%b2, %0|%0, %b2}"
12120 [(set_attr "type" "rotate")
12121 (set_attr "mode" "SI")])
12123 (define_insn "*rotlsi3_1_zext"
12124 [(set (match_operand:DI 0 "register_operand" "=r,r")
12126 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12127 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12128 (clobber (reg:CC FLAGS_REG))]
12129 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12131 rol{l}\t{%2, %k0|%k0, %2}
12132 rol{l}\t{%b2, %k0|%k0, %b2}"
12133 [(set_attr "type" "rotate")
12134 (set_attr "mode" "SI")])
12136 (define_expand "rotlhi3"
12137 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12138 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12139 (match_operand:QI 2 "nonmemory_operand" "")))
12140 (clobber (reg:CC FLAGS_REG))]
12141 "TARGET_HIMODE_MATH"
12142 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12144 (define_insn "*rotlhi3_1_one_bit"
12145 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12146 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12147 (match_operand:QI 2 "const1_operand" "")))
12148 (clobber (reg:CC FLAGS_REG))]
12149 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12150 && (TARGET_SHIFT1 || optimize_size)"
12152 [(set_attr "type" "rotate")
12153 (set (attr "length")
12154 (if_then_else (match_operand 0 "register_operand" "")
12156 (const_string "*")))])
12158 (define_insn "*rotlhi3_1"
12159 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12160 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12161 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12162 (clobber (reg:CC FLAGS_REG))]
12163 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12165 rol{w}\t{%2, %0|%0, %2}
12166 rol{w}\t{%b2, %0|%0, %b2}"
12167 [(set_attr "type" "rotate")
12168 (set_attr "mode" "HI")])
12170 (define_expand "rotlqi3"
12171 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12172 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12173 (match_operand:QI 2 "nonmemory_operand" "")))
12174 (clobber (reg:CC FLAGS_REG))]
12175 "TARGET_QIMODE_MATH"
12176 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12178 (define_insn "*rotlqi3_1_one_bit_slp"
12179 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12180 (rotate:QI (match_dup 0)
12181 (match_operand:QI 1 "const1_operand" "")))
12182 (clobber (reg:CC FLAGS_REG))]
12183 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12184 && (TARGET_SHIFT1 || optimize_size)"
12186 [(set_attr "type" "rotate1")
12187 (set (attr "length")
12188 (if_then_else (match_operand 0 "register_operand" "")
12190 (const_string "*")))])
12192 (define_insn "*rotlqi3_1_one_bit"
12193 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12194 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12195 (match_operand:QI 2 "const1_operand" "")))
12196 (clobber (reg:CC FLAGS_REG))]
12197 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12198 && (TARGET_SHIFT1 || optimize_size)"
12200 [(set_attr "type" "rotate")
12201 (set (attr "length")
12202 (if_then_else (match_operand 0 "register_operand" "")
12204 (const_string "*")))])
12206 (define_insn "*rotlqi3_1_slp"
12207 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12208 (rotate:QI (match_dup 0)
12209 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12210 (clobber (reg:CC FLAGS_REG))]
12211 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12212 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12214 rol{b}\t{%1, %0|%0, %1}
12215 rol{b}\t{%b1, %0|%0, %b1}"
12216 [(set_attr "type" "rotate1")
12217 (set_attr "mode" "QI")])
12219 (define_insn "*rotlqi3_1"
12220 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12221 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12222 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12223 (clobber (reg:CC FLAGS_REG))]
12224 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12226 rol{b}\t{%2, %0|%0, %2}
12227 rol{b}\t{%b2, %0|%0, %b2}"
12228 [(set_attr "type" "rotate")
12229 (set_attr "mode" "QI")])
12231 (define_expand "rotrdi3"
12232 [(set (match_operand:DI 0 "shiftdi_operand" "")
12233 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12234 (match_operand:QI 2 "nonmemory_operand" "")))
12235 (clobber (reg:CC FLAGS_REG))]
12240 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12243 if (!const_1_to_31_operand (operands[2], VOIDmode))
12245 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12249 ;; Implement rotation using two double-precision shift instructions
12250 ;; and a scratch register.
12251 (define_insn_and_split "ix86_rotrdi3"
12252 [(set (match_operand:DI 0 "register_operand" "=r")
12253 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12254 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12255 (clobber (reg:CC FLAGS_REG))
12256 (clobber (match_scratch:SI 3 "=&r"))]
12259 "&& reload_completed"
12260 [(set (match_dup 3) (match_dup 4))
12262 [(set (match_dup 4)
12263 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12264 (ashift:SI (match_dup 5)
12265 (minus:QI (const_int 32) (match_dup 2)))))
12266 (clobber (reg:CC FLAGS_REG))])
12268 [(set (match_dup 5)
12269 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12270 (ashift:SI (match_dup 3)
12271 (minus:QI (const_int 32) (match_dup 2)))))
12272 (clobber (reg:CC FLAGS_REG))])]
12273 "split_di (operands, 1, operands + 4, operands + 5);")
12275 (define_insn "*rotrdi3_1_one_bit_rex64"
12276 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12277 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12278 (match_operand:QI 2 "const1_operand" "")))
12279 (clobber (reg:CC FLAGS_REG))]
12280 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12281 && (TARGET_SHIFT1 || optimize_size)"
12283 [(set_attr "type" "rotate")
12284 (set (attr "length")
12285 (if_then_else (match_operand:DI 0 "register_operand" "")
12287 (const_string "*")))])
12289 (define_insn "*rotrdi3_1_rex64"
12290 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12291 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12292 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12293 (clobber (reg:CC FLAGS_REG))]
12294 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12296 ror{q}\t{%2, %0|%0, %2}
12297 ror{q}\t{%b2, %0|%0, %b2}"
12298 [(set_attr "type" "rotate")
12299 (set_attr "mode" "DI")])
12301 (define_expand "rotrsi3"
12302 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12303 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12304 (match_operand:QI 2 "nonmemory_operand" "")))
12305 (clobber (reg:CC FLAGS_REG))]
12307 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12309 (define_insn "*rotrsi3_1_one_bit"
12310 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12311 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12312 (match_operand:QI 2 "const1_operand" "")))
12313 (clobber (reg:CC FLAGS_REG))]
12314 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12315 && (TARGET_SHIFT1 || optimize_size)"
12317 [(set_attr "type" "rotate")
12318 (set (attr "length")
12319 (if_then_else (match_operand:SI 0 "register_operand" "")
12321 (const_string "*")))])
12323 (define_insn "*rotrsi3_1_one_bit_zext"
12324 [(set (match_operand:DI 0 "register_operand" "=r")
12326 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12327 (match_operand:QI 2 "const1_operand" ""))))
12328 (clobber (reg:CC FLAGS_REG))]
12329 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12330 && (TARGET_SHIFT1 || optimize_size)"
12332 [(set_attr "type" "rotate")
12333 (set (attr "length")
12334 (if_then_else (match_operand:SI 0 "register_operand" "")
12336 (const_string "*")))])
12338 (define_insn "*rotrsi3_1"
12339 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12340 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12341 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12342 (clobber (reg:CC FLAGS_REG))]
12343 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12345 ror{l}\t{%2, %0|%0, %2}
12346 ror{l}\t{%b2, %0|%0, %b2}"
12347 [(set_attr "type" "rotate")
12348 (set_attr "mode" "SI")])
12350 (define_insn "*rotrsi3_1_zext"
12351 [(set (match_operand:DI 0 "register_operand" "=r,r")
12353 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12354 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12355 (clobber (reg:CC FLAGS_REG))]
12356 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12358 ror{l}\t{%2, %k0|%k0, %2}
12359 ror{l}\t{%b2, %k0|%k0, %b2}"
12360 [(set_attr "type" "rotate")
12361 (set_attr "mode" "SI")])
12363 (define_expand "rotrhi3"
12364 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12365 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12366 (match_operand:QI 2 "nonmemory_operand" "")))
12367 (clobber (reg:CC FLAGS_REG))]
12368 "TARGET_HIMODE_MATH"
12369 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12371 (define_insn "*rotrhi3_one_bit"
12372 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12373 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12374 (match_operand:QI 2 "const1_operand" "")))
12375 (clobber (reg:CC FLAGS_REG))]
12376 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12377 && (TARGET_SHIFT1 || optimize_size)"
12379 [(set_attr "type" "rotate")
12380 (set (attr "length")
12381 (if_then_else (match_operand 0 "register_operand" "")
12383 (const_string "*")))])
12385 (define_insn "*rotrhi3"
12386 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12387 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12388 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12389 (clobber (reg:CC FLAGS_REG))]
12390 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12392 ror{w}\t{%2, %0|%0, %2}
12393 ror{w}\t{%b2, %0|%0, %b2}"
12394 [(set_attr "type" "rotate")
12395 (set_attr "mode" "HI")])
12397 (define_expand "rotrqi3"
12398 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12399 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12400 (match_operand:QI 2 "nonmemory_operand" "")))
12401 (clobber (reg:CC FLAGS_REG))]
12402 "TARGET_QIMODE_MATH"
12403 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12405 (define_insn "*rotrqi3_1_one_bit"
12406 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12407 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12408 (match_operand:QI 2 "const1_operand" "")))
12409 (clobber (reg:CC FLAGS_REG))]
12410 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12411 && (TARGET_SHIFT1 || optimize_size)"
12413 [(set_attr "type" "rotate")
12414 (set (attr "length")
12415 (if_then_else (match_operand 0 "register_operand" "")
12417 (const_string "*")))])
12419 (define_insn "*rotrqi3_1_one_bit_slp"
12420 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12421 (rotatert:QI (match_dup 0)
12422 (match_operand:QI 1 "const1_operand" "")))
12423 (clobber (reg:CC FLAGS_REG))]
12424 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12425 && (TARGET_SHIFT1 || optimize_size)"
12427 [(set_attr "type" "rotate1")
12428 (set (attr "length")
12429 (if_then_else (match_operand 0 "register_operand" "")
12431 (const_string "*")))])
12433 (define_insn "*rotrqi3_1"
12434 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12435 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12436 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12437 (clobber (reg:CC FLAGS_REG))]
12438 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12440 ror{b}\t{%2, %0|%0, %2}
12441 ror{b}\t{%b2, %0|%0, %b2}"
12442 [(set_attr "type" "rotate")
12443 (set_attr "mode" "QI")])
12445 (define_insn "*rotrqi3_1_slp"
12446 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12447 (rotatert:QI (match_dup 0)
12448 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12449 (clobber (reg:CC FLAGS_REG))]
12450 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12451 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12453 ror{b}\t{%1, %0|%0, %1}
12454 ror{b}\t{%b1, %0|%0, %b1}"
12455 [(set_attr "type" "rotate1")
12456 (set_attr "mode" "QI")])
12458 ;; Bit set / bit test instructions
12460 (define_expand "extv"
12461 [(set (match_operand:SI 0 "register_operand" "")
12462 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12463 (match_operand:SI 2 "immediate_operand" "")
12464 (match_operand:SI 3 "immediate_operand" "")))]
12467 /* Handle extractions from %ah et al. */
12468 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12471 /* From mips.md: extract_bit_field doesn't verify that our source
12472 matches the predicate, so check it again here. */
12473 if (! ext_register_operand (operands[1], VOIDmode))
12477 (define_expand "extzv"
12478 [(set (match_operand:SI 0 "register_operand" "")
12479 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12480 (match_operand:SI 2 "immediate_operand" "")
12481 (match_operand:SI 3 "immediate_operand" "")))]
12484 /* Handle extractions from %ah et al. */
12485 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12488 /* From mips.md: extract_bit_field doesn't verify that our source
12489 matches the predicate, so check it again here. */
12490 if (! ext_register_operand (operands[1], VOIDmode))
12494 (define_expand "insv"
12495 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12496 (match_operand 1 "immediate_operand" "")
12497 (match_operand 2 "immediate_operand" ""))
12498 (match_operand 3 "register_operand" ""))]
12501 /* Handle extractions from %ah et al. */
12502 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12505 /* From mips.md: insert_bit_field doesn't verify that our source
12506 matches the predicate, so check it again here. */
12507 if (! ext_register_operand (operands[0], VOIDmode))
12511 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12513 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12518 ;; %%% bts, btr, btc, bt.
12519 ;; In general these instructions are *slow* when applied to memory,
12520 ;; since they enforce atomic operation. When applied to registers,
12521 ;; it depends on the cpu implementation. They're never faster than
12522 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12523 ;; no point. But in 64-bit, we can't hold the relevant immediates
12524 ;; within the instruction itself, so operating on bits in the high
12525 ;; 32-bits of a register becomes easier.
12527 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12528 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12529 ;; negdf respectively, so they can never be disabled entirely.
12531 (define_insn "*btsq"
12532 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12534 (match_operand:DI 1 "const_0_to_63_operand" ""))
12536 (clobber (reg:CC FLAGS_REG))]
12537 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12539 [(set_attr "type" "alu1")])
12541 (define_insn "*btrq"
12542 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12544 (match_operand:DI 1 "const_0_to_63_operand" ""))
12546 (clobber (reg:CC FLAGS_REG))]
12547 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12549 [(set_attr "type" "alu1")])
12551 (define_insn "*btcq"
12552 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12554 (match_operand:DI 1 "const_0_to_63_operand" ""))
12555 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12556 (clobber (reg:CC FLAGS_REG))]
12557 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12559 [(set_attr "type" "alu1")])
12561 ;; Allow Nocona to avoid these instructions if a register is available.
12564 [(match_scratch:DI 2 "r")
12565 (parallel [(set (zero_extract:DI
12566 (match_operand:DI 0 "register_operand" "")
12568 (match_operand:DI 1 "const_0_to_63_operand" ""))
12570 (clobber (reg:CC FLAGS_REG))])]
12571 "TARGET_64BIT && !TARGET_USE_BT"
12574 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12577 if (HOST_BITS_PER_WIDE_INT >= 64)
12578 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12579 else if (i < HOST_BITS_PER_WIDE_INT)
12580 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12582 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12584 op1 = immed_double_const (lo, hi, DImode);
12587 emit_move_insn (operands[2], op1);
12591 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12596 [(match_scratch:DI 2 "r")
12597 (parallel [(set (zero_extract:DI
12598 (match_operand:DI 0 "register_operand" "")
12600 (match_operand:DI 1 "const_0_to_63_operand" ""))
12602 (clobber (reg:CC FLAGS_REG))])]
12603 "TARGET_64BIT && !TARGET_USE_BT"
12606 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12609 if (HOST_BITS_PER_WIDE_INT >= 64)
12610 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12611 else if (i < HOST_BITS_PER_WIDE_INT)
12612 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12614 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12616 op1 = immed_double_const (~lo, ~hi, DImode);
12619 emit_move_insn (operands[2], op1);
12623 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12628 [(match_scratch:DI 2 "r")
12629 (parallel [(set (zero_extract:DI
12630 (match_operand:DI 0 "register_operand" "")
12632 (match_operand:DI 1 "const_0_to_63_operand" ""))
12633 (not:DI (zero_extract:DI
12634 (match_dup 0) (const_int 1) (match_dup 1))))
12635 (clobber (reg:CC FLAGS_REG))])]
12636 "TARGET_64BIT && !TARGET_USE_BT"
12639 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12642 if (HOST_BITS_PER_WIDE_INT >= 64)
12643 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12644 else if (i < HOST_BITS_PER_WIDE_INT)
12645 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12647 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12649 op1 = immed_double_const (lo, hi, DImode);
12652 emit_move_insn (operands[2], op1);
12656 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12660 ;; Store-flag instructions.
12662 ;; For all sCOND expanders, also expand the compare or test insn that
12663 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12665 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12666 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12667 ;; way, which can later delete the movzx if only QImode is needed.
12669 (define_expand "seq"
12670 [(set (match_operand:QI 0 "register_operand" "")
12671 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12673 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12675 (define_expand "sne"
12676 [(set (match_operand:QI 0 "register_operand" "")
12677 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12679 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12681 (define_expand "sgt"
12682 [(set (match_operand:QI 0 "register_operand" "")
12683 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12685 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12687 (define_expand "sgtu"
12688 [(set (match_operand:QI 0 "register_operand" "")
12689 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12691 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12693 (define_expand "slt"
12694 [(set (match_operand:QI 0 "register_operand" "")
12695 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12697 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12699 (define_expand "sltu"
12700 [(set (match_operand:QI 0 "register_operand" "")
12701 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12703 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12705 (define_expand "sge"
12706 [(set (match_operand:QI 0 "register_operand" "")
12707 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12709 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12711 (define_expand "sgeu"
12712 [(set (match_operand:QI 0 "register_operand" "")
12713 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12715 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12717 (define_expand "sle"
12718 [(set (match_operand:QI 0 "register_operand" "")
12719 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12721 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12723 (define_expand "sleu"
12724 [(set (match_operand:QI 0 "register_operand" "")
12725 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12727 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12729 (define_expand "sunordered"
12730 [(set (match_operand:QI 0 "register_operand" "")
12731 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12732 "TARGET_80387 || TARGET_SSE"
12733 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12735 (define_expand "sordered"
12736 [(set (match_operand:QI 0 "register_operand" "")
12737 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12739 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12741 (define_expand "suneq"
12742 [(set (match_operand:QI 0 "register_operand" "")
12743 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12744 "TARGET_80387 || TARGET_SSE"
12745 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12747 (define_expand "sunge"
12748 [(set (match_operand:QI 0 "register_operand" "")
12749 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750 "TARGET_80387 || TARGET_SSE"
12751 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12753 (define_expand "sungt"
12754 [(set (match_operand:QI 0 "register_operand" "")
12755 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756 "TARGET_80387 || TARGET_SSE"
12757 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12759 (define_expand "sunle"
12760 [(set (match_operand:QI 0 "register_operand" "")
12761 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762 "TARGET_80387 || TARGET_SSE"
12763 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12765 (define_expand "sunlt"
12766 [(set (match_operand:QI 0 "register_operand" "")
12767 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768 "TARGET_80387 || TARGET_SSE"
12769 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12771 (define_expand "sltgt"
12772 [(set (match_operand:QI 0 "register_operand" "")
12773 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774 "TARGET_80387 || TARGET_SSE"
12775 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12777 (define_insn "*setcc_1"
12778 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12779 (match_operator:QI 1 "ix86_comparison_operator"
12780 [(reg FLAGS_REG) (const_int 0)]))]
12783 [(set_attr "type" "setcc")
12784 (set_attr "mode" "QI")])
12786 (define_insn "*setcc_2"
12787 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12788 (match_operator:QI 1 "ix86_comparison_operator"
12789 [(reg FLAGS_REG) (const_int 0)]))]
12792 [(set_attr "type" "setcc")
12793 (set_attr "mode" "QI")])
12795 ;; In general it is not safe to assume too much about CCmode registers,
12796 ;; so simplify-rtx stops when it sees a second one. Under certain
12797 ;; conditions this is safe on x86, so help combine not create
12804 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12805 (ne:QI (match_operator 1 "ix86_comparison_operator"
12806 [(reg FLAGS_REG) (const_int 0)])
12809 [(set (match_dup 0) (match_dup 1))]
12811 PUT_MODE (operands[1], QImode);
12815 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12816 (ne:QI (match_operator 1 "ix86_comparison_operator"
12817 [(reg FLAGS_REG) (const_int 0)])
12820 [(set (match_dup 0) (match_dup 1))]
12822 PUT_MODE (operands[1], QImode);
12826 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12827 (eq:QI (match_operator 1 "ix86_comparison_operator"
12828 [(reg FLAGS_REG) (const_int 0)])
12831 [(set (match_dup 0) (match_dup 1))]
12833 rtx new_op1 = copy_rtx (operands[1]);
12834 operands[1] = new_op1;
12835 PUT_MODE (new_op1, QImode);
12836 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12837 GET_MODE (XEXP (new_op1, 0))));
12839 /* Make sure that (a) the CCmode we have for the flags is strong
12840 enough for the reversed compare or (b) we have a valid FP compare. */
12841 if (! ix86_comparison_operator (new_op1, VOIDmode))
12846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12847 (eq:QI (match_operator 1 "ix86_comparison_operator"
12848 [(reg FLAGS_REG) (const_int 0)])
12851 [(set (match_dup 0) (match_dup 1))]
12853 rtx new_op1 = copy_rtx (operands[1]);
12854 operands[1] = new_op1;
12855 PUT_MODE (new_op1, QImode);
12856 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12857 GET_MODE (XEXP (new_op1, 0))));
12859 /* Make sure that (a) the CCmode we have for the flags is strong
12860 enough for the reversed compare or (b) we have a valid FP compare. */
12861 if (! ix86_comparison_operator (new_op1, VOIDmode))
12865 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12866 ;; subsequent logical operations are used to imitate conditional moves.
12867 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12870 (define_insn "*sse_setccsf"
12871 [(set (match_operand:SF 0 "register_operand" "=x")
12872 (match_operator:SF 1 "sse_comparison_operator"
12873 [(match_operand:SF 2 "register_operand" "0")
12874 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12876 "cmp%D1ss\t{%3, %0|%0, %3}"
12877 [(set_attr "type" "ssecmp")
12878 (set_attr "mode" "SF")])
12880 (define_insn "*sse_setccdf"
12881 [(set (match_operand:DF 0 "register_operand" "=Y")
12882 (match_operator:DF 1 "sse_comparison_operator"
12883 [(match_operand:DF 2 "register_operand" "0")
12884 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12886 "cmp%D1sd\t{%3, %0|%0, %3}"
12887 [(set_attr "type" "ssecmp")
12888 (set_attr "mode" "DF")])
12890 ;; Basic conditional jump instructions.
12891 ;; We ignore the overflow flag for signed branch instructions.
12893 ;; For all bCOND expanders, also expand the compare or test insn that
12894 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12896 (define_expand "beq"
12898 (if_then_else (match_dup 1)
12899 (label_ref (match_operand 0 "" ""))
12902 "ix86_expand_branch (EQ, operands[0]); DONE;")
12904 (define_expand "bne"
12906 (if_then_else (match_dup 1)
12907 (label_ref (match_operand 0 "" ""))
12910 "ix86_expand_branch (NE, operands[0]); DONE;")
12912 (define_expand "bgt"
12914 (if_then_else (match_dup 1)
12915 (label_ref (match_operand 0 "" ""))
12918 "ix86_expand_branch (GT, operands[0]); DONE;")
12920 (define_expand "bgtu"
12922 (if_then_else (match_dup 1)
12923 (label_ref (match_operand 0 "" ""))
12926 "ix86_expand_branch (GTU, operands[0]); DONE;")
12928 (define_expand "blt"
12930 (if_then_else (match_dup 1)
12931 (label_ref (match_operand 0 "" ""))
12934 "ix86_expand_branch (LT, operands[0]); DONE;")
12936 (define_expand "bltu"
12938 (if_then_else (match_dup 1)
12939 (label_ref (match_operand 0 "" ""))
12942 "ix86_expand_branch (LTU, operands[0]); DONE;")
12944 (define_expand "bge"
12946 (if_then_else (match_dup 1)
12947 (label_ref (match_operand 0 "" ""))
12950 "ix86_expand_branch (GE, operands[0]); DONE;")
12952 (define_expand "bgeu"
12954 (if_then_else (match_dup 1)
12955 (label_ref (match_operand 0 "" ""))
12958 "ix86_expand_branch (GEU, operands[0]); DONE;")
12960 (define_expand "ble"
12962 (if_then_else (match_dup 1)
12963 (label_ref (match_operand 0 "" ""))
12966 "ix86_expand_branch (LE, operands[0]); DONE;")
12968 (define_expand "bleu"
12970 (if_then_else (match_dup 1)
12971 (label_ref (match_operand 0 "" ""))
12974 "ix86_expand_branch (LEU, operands[0]); DONE;")
12976 (define_expand "bunordered"
12978 (if_then_else (match_dup 1)
12979 (label_ref (match_operand 0 "" ""))
12981 "TARGET_80387 || TARGET_SSE_MATH"
12982 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12984 (define_expand "bordered"
12986 (if_then_else (match_dup 1)
12987 (label_ref (match_operand 0 "" ""))
12989 "TARGET_80387 || TARGET_SSE_MATH"
12990 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12992 (define_expand "buneq"
12994 (if_then_else (match_dup 1)
12995 (label_ref (match_operand 0 "" ""))
12997 "TARGET_80387 || TARGET_SSE_MATH"
12998 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13000 (define_expand "bunge"
13002 (if_then_else (match_dup 1)
13003 (label_ref (match_operand 0 "" ""))
13005 "TARGET_80387 || TARGET_SSE_MATH"
13006 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13008 (define_expand "bungt"
13010 (if_then_else (match_dup 1)
13011 (label_ref (match_operand 0 "" ""))
13013 "TARGET_80387 || TARGET_SSE_MATH"
13014 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13016 (define_expand "bunle"
13018 (if_then_else (match_dup 1)
13019 (label_ref (match_operand 0 "" ""))
13021 "TARGET_80387 || TARGET_SSE_MATH"
13022 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13024 (define_expand "bunlt"
13026 (if_then_else (match_dup 1)
13027 (label_ref (match_operand 0 "" ""))
13029 "TARGET_80387 || TARGET_SSE_MATH"
13030 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13032 (define_expand "bltgt"
13034 (if_then_else (match_dup 1)
13035 (label_ref (match_operand 0 "" ""))
13037 "TARGET_80387 || TARGET_SSE_MATH"
13038 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13040 (define_insn "*jcc_1"
13042 (if_then_else (match_operator 1 "ix86_comparison_operator"
13043 [(reg FLAGS_REG) (const_int 0)])
13044 (label_ref (match_operand 0 "" ""))
13048 [(set_attr "type" "ibr")
13049 (set_attr "modrm" "0")
13050 (set (attr "length")
13051 (if_then_else (and (ge (minus (match_dup 0) (pc))
13053 (lt (minus (match_dup 0) (pc))
13058 (define_insn "*jcc_2"
13060 (if_then_else (match_operator 1 "ix86_comparison_operator"
13061 [(reg FLAGS_REG) (const_int 0)])
13063 (label_ref (match_operand 0 "" ""))))]
13066 [(set_attr "type" "ibr")
13067 (set_attr "modrm" "0")
13068 (set (attr "length")
13069 (if_then_else (and (ge (minus (match_dup 0) (pc))
13071 (lt (minus (match_dup 0) (pc))
13076 ;; In general it is not safe to assume too much about CCmode registers,
13077 ;; so simplify-rtx stops when it sees a second one. Under certain
13078 ;; conditions this is safe on x86, so help combine not create
13086 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13087 [(reg FLAGS_REG) (const_int 0)])
13089 (label_ref (match_operand 1 "" ""))
13093 (if_then_else (match_dup 0)
13094 (label_ref (match_dup 1))
13097 PUT_MODE (operands[0], VOIDmode);
13102 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13103 [(reg FLAGS_REG) (const_int 0)])
13105 (label_ref (match_operand 1 "" ""))
13109 (if_then_else (match_dup 0)
13110 (label_ref (match_dup 1))
13113 rtx new_op0 = copy_rtx (operands[0]);
13114 operands[0] = new_op0;
13115 PUT_MODE (new_op0, VOIDmode);
13116 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13117 GET_MODE (XEXP (new_op0, 0))));
13119 /* Make sure that (a) the CCmode we have for the flags is strong
13120 enough for the reversed compare or (b) we have a valid FP compare. */
13121 if (! ix86_comparison_operator (new_op0, VOIDmode))
13125 ;; Define combination compare-and-branch fp compare instructions to use
13126 ;; during early optimization. Splitting the operation apart early makes
13127 ;; for bad code when we want to reverse the operation.
13129 (define_insn "*fp_jcc_1_mixed"
13131 (if_then_else (match_operator 0 "comparison_operator"
13132 [(match_operand 1 "register_operand" "f#x,x#f")
13133 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13134 (label_ref (match_operand 3 "" ""))
13136 (clobber (reg:CCFP FPSR_REG))
13137 (clobber (reg:CCFP FLAGS_REG))]
13138 "TARGET_MIX_SSE_I387
13139 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13140 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13141 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13144 (define_insn "*fp_jcc_1_sse"
13146 (if_then_else (match_operator 0 "comparison_operator"
13147 [(match_operand 1 "register_operand" "x")
13148 (match_operand 2 "nonimmediate_operand" "xm")])
13149 (label_ref (match_operand 3 "" ""))
13151 (clobber (reg:CCFP FPSR_REG))
13152 (clobber (reg:CCFP FLAGS_REG))]
13154 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13155 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13156 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13159 (define_insn "*fp_jcc_1_387"
13161 (if_then_else (match_operator 0 "comparison_operator"
13162 [(match_operand 1 "register_operand" "f")
13163 (match_operand 2 "register_operand" "f")])
13164 (label_ref (match_operand 3 "" ""))
13166 (clobber (reg:CCFP FPSR_REG))
13167 (clobber (reg:CCFP FLAGS_REG))]
13168 "TARGET_CMOVE && TARGET_80387
13169 && FLOAT_MODE_P (GET_MODE (operands[1]))
13170 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13171 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13174 (define_insn "*fp_jcc_2_mixed"
13176 (if_then_else (match_operator 0 "comparison_operator"
13177 [(match_operand 1 "register_operand" "f#x,x#f")
13178 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13180 (label_ref (match_operand 3 "" ""))))
13181 (clobber (reg:CCFP FPSR_REG))
13182 (clobber (reg:CCFP FLAGS_REG))]
13183 "TARGET_MIX_SSE_I387
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_sse"
13191 (if_then_else (match_operator 0 "comparison_operator"
13192 [(match_operand 1 "register_operand" "x")
13193 (match_operand 2 "nonimmediate_operand" "xm")])
13195 (label_ref (match_operand 3 "" ""))))
13196 (clobber (reg:CCFP FPSR_REG))
13197 (clobber (reg:CCFP FLAGS_REG))]
13199 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13200 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13201 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13204 (define_insn "*fp_jcc_2_387"
13206 (if_then_else (match_operator 0 "comparison_operator"
13207 [(match_operand 1 "register_operand" "f")
13208 (match_operand 2 "register_operand" "f")])
13210 (label_ref (match_operand 3 "" ""))))
13211 (clobber (reg:CCFP FPSR_REG))
13212 (clobber (reg:CCFP FLAGS_REG))]
13213 "TARGET_CMOVE && TARGET_80387
13214 && FLOAT_MODE_P (GET_MODE (operands[1]))
13215 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13216 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13219 (define_insn "*fp_jcc_3_387"
13221 (if_then_else (match_operator 0 "comparison_operator"
13222 [(match_operand 1 "register_operand" "f")
13223 (match_operand 2 "nonimmediate_operand" "fm")])
13224 (label_ref (match_operand 3 "" ""))
13226 (clobber (reg:CCFP FPSR_REG))
13227 (clobber (reg:CCFP FLAGS_REG))
13228 (clobber (match_scratch:HI 4 "=a"))]
13230 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13231 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13232 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13233 && SELECT_CC_MODE (GET_CODE (operands[0]),
13234 operands[1], operands[2]) == CCFPmode
13235 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13238 (define_insn "*fp_jcc_4_387"
13240 (if_then_else (match_operator 0 "comparison_operator"
13241 [(match_operand 1 "register_operand" "f")
13242 (match_operand 2 "nonimmediate_operand" "fm")])
13244 (label_ref (match_operand 3 "" ""))))
13245 (clobber (reg:CCFP FPSR_REG))
13246 (clobber (reg:CCFP FLAGS_REG))
13247 (clobber (match_scratch:HI 4 "=a"))]
13249 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13250 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13251 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13252 && SELECT_CC_MODE (GET_CODE (operands[0]),
13253 operands[1], operands[2]) == CCFPmode
13254 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13257 (define_insn "*fp_jcc_5_387"
13259 (if_then_else (match_operator 0 "comparison_operator"
13260 [(match_operand 1 "register_operand" "f")
13261 (match_operand 2 "register_operand" "f")])
13262 (label_ref (match_operand 3 "" ""))
13264 (clobber (reg:CCFP FPSR_REG))
13265 (clobber (reg:CCFP FLAGS_REG))
13266 (clobber (match_scratch:HI 4 "=a"))]
13268 && FLOAT_MODE_P (GET_MODE (operands[1]))
13269 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13270 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13273 (define_insn "*fp_jcc_6_387"
13275 (if_then_else (match_operator 0 "comparison_operator"
13276 [(match_operand 1 "register_operand" "f")
13277 (match_operand 2 "register_operand" "f")])
13279 (label_ref (match_operand 3 "" ""))))
13280 (clobber (reg:CCFP FPSR_REG))
13281 (clobber (reg:CCFP FLAGS_REG))
13282 (clobber (match_scratch:HI 4 "=a"))]
13284 && FLOAT_MODE_P (GET_MODE (operands[1]))
13285 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13286 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13289 (define_insn "*fp_jcc_7_387"
13291 (if_then_else (match_operator 0 "comparison_operator"
13292 [(match_operand 1 "register_operand" "f")
13293 (match_operand 2 "const0_operand" "X")])
13294 (label_ref (match_operand 3 "" ""))
13296 (clobber (reg:CCFP FPSR_REG))
13297 (clobber (reg:CCFP FLAGS_REG))
13298 (clobber (match_scratch:HI 4 "=a"))]
13300 && FLOAT_MODE_P (GET_MODE (operands[1]))
13301 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13302 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13303 && SELECT_CC_MODE (GET_CODE (operands[0]),
13304 operands[1], operands[2]) == CCFPmode
13305 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13308 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13309 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13310 ;; with a precedence over other operators and is always put in the first
13311 ;; place. Swap condition and operands to match ficom instruction.
13313 (define_insn "*fp_jcc_8<mode>_387"
13315 (if_then_else (match_operator 0 "comparison_operator"
13316 [(match_operator 1 "float_operator"
13317 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13318 (match_operand 3 "register_operand" "f,f")])
13319 (label_ref (match_operand 4 "" ""))
13321 (clobber (reg:CCFP FPSR_REG))
13322 (clobber (reg:CCFP FLAGS_REG))
13323 (clobber (match_scratch:HI 5 "=a,a"))]
13324 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13325 && FLOAT_MODE_P (GET_MODE (operands[3]))
13326 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13327 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13328 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13329 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13334 (if_then_else (match_operator 0 "comparison_operator"
13335 [(match_operand 1 "register_operand" "")
13336 (match_operand 2 "nonimmediate_operand" "")])
13337 (match_operand 3 "" "")
13338 (match_operand 4 "" "")))
13339 (clobber (reg:CCFP FPSR_REG))
13340 (clobber (reg:CCFP FLAGS_REG))]
13344 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13345 operands[3], operands[4], NULL_RTX, NULL_RTX);
13351 (if_then_else (match_operator 0 "comparison_operator"
13352 [(match_operand 1 "register_operand" "")
13353 (match_operand 2 "general_operand" "")])
13354 (match_operand 3 "" "")
13355 (match_operand 4 "" "")))
13356 (clobber (reg:CCFP FPSR_REG))
13357 (clobber (reg:CCFP FLAGS_REG))
13358 (clobber (match_scratch:HI 5 "=a"))]
13362 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13363 operands[3], operands[4], operands[5], NULL_RTX);
13369 (if_then_else (match_operator 0 "comparison_operator"
13370 [(match_operator 1 "float_operator"
13371 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13372 (match_operand 3 "register_operand" "")])
13373 (match_operand 4 "" "")
13374 (match_operand 5 "" "")))
13375 (clobber (reg:CCFP FPSR_REG))
13376 (clobber (reg:CCFP FLAGS_REG))
13377 (clobber (match_scratch:HI 6 "=a"))]
13381 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13382 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13383 operands[3], operands[7],
13384 operands[4], operands[5], operands[6], NULL_RTX);
13388 ;; %%% Kill this when reload knows how to do it.
13391 (if_then_else (match_operator 0 "comparison_operator"
13392 [(match_operator 1 "float_operator"
13393 [(match_operand:X87MODEI12 2 "register_operand" "")])
13394 (match_operand 3 "register_operand" "")])
13395 (match_operand 4 "" "")
13396 (match_operand 5 "" "")))
13397 (clobber (reg:CCFP FPSR_REG))
13398 (clobber (reg:CCFP FLAGS_REG))
13399 (clobber (match_scratch:HI 6 "=a"))]
13403 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13404 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13405 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13406 operands[3], operands[7],
13407 operands[4], operands[5], operands[6], operands[2]);
13411 ;; Unconditional and other jump instructions
13413 (define_insn "jump"
13415 (label_ref (match_operand 0 "" "")))]
13418 [(set_attr "type" "ibr")
13419 (set (attr "length")
13420 (if_then_else (and (ge (minus (match_dup 0) (pc))
13422 (lt (minus (match_dup 0) (pc))
13426 (set_attr "modrm" "0")])
13428 (define_expand "indirect_jump"
13429 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13433 (define_insn "*indirect_jump"
13434 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13437 [(set_attr "type" "ibr")
13438 (set_attr "length_immediate" "0")])
13440 (define_insn "*indirect_jump_rtx64"
13441 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13444 [(set_attr "type" "ibr")
13445 (set_attr "length_immediate" "0")])
13447 (define_expand "tablejump"
13448 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13449 (use (label_ref (match_operand 1 "" "")))])]
13452 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13453 relative. Convert the relative address to an absolute address. */
13457 enum rtx_code code;
13463 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13465 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13469 op1 = pic_offset_table_rtx;
13474 op0 = pic_offset_table_rtx;
13478 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13483 (define_insn "*tablejump_1"
13484 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13485 (use (label_ref (match_operand 1 "" "")))]
13488 [(set_attr "type" "ibr")
13489 (set_attr "length_immediate" "0")])
13491 (define_insn "*tablejump_1_rtx64"
13492 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13493 (use (label_ref (match_operand 1 "" "")))]
13496 [(set_attr "type" "ibr")
13497 (set_attr "length_immediate" "0")])
13499 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13502 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13503 (set (match_operand:QI 1 "register_operand" "")
13504 (match_operator:QI 2 "ix86_comparison_operator"
13505 [(reg FLAGS_REG) (const_int 0)]))
13506 (set (match_operand 3 "q_regs_operand" "")
13507 (zero_extend (match_dup 1)))]
13508 "(peep2_reg_dead_p (3, operands[1])
13509 || operands_match_p (operands[1], operands[3]))
13510 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13511 [(set (match_dup 4) (match_dup 0))
13512 (set (strict_low_part (match_dup 5))
13515 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13516 operands[5] = gen_lowpart (QImode, operands[3]);
13517 ix86_expand_clear (operands[3]);
13520 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13523 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13524 (set (match_operand:QI 1 "register_operand" "")
13525 (match_operator:QI 2 "ix86_comparison_operator"
13526 [(reg FLAGS_REG) (const_int 0)]))
13527 (parallel [(set (match_operand 3 "q_regs_operand" "")
13528 (zero_extend (match_dup 1)))
13529 (clobber (reg:CC FLAGS_REG))])]
13530 "(peep2_reg_dead_p (3, operands[1])
13531 || operands_match_p (operands[1], operands[3]))
13532 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13533 [(set (match_dup 4) (match_dup 0))
13534 (set (strict_low_part (match_dup 5))
13537 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13538 operands[5] = gen_lowpart (QImode, operands[3]);
13539 ix86_expand_clear (operands[3]);
13542 ;; Call instructions.
13544 ;; The predicates normally associated with named expanders are not properly
13545 ;; checked for calls. This is a bug in the generic code, but it isn't that
13546 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13548 ;; Call subroutine returning no value.
13550 (define_expand "call_pop"
13551 [(parallel [(call (match_operand:QI 0 "" "")
13552 (match_operand:SI 1 "" ""))
13553 (set (reg:SI SP_REG)
13554 (plus:SI (reg:SI SP_REG)
13555 (match_operand:SI 3 "" "")))])]
13558 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13562 (define_insn "*call_pop_0"
13563 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13564 (match_operand:SI 1 "" ""))
13565 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13566 (match_operand:SI 2 "immediate_operand" "")))]
13569 if (SIBLING_CALL_P (insn))
13572 return "call\t%P0";
13574 [(set_attr "type" "call")])
13576 (define_insn "*call_pop_1"
13577 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13578 (match_operand:SI 1 "" ""))
13579 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13580 (match_operand:SI 2 "immediate_operand" "i")))]
13583 if (constant_call_address_operand (operands[0], Pmode))
13585 if (SIBLING_CALL_P (insn))
13588 return "call\t%P0";
13590 if (SIBLING_CALL_P (insn))
13593 return "call\t%A0";
13595 [(set_attr "type" "call")])
13597 (define_expand "call"
13598 [(call (match_operand:QI 0 "" "")
13599 (match_operand 1 "" ""))
13600 (use (match_operand 2 "" ""))]
13603 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13607 (define_expand "sibcall"
13608 [(call (match_operand:QI 0 "" "")
13609 (match_operand 1 "" ""))
13610 (use (match_operand 2 "" ""))]
13613 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13617 (define_insn "*call_0"
13618 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13619 (match_operand 1 "" ""))]
13622 if (SIBLING_CALL_P (insn))
13625 return "call\t%P0";
13627 [(set_attr "type" "call")])
13629 (define_insn "*call_1"
13630 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13631 (match_operand 1 "" ""))]
13632 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13634 if (constant_call_address_operand (operands[0], Pmode))
13635 return "call\t%P0";
13636 return "call\t%A0";
13638 [(set_attr "type" "call")])
13640 (define_insn "*sibcall_1"
13641 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13642 (match_operand 1 "" ""))]
13643 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13645 if (constant_call_address_operand (operands[0], Pmode))
13649 [(set_attr "type" "call")])
13651 (define_insn "*call_1_rex64"
13652 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13653 (match_operand 1 "" ""))]
13654 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13656 if (constant_call_address_operand (operands[0], Pmode))
13657 return "call\t%P0";
13658 return "call\t%A0";
13660 [(set_attr "type" "call")])
13662 (define_insn "*sibcall_1_rex64"
13663 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13664 (match_operand 1 "" ""))]
13665 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13667 [(set_attr "type" "call")])
13669 (define_insn "*sibcall_1_rex64_v"
13670 [(call (mem:QI (reg:DI 40))
13671 (match_operand 0 "" ""))]
13672 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13674 [(set_attr "type" "call")])
13677 ;; Call subroutine, returning value in operand 0
13679 (define_expand "call_value_pop"
13680 [(parallel [(set (match_operand 0 "" "")
13681 (call (match_operand:QI 1 "" "")
13682 (match_operand:SI 2 "" "")))
13683 (set (reg:SI SP_REG)
13684 (plus:SI (reg:SI SP_REG)
13685 (match_operand:SI 4 "" "")))])]
13688 ix86_expand_call (operands[0], operands[1], operands[2],
13689 operands[3], operands[4], 0);
13693 (define_expand "call_value"
13694 [(set (match_operand 0 "" "")
13695 (call (match_operand:QI 1 "" "")
13696 (match_operand:SI 2 "" "")))
13697 (use (match_operand:SI 3 "" ""))]
13698 ;; Operand 2 not used on the i386.
13701 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13705 (define_expand "sibcall_value"
13706 [(set (match_operand 0 "" "")
13707 (call (match_operand:QI 1 "" "")
13708 (match_operand:SI 2 "" "")))
13709 (use (match_operand:SI 3 "" ""))]
13710 ;; Operand 2 not used on the i386.
13713 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13717 ;; Call subroutine returning any type.
13719 (define_expand "untyped_call"
13720 [(parallel [(call (match_operand 0 "" "")
13722 (match_operand 1 "" "")
13723 (match_operand 2 "" "")])]
13728 /* In order to give reg-stack an easier job in validating two
13729 coprocessor registers as containing a possible return value,
13730 simply pretend the untyped call returns a complex long double
13733 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13734 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13735 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13738 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13740 rtx set = XVECEXP (operands[2], 0, i);
13741 emit_move_insn (SET_DEST (set), SET_SRC (set));
13744 /* The optimizer does not know that the call sets the function value
13745 registers we stored in the result block. We avoid problems by
13746 claiming that all hard registers are used and clobbered at this
13748 emit_insn (gen_blockage (const0_rtx));
13753 ;; Prologue and epilogue instructions
13755 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13756 ;; all of memory. This blocks insns from being moved across this point.
13758 (define_insn "blockage"
13759 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13762 [(set_attr "length" "0")])
13764 ;; Insn emitted into the body of a function to return from a function.
13765 ;; This is only done if the function's epilogue is known to be simple.
13766 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13768 (define_expand "return"
13770 "ix86_can_use_return_insn_p ()"
13772 if (current_function_pops_args)
13774 rtx popc = GEN_INT (current_function_pops_args);
13775 emit_jump_insn (gen_return_pop_internal (popc));
13780 (define_insn "return_internal"
13784 [(set_attr "length" "1")
13785 (set_attr "length_immediate" "0")
13786 (set_attr "modrm" "0")])
13788 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13789 ;; instruction Athlon and K8 have.
13791 (define_insn "return_internal_long"
13793 (unspec [(const_int 0)] UNSPEC_REP)]
13796 [(set_attr "length" "1")
13797 (set_attr "length_immediate" "0")
13798 (set_attr "prefix_rep" "1")
13799 (set_attr "modrm" "0")])
13801 (define_insn "return_pop_internal"
13803 (use (match_operand:SI 0 "const_int_operand" ""))]
13806 [(set_attr "length" "3")
13807 (set_attr "length_immediate" "2")
13808 (set_attr "modrm" "0")])
13810 (define_insn "return_indirect_internal"
13812 (use (match_operand:SI 0 "register_operand" "r"))]
13815 [(set_attr "type" "ibr")
13816 (set_attr "length_immediate" "0")])
13822 [(set_attr "length" "1")
13823 (set_attr "length_immediate" "0")
13824 (set_attr "modrm" "0")])
13826 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13827 ;; branch prediction penalty for the third jump in a 16-byte
13830 (define_insn "align"
13831 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13834 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13835 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13837 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13838 The align insn is used to avoid 3 jump instructions in the row to improve
13839 branch prediction and the benefits hardly outweight the cost of extra 8
13840 nops on the average inserted by full alignment pseudo operation. */
13844 [(set_attr "length" "16")])
13846 (define_expand "prologue"
13849 "ix86_expand_prologue (); DONE;")
13851 (define_insn "set_got"
13852 [(set (match_operand:SI 0 "register_operand" "=r")
13853 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13854 (clobber (reg:CC FLAGS_REG))]
13856 { return output_set_got (operands[0]); }
13857 [(set_attr "type" "multi")
13858 (set_attr "length" "12")])
13860 (define_insn "set_got_rex64"
13861 [(set (match_operand:DI 0 "register_operand" "=r")
13862 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13864 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13865 [(set_attr "type" "lea")
13866 (set_attr "length" "6")])
13868 (define_expand "epilogue"
13871 "ix86_expand_epilogue (1); DONE;")
13873 (define_expand "sibcall_epilogue"
13876 "ix86_expand_epilogue (0); DONE;")
13878 (define_expand "eh_return"
13879 [(use (match_operand 0 "register_operand" ""))]
13882 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13884 /* Tricky bit: we write the address of the handler to which we will
13885 be returning into someone else's stack frame, one word below the
13886 stack address we wish to restore. */
13887 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13888 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13889 tmp = gen_rtx_MEM (Pmode, tmp);
13890 emit_move_insn (tmp, ra);
13892 if (Pmode == SImode)
13893 emit_jump_insn (gen_eh_return_si (sa));
13895 emit_jump_insn (gen_eh_return_di (sa));
13900 (define_insn_and_split "eh_return_si"
13902 (unspec [(match_operand:SI 0 "register_operand" "c")]
13903 UNSPEC_EH_RETURN))]
13908 "ix86_expand_epilogue (2); DONE;")
13910 (define_insn_and_split "eh_return_di"
13912 (unspec [(match_operand:DI 0 "register_operand" "c")]
13913 UNSPEC_EH_RETURN))]
13918 "ix86_expand_epilogue (2); DONE;")
13920 (define_insn "leave"
13921 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13922 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13923 (clobber (mem:BLK (scratch)))]
13926 [(set_attr "type" "leave")])
13928 (define_insn "leave_rex64"
13929 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13930 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13931 (clobber (mem:BLK (scratch)))]
13934 [(set_attr "type" "leave")])
13936 (define_expand "ffssi2"
13938 [(set (match_operand:SI 0 "register_operand" "")
13939 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13940 (clobber (match_scratch:SI 2 ""))
13941 (clobber (reg:CC FLAGS_REG))])]
13945 (define_insn_and_split "*ffs_cmove"
13946 [(set (match_operand:SI 0 "register_operand" "=r")
13947 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13948 (clobber (match_scratch:SI 2 "=&r"))
13949 (clobber (reg:CC FLAGS_REG))]
13952 "&& reload_completed"
13953 [(set (match_dup 2) (const_int -1))
13954 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13955 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13956 (set (match_dup 0) (if_then_else:SI
13957 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13960 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13961 (clobber (reg:CC FLAGS_REG))])]
13964 (define_insn_and_split "*ffs_no_cmove"
13965 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13966 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13967 (clobber (match_scratch:SI 2 "=&q"))
13968 (clobber (reg:CC FLAGS_REG))]
13972 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13973 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13974 (set (strict_low_part (match_dup 3))
13975 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13976 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13977 (clobber (reg:CC FLAGS_REG))])
13978 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13979 (clobber (reg:CC FLAGS_REG))])
13980 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13981 (clobber (reg:CC FLAGS_REG))])]
13983 operands[3] = gen_lowpart (QImode, operands[2]);
13984 ix86_expand_clear (operands[2]);
13987 (define_insn "*ffssi_1"
13988 [(set (reg:CCZ FLAGS_REG)
13989 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13991 (set (match_operand:SI 0 "register_operand" "=r")
13992 (ctz:SI (match_dup 1)))]
13994 "bsf{l}\t{%1, %0|%0, %1}"
13995 [(set_attr "prefix_0f" "1")])
13997 (define_expand "ffsdi2"
13999 [(set (match_operand:DI 0 "register_operand" "")
14000 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14001 (clobber (match_scratch:DI 2 ""))
14002 (clobber (reg:CC FLAGS_REG))])]
14003 "TARGET_64BIT && TARGET_CMOVE"
14006 (define_insn_and_split "*ffs_rex64"
14007 [(set (match_operand:DI 0 "register_operand" "=r")
14008 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14009 (clobber (match_scratch:DI 2 "=&r"))
14010 (clobber (reg:CC FLAGS_REG))]
14011 "TARGET_64BIT && TARGET_CMOVE"
14013 "&& reload_completed"
14014 [(set (match_dup 2) (const_int -1))
14015 (parallel [(set (reg:CCZ FLAGS_REG)
14016 (compare:CCZ (match_dup 1) (const_int 0)))
14017 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14018 (set (match_dup 0) (if_then_else:DI
14019 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14022 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14023 (clobber (reg:CC FLAGS_REG))])]
14026 (define_insn "*ffsdi_1"
14027 [(set (reg:CCZ FLAGS_REG)
14028 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14030 (set (match_operand:DI 0 "register_operand" "=r")
14031 (ctz:DI (match_dup 1)))]
14033 "bsf{q}\t{%1, %0|%0, %1}"
14034 [(set_attr "prefix_0f" "1")])
14036 (define_insn "ctzsi2"
14037 [(set (match_operand:SI 0 "register_operand" "=r")
14038 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14039 (clobber (reg:CC FLAGS_REG))]
14041 "bsf{l}\t{%1, %0|%0, %1}"
14042 [(set_attr "prefix_0f" "1")])
14044 (define_insn "ctzdi2"
14045 [(set (match_operand:DI 0 "register_operand" "=r")
14046 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14047 (clobber (reg:CC FLAGS_REG))]
14049 "bsf{q}\t{%1, %0|%0, %1}"
14050 [(set_attr "prefix_0f" "1")])
14052 (define_expand "clzsi2"
14054 [(set (match_operand:SI 0 "register_operand" "")
14055 (minus:SI (const_int 31)
14056 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14057 (clobber (reg:CC FLAGS_REG))])
14059 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14060 (clobber (reg:CC FLAGS_REG))])]
14064 (define_insn "*bsr"
14065 [(set (match_operand:SI 0 "register_operand" "=r")
14066 (minus:SI (const_int 31)
14067 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14068 (clobber (reg:CC FLAGS_REG))]
14070 "bsr{l}\t{%1, %0|%0, %1}"
14071 [(set_attr "prefix_0f" "1")])
14073 (define_expand "clzdi2"
14075 [(set (match_operand:DI 0 "register_operand" "")
14076 (minus:DI (const_int 63)
14077 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14078 (clobber (reg:CC FLAGS_REG))])
14080 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14081 (clobber (reg:CC FLAGS_REG))])]
14085 (define_insn "*bsr_rex64"
14086 [(set (match_operand:DI 0 "register_operand" "=r")
14087 (minus:DI (const_int 63)
14088 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14089 (clobber (reg:CC FLAGS_REG))]
14091 "bsr{q}\t{%1, %0|%0, %1}"
14092 [(set_attr "prefix_0f" "1")])
14094 ;; Thread-local storage patterns for ELF.
14096 ;; Note that these code sequences must appear exactly as shown
14097 ;; in order to allow linker relaxation.
14099 (define_insn "*tls_global_dynamic_32_gnu"
14100 [(set (match_operand:SI 0 "register_operand" "=a")
14101 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14102 (match_operand:SI 2 "tls_symbolic_operand" "")
14103 (match_operand:SI 3 "call_insn_operand" "")]
14105 (clobber (match_scratch:SI 4 "=d"))
14106 (clobber (match_scratch:SI 5 "=c"))
14107 (clobber (reg:CC FLAGS_REG))]
14108 "!TARGET_64BIT && TARGET_GNU_TLS"
14109 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14110 [(set_attr "type" "multi")
14111 (set_attr "length" "12")])
14113 (define_insn "*tls_global_dynamic_32_sun"
14114 [(set (match_operand:SI 0 "register_operand" "=a")
14115 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14116 (match_operand:SI 2 "tls_symbolic_operand" "")
14117 (match_operand:SI 3 "call_insn_operand" "")]
14119 (clobber (match_scratch:SI 4 "=d"))
14120 (clobber (match_scratch:SI 5 "=c"))
14121 (clobber (reg:CC FLAGS_REG))]
14122 "!TARGET_64BIT && TARGET_SUN_TLS"
14123 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14124 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14125 [(set_attr "type" "multi")
14126 (set_attr "length" "14")])
14128 (define_expand "tls_global_dynamic_32"
14129 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14132 (match_operand:SI 1 "tls_symbolic_operand" "")
14135 (clobber (match_scratch:SI 4 ""))
14136 (clobber (match_scratch:SI 5 ""))
14137 (clobber (reg:CC FLAGS_REG))])]
14141 operands[2] = pic_offset_table_rtx;
14144 operands[2] = gen_reg_rtx (Pmode);
14145 emit_insn (gen_set_got (operands[2]));
14147 operands[3] = ix86_tls_get_addr ();
14150 (define_insn "*tls_global_dynamic_64"
14151 [(set (match_operand:DI 0 "register_operand" "=a")
14152 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14153 (match_operand:DI 3 "" "")))
14154 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14157 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14158 [(set_attr "type" "multi")
14159 (set_attr "length" "16")])
14161 (define_expand "tls_global_dynamic_64"
14162 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14163 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14164 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14168 operands[2] = ix86_tls_get_addr ();
14171 (define_insn "*tls_local_dynamic_base_32_gnu"
14172 [(set (match_operand:SI 0 "register_operand" "=a")
14173 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14174 (match_operand:SI 2 "call_insn_operand" "")]
14175 UNSPEC_TLS_LD_BASE))
14176 (clobber (match_scratch:SI 3 "=d"))
14177 (clobber (match_scratch:SI 4 "=c"))
14178 (clobber (reg:CC FLAGS_REG))]
14179 "!TARGET_64BIT && TARGET_GNU_TLS"
14180 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14181 [(set_attr "type" "multi")
14182 (set_attr "length" "11")])
14184 (define_insn "*tls_local_dynamic_base_32_sun"
14185 [(set (match_operand:SI 0 "register_operand" "=a")
14186 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14187 (match_operand:SI 2 "call_insn_operand" "")]
14188 UNSPEC_TLS_LD_BASE))
14189 (clobber (match_scratch:SI 3 "=d"))
14190 (clobber (match_scratch:SI 4 "=c"))
14191 (clobber (reg:CC FLAGS_REG))]
14192 "!TARGET_64BIT && TARGET_SUN_TLS"
14193 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14194 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14195 [(set_attr "type" "multi")
14196 (set_attr "length" "13")])
14198 (define_expand "tls_local_dynamic_base_32"
14199 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14200 (unspec:SI [(match_dup 1) (match_dup 2)]
14201 UNSPEC_TLS_LD_BASE))
14202 (clobber (match_scratch:SI 3 ""))
14203 (clobber (match_scratch:SI 4 ""))
14204 (clobber (reg:CC FLAGS_REG))])]
14208 operands[1] = pic_offset_table_rtx;
14211 operands[1] = gen_reg_rtx (Pmode);
14212 emit_insn (gen_set_got (operands[1]));
14214 operands[2] = ix86_tls_get_addr ();
14217 (define_insn "*tls_local_dynamic_base_64"
14218 [(set (match_operand:DI 0 "register_operand" "=a")
14219 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14220 (match_operand:DI 2 "" "")))
14221 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14223 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14224 [(set_attr "type" "multi")
14225 (set_attr "length" "12")])
14227 (define_expand "tls_local_dynamic_base_64"
14228 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14229 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14230 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14233 operands[1] = ix86_tls_get_addr ();
14236 ;; Local dynamic of a single variable is a lose. Show combine how
14237 ;; to convert that back to global dynamic.
14239 (define_insn_and_split "*tls_local_dynamic_32_once"
14240 [(set (match_operand:SI 0 "register_operand" "=a")
14241 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14242 (match_operand:SI 2 "call_insn_operand" "")]
14243 UNSPEC_TLS_LD_BASE)
14244 (const:SI (unspec:SI
14245 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14247 (clobber (match_scratch:SI 4 "=d"))
14248 (clobber (match_scratch:SI 5 "=c"))
14249 (clobber (reg:CC FLAGS_REG))]
14253 [(parallel [(set (match_dup 0)
14254 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14256 (clobber (match_dup 4))
14257 (clobber (match_dup 5))
14258 (clobber (reg:CC FLAGS_REG))])]
14261 ;; Load and add the thread base pointer from %gs:0.
14263 (define_insn "*load_tp_si"
14264 [(set (match_operand:SI 0 "register_operand" "=r")
14265 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14267 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14268 [(set_attr "type" "imov")
14269 (set_attr "modrm" "0")
14270 (set_attr "length" "7")
14271 (set_attr "memory" "load")
14272 (set_attr "imm_disp" "false")])
14274 (define_insn "*add_tp_si"
14275 [(set (match_operand:SI 0 "register_operand" "=r")
14276 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14277 (match_operand:SI 1 "register_operand" "0")))
14278 (clobber (reg:CC FLAGS_REG))]
14280 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14281 [(set_attr "type" "alu")
14282 (set_attr "modrm" "0")
14283 (set_attr "length" "7")
14284 (set_attr "memory" "load")
14285 (set_attr "imm_disp" "false")])
14287 (define_insn "*load_tp_di"
14288 [(set (match_operand:DI 0 "register_operand" "=r")
14289 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14291 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14292 [(set_attr "type" "imov")
14293 (set_attr "modrm" "0")
14294 (set_attr "length" "7")
14295 (set_attr "memory" "load")
14296 (set_attr "imm_disp" "false")])
14298 (define_insn "*add_tp_di"
14299 [(set (match_operand:DI 0 "register_operand" "=r")
14300 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14301 (match_operand:DI 1 "register_operand" "0")))
14302 (clobber (reg:CC FLAGS_REG))]
14304 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14305 [(set_attr "type" "alu")
14306 (set_attr "modrm" "0")
14307 (set_attr "length" "7")
14308 (set_attr "memory" "load")
14309 (set_attr "imm_disp" "false")])
14311 ;; These patterns match the binary 387 instructions for addM3, subM3,
14312 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14313 ;; SFmode. The first is the normal insn, the second the same insn but
14314 ;; with one operand a conversion, and the third the same insn but with
14315 ;; the other operand a conversion. The conversion may be SFmode or
14316 ;; SImode if the target mode DFmode, but only SImode if the target mode
14319 ;; Gcc is slightly more smart about handling normal two address instructions
14320 ;; so use special patterns for add and mull.
14322 (define_insn "*fop_sf_comm_mixed"
14323 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14324 (match_operator:SF 3 "binary_fp_operator"
14325 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14326 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14327 "TARGET_MIX_SSE_I387
14328 && COMMUTATIVE_ARITH_P (operands[3])
14329 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14330 "* return output_387_binary_op (insn, operands);"
14331 [(set (attr "type")
14332 (if_then_else (eq_attr "alternative" "1")
14333 (if_then_else (match_operand:SF 3 "mult_operator" "")
14334 (const_string "ssemul")
14335 (const_string "sseadd"))
14336 (if_then_else (match_operand:SF 3 "mult_operator" "")
14337 (const_string "fmul")
14338 (const_string "fop"))))
14339 (set_attr "mode" "SF")])
14341 (define_insn "*fop_sf_comm_sse"
14342 [(set (match_operand:SF 0 "register_operand" "=x")
14343 (match_operator:SF 3 "binary_fp_operator"
14344 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14345 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14347 && COMMUTATIVE_ARITH_P (operands[3])
14348 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14349 "* return output_387_binary_op (insn, operands);"
14350 [(set (attr "type")
14351 (if_then_else (match_operand:SF 3 "mult_operator" "")
14352 (const_string "ssemul")
14353 (const_string "sseadd")))
14354 (set_attr "mode" "SF")])
14356 (define_insn "*fop_sf_comm_i387"
14357 [(set (match_operand:SF 0 "register_operand" "=f")
14358 (match_operator:SF 3 "binary_fp_operator"
14359 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14360 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14362 && COMMUTATIVE_ARITH_P (operands[3])
14363 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14364 "* return output_387_binary_op (insn, operands);"
14365 [(set (attr "type")
14366 (if_then_else (match_operand:SF 3 "mult_operator" "")
14367 (const_string "fmul")
14368 (const_string "fop")))
14369 (set_attr "mode" "SF")])
14371 (define_insn "*fop_sf_1_mixed"
14372 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14373 (match_operator:SF 3 "binary_fp_operator"
14374 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14375 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14376 "TARGET_MIX_SSE_I387
14377 && !COMMUTATIVE_ARITH_P (operands[3])
14378 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14379 "* return output_387_binary_op (insn, operands);"
14380 [(set (attr "type")
14381 (cond [(and (eq_attr "alternative" "2")
14382 (match_operand:SF 3 "mult_operator" ""))
14383 (const_string "ssemul")
14384 (and (eq_attr "alternative" "2")
14385 (match_operand:SF 3 "div_operator" ""))
14386 (const_string "ssediv")
14387 (eq_attr "alternative" "2")
14388 (const_string "sseadd")
14389 (match_operand:SF 3 "mult_operator" "")
14390 (const_string "fmul")
14391 (match_operand:SF 3 "div_operator" "")
14392 (const_string "fdiv")
14394 (const_string "fop")))
14395 (set_attr "mode" "SF")])
14397 (define_insn "*fop_sf_1_sse"
14398 [(set (match_operand:SF 0 "register_operand" "=x")
14399 (match_operator:SF 3 "binary_fp_operator"
14400 [(match_operand:SF 1 "register_operand" "0")
14401 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14403 && !COMMUTATIVE_ARITH_P (operands[3])"
14404 "* return output_387_binary_op (insn, operands);"
14405 [(set (attr "type")
14406 (cond [(match_operand:SF 3 "mult_operator" "")
14407 (const_string "ssemul")
14408 (match_operand:SF 3 "div_operator" "")
14409 (const_string "ssediv")
14411 (const_string "sseadd")))
14412 (set_attr "mode" "SF")])
14414 ;; This pattern is not fully shadowed by the pattern above.
14415 (define_insn "*fop_sf_1_i387"
14416 [(set (match_operand:SF 0 "register_operand" "=f,f")
14417 (match_operator:SF 3 "binary_fp_operator"
14418 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14419 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14420 "TARGET_80387 && !TARGET_SSE_MATH
14421 && !COMMUTATIVE_ARITH_P (operands[3])
14422 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14423 "* return output_387_binary_op (insn, operands);"
14424 [(set (attr "type")
14425 (cond [(match_operand:SF 3 "mult_operator" "")
14426 (const_string "fmul")
14427 (match_operand:SF 3 "div_operator" "")
14428 (const_string "fdiv")
14430 (const_string "fop")))
14431 (set_attr "mode" "SF")])
14433 ;; ??? Add SSE splitters for these!
14434 (define_insn "*fop_sf_2<mode>_i387"
14435 [(set (match_operand:SF 0 "register_operand" "=f,f")
14436 (match_operator:SF 3 "binary_fp_operator"
14437 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14438 (match_operand:SF 2 "register_operand" "0,0")]))]
14439 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14440 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14441 [(set (attr "type")
14442 (cond [(match_operand:SF 3 "mult_operator" "")
14443 (const_string "fmul")
14444 (match_operand:SF 3 "div_operator" "")
14445 (const_string "fdiv")
14447 (const_string "fop")))
14448 (set_attr "fp_int_src" "true")
14449 (set_attr "mode" "<MODE>")])
14451 (define_insn "*fop_sf_3<mode>_i387"
14452 [(set (match_operand:SF 0 "register_operand" "=f,f")
14453 (match_operator:SF 3 "binary_fp_operator"
14454 [(match_operand:SF 1 "register_operand" "0,0")
14455 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14456 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14457 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14458 [(set (attr "type")
14459 (cond [(match_operand:SF 3 "mult_operator" "")
14460 (const_string "fmul")
14461 (match_operand:SF 3 "div_operator" "")
14462 (const_string "fdiv")
14464 (const_string "fop")))
14465 (set_attr "fp_int_src" "true")
14466 (set_attr "mode" "<MODE>")])
14468 (define_insn "*fop_df_comm_mixed"
14469 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14470 (match_operator:DF 3 "binary_fp_operator"
14471 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14472 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14473 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14474 && COMMUTATIVE_ARITH_P (operands[3])
14475 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14476 "* return output_387_binary_op (insn, operands);"
14477 [(set (attr "type")
14478 (if_then_else (eq_attr "alternative" "1")
14479 (if_then_else (match_operand:SF 3 "mult_operator" "")
14480 (const_string "ssemul")
14481 (const_string "sseadd"))
14482 (if_then_else (match_operand:SF 3 "mult_operator" "")
14483 (const_string "fmul")
14484 (const_string "fop"))))
14485 (set_attr "mode" "DF")])
14487 (define_insn "*fop_df_comm_sse"
14488 [(set (match_operand:DF 0 "register_operand" "=Y")
14489 (match_operator:DF 3 "binary_fp_operator"
14490 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14491 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14492 "TARGET_SSE2 && TARGET_SSE_MATH
14493 && COMMUTATIVE_ARITH_P (operands[3])
14494 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14495 "* return output_387_binary_op (insn, operands);"
14496 [(set (attr "type")
14497 (if_then_else (match_operand:SF 3 "mult_operator" "")
14498 (const_string "ssemul")
14499 (const_string "sseadd")))
14500 (set_attr "mode" "DF")])
14502 (define_insn "*fop_df_comm_i387"
14503 [(set (match_operand:DF 0 "register_operand" "=f")
14504 (match_operator:DF 3 "binary_fp_operator"
14505 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14506 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14508 && COMMUTATIVE_ARITH_P (operands[3])
14509 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14510 "* return output_387_binary_op (insn, operands);"
14511 [(set (attr "type")
14512 (if_then_else (match_operand:SF 3 "mult_operator" "")
14513 (const_string "fmul")
14514 (const_string "fop")))
14515 (set_attr "mode" "DF")])
14517 (define_insn "*fop_df_1_mixed"
14518 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14519 (match_operator:DF 3 "binary_fp_operator"
14520 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14521 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14522 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14523 && !COMMUTATIVE_ARITH_P (operands[3])
14524 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14525 "* return output_387_binary_op (insn, operands);"
14526 [(set (attr "type")
14527 (cond [(and (eq_attr "alternative" "2")
14528 (match_operand:SF 3 "mult_operator" ""))
14529 (const_string "ssemul")
14530 (and (eq_attr "alternative" "2")
14531 (match_operand:SF 3 "div_operator" ""))
14532 (const_string "ssediv")
14533 (eq_attr "alternative" "2")
14534 (const_string "sseadd")
14535 (match_operand:DF 3 "mult_operator" "")
14536 (const_string "fmul")
14537 (match_operand:DF 3 "div_operator" "")
14538 (const_string "fdiv")
14540 (const_string "fop")))
14541 (set_attr "mode" "DF")])
14543 (define_insn "*fop_df_1_sse"
14544 [(set (match_operand:DF 0 "register_operand" "=Y")
14545 (match_operator:DF 3 "binary_fp_operator"
14546 [(match_operand:DF 1 "register_operand" "0")
14547 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14548 "TARGET_SSE2 && TARGET_SSE_MATH
14549 && !COMMUTATIVE_ARITH_P (operands[3])"
14550 "* return output_387_binary_op (insn, operands);"
14551 [(set_attr "mode" "DF")
14553 (cond [(match_operand:SF 3 "mult_operator" "")
14554 (const_string "ssemul")
14555 (match_operand:SF 3 "div_operator" "")
14556 (const_string "ssediv")
14558 (const_string "sseadd")))])
14560 ;; This pattern is not fully shadowed by the pattern above.
14561 (define_insn "*fop_df_1_i387"
14562 [(set (match_operand:DF 0 "register_operand" "=f,f")
14563 (match_operator:DF 3 "binary_fp_operator"
14564 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14565 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14566 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14567 && !COMMUTATIVE_ARITH_P (operands[3])
14568 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14569 "* return output_387_binary_op (insn, operands);"
14570 [(set (attr "type")
14571 (cond [(match_operand:DF 3 "mult_operator" "")
14572 (const_string "fmul")
14573 (match_operand:DF 3 "div_operator" "")
14574 (const_string "fdiv")
14576 (const_string "fop")))
14577 (set_attr "mode" "DF")])
14579 ;; ??? Add SSE splitters for these!
14580 (define_insn "*fop_df_2<mode>_i387"
14581 [(set (match_operand:DF 0 "register_operand" "=f,f")
14582 (match_operator:DF 3 "binary_fp_operator"
14583 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14584 (match_operand:DF 2 "register_operand" "0,0")]))]
14585 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14586 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14587 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14588 [(set (attr "type")
14589 (cond [(match_operand:DF 3 "mult_operator" "")
14590 (const_string "fmul")
14591 (match_operand:DF 3 "div_operator" "")
14592 (const_string "fdiv")
14594 (const_string "fop")))
14595 (set_attr "fp_int_src" "true")
14596 (set_attr "mode" "<MODE>")])
14598 (define_insn "*fop_df_3<mode>_i387"
14599 [(set (match_operand:DF 0 "register_operand" "=f,f")
14600 (match_operator:DF 3 "binary_fp_operator"
14601 [(match_operand:DF 1 "register_operand" "0,0")
14602 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14603 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14604 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14605 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14606 [(set (attr "type")
14607 (cond [(match_operand:DF 3 "mult_operator" "")
14608 (const_string "fmul")
14609 (match_operand:DF 3 "div_operator" "")
14610 (const_string "fdiv")
14612 (const_string "fop")))
14613 (set_attr "fp_int_src" "true")
14614 (set_attr "mode" "<MODE>")])
14616 (define_insn "*fop_df_4_i387"
14617 [(set (match_operand:DF 0 "register_operand" "=f,f")
14618 (match_operator:DF 3 "binary_fp_operator"
14619 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14620 (match_operand:DF 2 "register_operand" "0,f")]))]
14621 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14622 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14623 "* return output_387_binary_op (insn, operands);"
14624 [(set (attr "type")
14625 (cond [(match_operand:DF 3 "mult_operator" "")
14626 (const_string "fmul")
14627 (match_operand:DF 3 "div_operator" "")
14628 (const_string "fdiv")
14630 (const_string "fop")))
14631 (set_attr "mode" "SF")])
14633 (define_insn "*fop_df_5_i387"
14634 [(set (match_operand:DF 0 "register_operand" "=f,f")
14635 (match_operator:DF 3 "binary_fp_operator"
14636 [(match_operand:DF 1 "register_operand" "0,f")
14638 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14639 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14640 "* return output_387_binary_op (insn, operands);"
14641 [(set (attr "type")
14642 (cond [(match_operand:DF 3 "mult_operator" "")
14643 (const_string "fmul")
14644 (match_operand:DF 3 "div_operator" "")
14645 (const_string "fdiv")
14647 (const_string "fop")))
14648 (set_attr "mode" "SF")])
14650 (define_insn "*fop_df_6_i387"
14651 [(set (match_operand:DF 0 "register_operand" "=f,f")
14652 (match_operator:DF 3 "binary_fp_operator"
14654 (match_operand:SF 1 "register_operand" "0,f"))
14656 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14657 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14658 "* return output_387_binary_op (insn, operands);"
14659 [(set (attr "type")
14660 (cond [(match_operand:DF 3 "mult_operator" "")
14661 (const_string "fmul")
14662 (match_operand:DF 3 "div_operator" "")
14663 (const_string "fdiv")
14665 (const_string "fop")))
14666 (set_attr "mode" "SF")])
14668 (define_insn "*fop_xf_comm_i387"
14669 [(set (match_operand:XF 0 "register_operand" "=f")
14670 (match_operator:XF 3 "binary_fp_operator"
14671 [(match_operand:XF 1 "register_operand" "%0")
14672 (match_operand:XF 2 "register_operand" "f")]))]
14674 && COMMUTATIVE_ARITH_P (operands[3])"
14675 "* return output_387_binary_op (insn, operands);"
14676 [(set (attr "type")
14677 (if_then_else (match_operand:XF 3 "mult_operator" "")
14678 (const_string "fmul")
14679 (const_string "fop")))
14680 (set_attr "mode" "XF")])
14682 (define_insn "*fop_xf_1_i387"
14683 [(set (match_operand:XF 0 "register_operand" "=f,f")
14684 (match_operator:XF 3 "binary_fp_operator"
14685 [(match_operand:XF 1 "register_operand" "0,f")
14686 (match_operand:XF 2 "register_operand" "f,0")]))]
14688 && !COMMUTATIVE_ARITH_P (operands[3])"
14689 "* return output_387_binary_op (insn, operands);"
14690 [(set (attr "type")
14691 (cond [(match_operand:XF 3 "mult_operator" "")
14692 (const_string "fmul")
14693 (match_operand:XF 3 "div_operator" "")
14694 (const_string "fdiv")
14696 (const_string "fop")))
14697 (set_attr "mode" "XF")])
14699 (define_insn "*fop_xf_2<mode>_i387"
14700 [(set (match_operand:XF 0 "register_operand" "=f,f")
14701 (match_operator:XF 3 "binary_fp_operator"
14702 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14703 (match_operand:XF 2 "register_operand" "0,0")]))]
14704 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14705 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14706 [(set (attr "type")
14707 (cond [(match_operand:XF 3 "mult_operator" "")
14708 (const_string "fmul")
14709 (match_operand:XF 3 "div_operator" "")
14710 (const_string "fdiv")
14712 (const_string "fop")))
14713 (set_attr "fp_int_src" "true")
14714 (set_attr "mode" "<MODE>")])
14716 (define_insn "*fop_xf_3<mode>_i387"
14717 [(set (match_operand:XF 0 "register_operand" "=f,f")
14718 (match_operator:XF 3 "binary_fp_operator"
14719 [(match_operand:XF 1 "register_operand" "0,0")
14720 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14721 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14722 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14723 [(set (attr "type")
14724 (cond [(match_operand:XF 3 "mult_operator" "")
14725 (const_string "fmul")
14726 (match_operand:XF 3 "div_operator" "")
14727 (const_string "fdiv")
14729 (const_string "fop")))
14730 (set_attr "fp_int_src" "true")
14731 (set_attr "mode" "<MODE>")])
14733 (define_insn "*fop_xf_4_i387"
14734 [(set (match_operand:XF 0 "register_operand" "=f,f")
14735 (match_operator:XF 3 "binary_fp_operator"
14736 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14737 (match_operand:XF 2 "register_operand" "0,f")]))]
14739 "* return output_387_binary_op (insn, operands);"
14740 [(set (attr "type")
14741 (cond [(match_operand:XF 3 "mult_operator" "")
14742 (const_string "fmul")
14743 (match_operand:XF 3 "div_operator" "")
14744 (const_string "fdiv")
14746 (const_string "fop")))
14747 (set_attr "mode" "SF")])
14749 (define_insn "*fop_xf_5_i387"
14750 [(set (match_operand:XF 0 "register_operand" "=f,f")
14751 (match_operator:XF 3 "binary_fp_operator"
14752 [(match_operand:XF 1 "register_operand" "0,f")
14754 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14756 "* return output_387_binary_op (insn, operands);"
14757 [(set (attr "type")
14758 (cond [(match_operand:XF 3 "mult_operator" "")
14759 (const_string "fmul")
14760 (match_operand:XF 3 "div_operator" "")
14761 (const_string "fdiv")
14763 (const_string "fop")))
14764 (set_attr "mode" "SF")])
14766 (define_insn "*fop_xf_6_i387"
14767 [(set (match_operand:XF 0 "register_operand" "=f,f")
14768 (match_operator:XF 3 "binary_fp_operator"
14770 (match_operand 1 "register_operand" "0,f"))
14772 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14774 "* return output_387_binary_op (insn, operands);"
14775 [(set (attr "type")
14776 (cond [(match_operand:XF 3 "mult_operator" "")
14777 (const_string "fmul")
14778 (match_operand:XF 3 "div_operator" "")
14779 (const_string "fdiv")
14781 (const_string "fop")))
14782 (set_attr "mode" "SF")])
14785 [(set (match_operand 0 "register_operand" "")
14786 (match_operator 3 "binary_fp_operator"
14787 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14788 (match_operand 2 "register_operand" "")]))]
14789 "TARGET_80387 && reload_completed
14790 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14793 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14794 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14795 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14796 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14797 GET_MODE (operands[3]),
14800 ix86_free_from_memory (GET_MODE (operands[1]));
14805 [(set (match_operand 0 "register_operand" "")
14806 (match_operator 3 "binary_fp_operator"
14807 [(match_operand 1 "register_operand" "")
14808 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14809 "TARGET_80387 && reload_completed
14810 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14813 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14814 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14815 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14816 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14817 GET_MODE (operands[3]),
14820 ix86_free_from_memory (GET_MODE (operands[2]));
14824 ;; FPU special functions.
14826 (define_expand "sqrtsf2"
14827 [(set (match_operand:SF 0 "register_operand" "")
14828 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14829 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14831 if (!TARGET_SSE_MATH)
14832 operands[1] = force_reg (SFmode, operands[1]);
14835 (define_insn "*sqrtsf2_mixed"
14836 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14837 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14838 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14841 sqrtss\t{%1, %0|%0, %1}"
14842 [(set_attr "type" "fpspc,sse")
14843 (set_attr "mode" "SF,SF")
14844 (set_attr "athlon_decode" "direct,*")])
14846 (define_insn "*sqrtsf2_sse"
14847 [(set (match_operand:SF 0 "register_operand" "=x")
14848 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14850 "sqrtss\t{%1, %0|%0, %1}"
14851 [(set_attr "type" "sse")
14852 (set_attr "mode" "SF")
14853 (set_attr "athlon_decode" "*")])
14855 (define_insn "*sqrtsf2_i387"
14856 [(set (match_operand:SF 0 "register_operand" "=f")
14857 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14858 "TARGET_USE_FANCY_MATH_387"
14860 [(set_attr "type" "fpspc")
14861 (set_attr "mode" "SF")
14862 (set_attr "athlon_decode" "direct")])
14864 (define_expand "sqrtdf2"
14865 [(set (match_operand:DF 0 "register_operand" "")
14866 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14867 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14869 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14870 operands[1] = force_reg (DFmode, operands[1]);
14873 (define_insn "*sqrtdf2_mixed"
14874 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14875 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14876 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14879 sqrtsd\t{%1, %0|%0, %1}"
14880 [(set_attr "type" "fpspc,sse")
14881 (set_attr "mode" "DF,DF")
14882 (set_attr "athlon_decode" "direct,*")])
14884 (define_insn "*sqrtdf2_sse"
14885 [(set (match_operand:DF 0 "register_operand" "=Y")
14886 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14887 "TARGET_SSE2 && TARGET_SSE_MATH"
14888 "sqrtsd\t{%1, %0|%0, %1}"
14889 [(set_attr "type" "sse")
14890 (set_attr "mode" "DF")
14891 (set_attr "athlon_decode" "*")])
14893 (define_insn "*sqrtdf2_i387"
14894 [(set (match_operand:DF 0 "register_operand" "=f")
14895 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14896 "TARGET_USE_FANCY_MATH_387"
14898 [(set_attr "type" "fpspc")
14899 (set_attr "mode" "DF")
14900 (set_attr "athlon_decode" "direct")])
14902 (define_insn "*sqrtextendsfdf2_i387"
14903 [(set (match_operand:DF 0 "register_operand" "=f")
14904 (sqrt:DF (float_extend:DF
14905 (match_operand:SF 1 "register_operand" "0"))))]
14906 "TARGET_USE_FANCY_MATH_387
14907 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14909 [(set_attr "type" "fpspc")
14910 (set_attr "mode" "DF")
14911 (set_attr "athlon_decode" "direct")])
14913 (define_insn "sqrtxf2"
14914 [(set (match_operand:XF 0 "register_operand" "=f")
14915 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14916 "TARGET_USE_FANCY_MATH_387
14917 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14919 [(set_attr "type" "fpspc")
14920 (set_attr "mode" "XF")
14921 (set_attr "athlon_decode" "direct")])
14923 (define_insn "*sqrtextendsfxf2_i387"
14924 [(set (match_operand:XF 0 "register_operand" "=f")
14925 (sqrt:XF (float_extend:XF
14926 (match_operand:SF 1 "register_operand" "0"))))]
14927 "TARGET_USE_FANCY_MATH_387"
14929 [(set_attr "type" "fpspc")
14930 (set_attr "mode" "XF")
14931 (set_attr "athlon_decode" "direct")])
14933 (define_insn "*sqrtextenddfxf2_i387"
14934 [(set (match_operand:XF 0 "register_operand" "=f")
14935 (sqrt:XF (float_extend:XF
14936 (match_operand:DF 1 "register_operand" "0"))))]
14937 "TARGET_USE_FANCY_MATH_387"
14939 [(set_attr "type" "fpspc")
14940 (set_attr "mode" "XF")
14941 (set_attr "athlon_decode" "direct")])
14943 (define_insn "fpremxf4"
14944 [(set (match_operand:XF 0 "register_operand" "=f")
14945 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14946 (match_operand:XF 3 "register_operand" "1")]
14948 (set (match_operand:XF 1 "register_operand" "=u")
14949 (unspec:XF [(match_dup 2) (match_dup 3)]
14951 (set (reg:CCFP FPSR_REG)
14952 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14953 "TARGET_USE_FANCY_MATH_387
14954 && flag_unsafe_math_optimizations"
14956 [(set_attr "type" "fpspc")
14957 (set_attr "mode" "XF")])
14959 (define_expand "fmodsf3"
14960 [(use (match_operand:SF 0 "register_operand" ""))
14961 (use (match_operand:SF 1 "register_operand" ""))
14962 (use (match_operand:SF 2 "register_operand" ""))]
14963 "TARGET_USE_FANCY_MATH_387
14964 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14965 && flag_unsafe_math_optimizations"
14967 rtx label = gen_label_rtx ();
14969 rtx op1 = gen_reg_rtx (XFmode);
14970 rtx op2 = gen_reg_rtx (XFmode);
14972 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14973 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14975 emit_label (label);
14977 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14978 ix86_emit_fp_unordered_jump (label);
14980 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14984 (define_expand "fmoddf3"
14985 [(use (match_operand:DF 0 "register_operand" ""))
14986 (use (match_operand:DF 1 "register_operand" ""))
14987 (use (match_operand:DF 2 "register_operand" ""))]
14988 "TARGET_USE_FANCY_MATH_387
14989 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14990 && flag_unsafe_math_optimizations"
14992 rtx label = gen_label_rtx ();
14994 rtx op1 = gen_reg_rtx (XFmode);
14995 rtx op2 = gen_reg_rtx (XFmode);
14997 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14998 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15000 emit_label (label);
15002 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15003 ix86_emit_fp_unordered_jump (label);
15005 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15009 (define_expand "fmodxf3"
15010 [(use (match_operand:XF 0 "register_operand" ""))
15011 (use (match_operand:XF 1 "register_operand" ""))
15012 (use (match_operand:XF 2 "register_operand" ""))]
15013 "TARGET_USE_FANCY_MATH_387
15014 && flag_unsafe_math_optimizations"
15016 rtx label = gen_label_rtx ();
15018 emit_label (label);
15020 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15021 operands[1], operands[2]));
15022 ix86_emit_fp_unordered_jump (label);
15024 emit_move_insn (operands[0], operands[1]);
15028 (define_insn "fprem1xf4"
15029 [(set (match_operand:XF 0 "register_operand" "=f")
15030 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15031 (match_operand:XF 3 "register_operand" "1")]
15033 (set (match_operand:XF 1 "register_operand" "=u")
15034 (unspec:XF [(match_dup 2) (match_dup 3)]
15036 (set (reg:CCFP FPSR_REG)
15037 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15038 "TARGET_USE_FANCY_MATH_387
15039 && flag_unsafe_math_optimizations"
15041 [(set_attr "type" "fpspc")
15042 (set_attr "mode" "XF")])
15044 (define_expand "dremsf3"
15045 [(use (match_operand:SF 0 "register_operand" ""))
15046 (use (match_operand:SF 1 "register_operand" ""))
15047 (use (match_operand:SF 2 "register_operand" ""))]
15048 "TARGET_USE_FANCY_MATH_387
15049 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15050 && flag_unsafe_math_optimizations"
15052 rtx label = gen_label_rtx ();
15054 rtx op1 = gen_reg_rtx (XFmode);
15055 rtx op2 = gen_reg_rtx (XFmode);
15057 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15058 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15060 emit_label (label);
15062 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15063 ix86_emit_fp_unordered_jump (label);
15065 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15069 (define_expand "dremdf3"
15070 [(use (match_operand:DF 0 "register_operand" ""))
15071 (use (match_operand:DF 1 "register_operand" ""))
15072 (use (match_operand:DF 2 "register_operand" ""))]
15073 "TARGET_USE_FANCY_MATH_387
15074 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15075 && flag_unsafe_math_optimizations"
15077 rtx label = gen_label_rtx ();
15079 rtx op1 = gen_reg_rtx (XFmode);
15080 rtx op2 = gen_reg_rtx (XFmode);
15082 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15083 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15085 emit_label (label);
15087 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15088 ix86_emit_fp_unordered_jump (label);
15090 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15094 (define_expand "dremxf3"
15095 [(use (match_operand:XF 0 "register_operand" ""))
15096 (use (match_operand:XF 1 "register_operand" ""))
15097 (use (match_operand:XF 2 "register_operand" ""))]
15098 "TARGET_USE_FANCY_MATH_387
15099 && flag_unsafe_math_optimizations"
15101 rtx label = gen_label_rtx ();
15103 emit_label (label);
15105 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15106 operands[1], operands[2]));
15107 ix86_emit_fp_unordered_jump (label);
15109 emit_move_insn (operands[0], operands[1]);
15113 (define_insn "*sindf2"
15114 [(set (match_operand:DF 0 "register_operand" "=f")
15115 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15116 "TARGET_USE_FANCY_MATH_387
15117 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15118 && flag_unsafe_math_optimizations"
15120 [(set_attr "type" "fpspc")
15121 (set_attr "mode" "DF")])
15123 (define_insn "*sinsf2"
15124 [(set (match_operand:SF 0 "register_operand" "=f")
15125 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15126 "TARGET_USE_FANCY_MATH_387
15127 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15128 && flag_unsafe_math_optimizations"
15130 [(set_attr "type" "fpspc")
15131 (set_attr "mode" "SF")])
15133 (define_insn "*sinextendsfdf2"
15134 [(set (match_operand:DF 0 "register_operand" "=f")
15135 (unspec:DF [(float_extend:DF
15136 (match_operand:SF 1 "register_operand" "0"))]
15138 "TARGET_USE_FANCY_MATH_387
15139 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15140 && flag_unsafe_math_optimizations"
15142 [(set_attr "type" "fpspc")
15143 (set_attr "mode" "DF")])
15145 (define_insn "*sinxf2"
15146 [(set (match_operand:XF 0 "register_operand" "=f")
15147 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && flag_unsafe_math_optimizations"
15151 [(set_attr "type" "fpspc")
15152 (set_attr "mode" "XF")])
15154 (define_insn "*cosdf2"
15155 [(set (match_operand:DF 0 "register_operand" "=f")
15156 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15157 "TARGET_USE_FANCY_MATH_387
15158 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15159 && flag_unsafe_math_optimizations"
15161 [(set_attr "type" "fpspc")
15162 (set_attr "mode" "DF")])
15164 (define_insn "*cossf2"
15165 [(set (match_operand:SF 0 "register_operand" "=f")
15166 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15167 "TARGET_USE_FANCY_MATH_387
15168 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15169 && flag_unsafe_math_optimizations"
15171 [(set_attr "type" "fpspc")
15172 (set_attr "mode" "SF")])
15174 (define_insn "*cosextendsfdf2"
15175 [(set (match_operand:DF 0 "register_operand" "=f")
15176 (unspec:DF [(float_extend:DF
15177 (match_operand:SF 1 "register_operand" "0"))]
15179 "TARGET_USE_FANCY_MATH_387
15180 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15181 && flag_unsafe_math_optimizations"
15183 [(set_attr "type" "fpspc")
15184 (set_attr "mode" "DF")])
15186 (define_insn "*cosxf2"
15187 [(set (match_operand:XF 0 "register_operand" "=f")
15188 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15189 "TARGET_USE_FANCY_MATH_387
15190 && flag_unsafe_math_optimizations"
15192 [(set_attr "type" "fpspc")
15193 (set_attr "mode" "XF")])
15195 ;; With sincos pattern defined, sin and cos builtin function will be
15196 ;; expanded to sincos pattern with one of its outputs left unused.
15197 ;; Cse pass will detected, if two sincos patterns can be combined,
15198 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15199 ;; depending on the unused output.
15201 (define_insn "sincosdf3"
15202 [(set (match_operand:DF 0 "register_operand" "=f")
15203 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15204 UNSPEC_SINCOS_COS))
15205 (set (match_operand:DF 1 "register_operand" "=u")
15206 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15207 "TARGET_USE_FANCY_MATH_387
15208 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15209 && flag_unsafe_math_optimizations"
15211 [(set_attr "type" "fpspc")
15212 (set_attr "mode" "DF")])
15215 [(set (match_operand:DF 0 "register_operand" "")
15216 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15217 UNSPEC_SINCOS_COS))
15218 (set (match_operand:DF 1 "register_operand" "")
15219 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15220 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15221 && !reload_completed && !reload_in_progress"
15222 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15226 [(set (match_operand:DF 0 "register_operand" "")
15227 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15228 UNSPEC_SINCOS_COS))
15229 (set (match_operand:DF 1 "register_operand" "")
15230 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15231 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15232 && !reload_completed && !reload_in_progress"
15233 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15236 (define_insn "sincossf3"
15237 [(set (match_operand:SF 0 "register_operand" "=f")
15238 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15239 UNSPEC_SINCOS_COS))
15240 (set (match_operand:SF 1 "register_operand" "=u")
15241 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15242 "TARGET_USE_FANCY_MATH_387
15243 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15244 && flag_unsafe_math_optimizations"
15246 [(set_attr "type" "fpspc")
15247 (set_attr "mode" "SF")])
15250 [(set (match_operand:SF 0 "register_operand" "")
15251 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15252 UNSPEC_SINCOS_COS))
15253 (set (match_operand:SF 1 "register_operand" "")
15254 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15255 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15256 && !reload_completed && !reload_in_progress"
15257 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15261 [(set (match_operand:SF 0 "register_operand" "")
15262 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15263 UNSPEC_SINCOS_COS))
15264 (set (match_operand:SF 1 "register_operand" "")
15265 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15266 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15267 && !reload_completed && !reload_in_progress"
15268 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15271 (define_insn "*sincosextendsfdf3"
15272 [(set (match_operand:DF 0 "register_operand" "=f")
15273 (unspec:DF [(float_extend:DF
15274 (match_operand:SF 2 "register_operand" "0"))]
15275 UNSPEC_SINCOS_COS))
15276 (set (match_operand:DF 1 "register_operand" "=u")
15277 (unspec:DF [(float_extend:DF
15278 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15279 "TARGET_USE_FANCY_MATH_387
15280 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15281 && flag_unsafe_math_optimizations"
15283 [(set_attr "type" "fpspc")
15284 (set_attr "mode" "DF")])
15287 [(set (match_operand:DF 0 "register_operand" "")
15288 (unspec:DF [(float_extend:DF
15289 (match_operand:SF 2 "register_operand" ""))]
15290 UNSPEC_SINCOS_COS))
15291 (set (match_operand:DF 1 "register_operand" "")
15292 (unspec:DF [(float_extend:DF
15293 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15294 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15295 && !reload_completed && !reload_in_progress"
15296 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15297 (match_dup 2))] UNSPEC_SIN))]
15301 [(set (match_operand:DF 0 "register_operand" "")
15302 (unspec:DF [(float_extend:DF
15303 (match_operand:SF 2 "register_operand" ""))]
15304 UNSPEC_SINCOS_COS))
15305 (set (match_operand:DF 1 "register_operand" "")
15306 (unspec:DF [(float_extend:DF
15307 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15308 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15309 && !reload_completed && !reload_in_progress"
15310 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15311 (match_dup 2))] UNSPEC_COS))]
15314 (define_insn "sincosxf3"
15315 [(set (match_operand:XF 0 "register_operand" "=f")
15316 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15317 UNSPEC_SINCOS_COS))
15318 (set (match_operand:XF 1 "register_operand" "=u")
15319 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15320 "TARGET_USE_FANCY_MATH_387
15321 && flag_unsafe_math_optimizations"
15323 [(set_attr "type" "fpspc")
15324 (set_attr "mode" "XF")])
15327 [(set (match_operand:XF 0 "register_operand" "")
15328 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15329 UNSPEC_SINCOS_COS))
15330 (set (match_operand:XF 1 "register_operand" "")
15331 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15332 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15333 && !reload_completed && !reload_in_progress"
15334 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15338 [(set (match_operand:XF 0 "register_operand" "")
15339 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15340 UNSPEC_SINCOS_COS))
15341 (set (match_operand:XF 1 "register_operand" "")
15342 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15343 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15344 && !reload_completed && !reload_in_progress"
15345 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15348 (define_insn "*tandf3_1"
15349 [(set (match_operand:DF 0 "register_operand" "=f")
15350 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15352 (set (match_operand:DF 1 "register_operand" "=u")
15353 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15354 "TARGET_USE_FANCY_MATH_387
15355 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15356 && flag_unsafe_math_optimizations"
15358 [(set_attr "type" "fpspc")
15359 (set_attr "mode" "DF")])
15361 ;; optimize sequence: fptan
15364 ;; into fptan insn.
15367 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15368 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15370 (set (match_operand:DF 1 "register_operand" "")
15371 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15373 (match_operand:DF 3 "immediate_operand" ""))]
15374 "standard_80387_constant_p (operands[3]) == 2"
15375 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15376 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15379 (define_expand "tandf2"
15380 [(parallel [(set (match_dup 2)
15381 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15383 (set (match_operand:DF 0 "register_operand" "")
15384 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15385 "TARGET_USE_FANCY_MATH_387
15386 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15387 && flag_unsafe_math_optimizations"
15389 operands[2] = gen_reg_rtx (DFmode);
15392 (define_insn "*tansf3_1"
15393 [(set (match_operand:SF 0 "register_operand" "=f")
15394 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15396 (set (match_operand:SF 1 "register_operand" "=u")
15397 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15398 "TARGET_USE_FANCY_MATH_387
15399 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15400 && flag_unsafe_math_optimizations"
15402 [(set_attr "type" "fpspc")
15403 (set_attr "mode" "SF")])
15405 ;; optimize sequence: fptan
15408 ;; into fptan insn.
15411 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15412 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15414 (set (match_operand:SF 1 "register_operand" "")
15415 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15417 (match_operand:SF 3 "immediate_operand" ""))]
15418 "standard_80387_constant_p (operands[3]) == 2"
15419 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15420 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15423 (define_expand "tansf2"
15424 [(parallel [(set (match_dup 2)
15425 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15427 (set (match_operand:SF 0 "register_operand" "")
15428 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15429 "TARGET_USE_FANCY_MATH_387
15430 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15431 && flag_unsafe_math_optimizations"
15433 operands[2] = gen_reg_rtx (SFmode);
15436 (define_insn "*tanxf3_1"
15437 [(set (match_operand:XF 0 "register_operand" "=f")
15438 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15440 (set (match_operand:XF 1 "register_operand" "=u")
15441 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15442 "TARGET_USE_FANCY_MATH_387
15443 && flag_unsafe_math_optimizations"
15445 [(set_attr "type" "fpspc")
15446 (set_attr "mode" "XF")])
15448 ;; optimize sequence: fptan
15451 ;; into fptan insn.
15454 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15455 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15457 (set (match_operand:XF 1 "register_operand" "")
15458 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15460 (match_operand:XF 3 "immediate_operand" ""))]
15461 "standard_80387_constant_p (operands[3]) == 2"
15462 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15463 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15466 (define_expand "tanxf2"
15467 [(parallel [(set (match_dup 2)
15468 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15470 (set (match_operand:XF 0 "register_operand" "")
15471 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15472 "TARGET_USE_FANCY_MATH_387
15473 && flag_unsafe_math_optimizations"
15475 operands[2] = gen_reg_rtx (XFmode);
15478 (define_insn "atan2df3_1"
15479 [(set (match_operand:DF 0 "register_operand" "=f")
15480 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15481 (match_operand:DF 1 "register_operand" "u")]
15483 (clobber (match_scratch:DF 3 "=1"))]
15484 "TARGET_USE_FANCY_MATH_387
15485 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15486 && flag_unsafe_math_optimizations"
15488 [(set_attr "type" "fpspc")
15489 (set_attr "mode" "DF")])
15491 (define_expand "atan2df3"
15492 [(use (match_operand:DF 0 "register_operand" ""))
15493 (use (match_operand:DF 2 "register_operand" ""))
15494 (use (match_operand:DF 1 "register_operand" ""))]
15495 "TARGET_USE_FANCY_MATH_387
15496 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15497 && flag_unsafe_math_optimizations"
15499 rtx copy = gen_reg_rtx (DFmode);
15500 emit_move_insn (copy, operands[1]);
15501 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15505 (define_expand "atandf2"
15506 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15507 (unspec:DF [(match_dup 2)
15508 (match_operand:DF 1 "register_operand" "")]
15510 (clobber (match_scratch:DF 3 ""))])]
15511 "TARGET_USE_FANCY_MATH_387
15512 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15513 && flag_unsafe_math_optimizations"
15515 operands[2] = gen_reg_rtx (DFmode);
15516 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15519 (define_insn "atan2sf3_1"
15520 [(set (match_operand:SF 0 "register_operand" "=f")
15521 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15522 (match_operand:SF 1 "register_operand" "u")]
15524 (clobber (match_scratch:SF 3 "=1"))]
15525 "TARGET_USE_FANCY_MATH_387
15526 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15527 && flag_unsafe_math_optimizations"
15529 [(set_attr "type" "fpspc")
15530 (set_attr "mode" "SF")])
15532 (define_expand "atan2sf3"
15533 [(use (match_operand:SF 0 "register_operand" ""))
15534 (use (match_operand:SF 2 "register_operand" ""))
15535 (use (match_operand:SF 1 "register_operand" ""))]
15536 "TARGET_USE_FANCY_MATH_387
15537 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15538 && flag_unsafe_math_optimizations"
15540 rtx copy = gen_reg_rtx (SFmode);
15541 emit_move_insn (copy, operands[1]);
15542 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15546 (define_expand "atansf2"
15547 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15548 (unspec:SF [(match_dup 2)
15549 (match_operand:SF 1 "register_operand" "")]
15551 (clobber (match_scratch:SF 3 ""))])]
15552 "TARGET_USE_FANCY_MATH_387
15553 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15554 && flag_unsafe_math_optimizations"
15556 operands[2] = gen_reg_rtx (SFmode);
15557 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15560 (define_insn "atan2xf3_1"
15561 [(set (match_operand:XF 0 "register_operand" "=f")
15562 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15563 (match_operand:XF 1 "register_operand" "u")]
15565 (clobber (match_scratch:XF 3 "=1"))]
15566 "TARGET_USE_FANCY_MATH_387
15567 && flag_unsafe_math_optimizations"
15569 [(set_attr "type" "fpspc")
15570 (set_attr "mode" "XF")])
15572 (define_expand "atan2xf3"
15573 [(use (match_operand:XF 0 "register_operand" ""))
15574 (use (match_operand:XF 2 "register_operand" ""))
15575 (use (match_operand:XF 1 "register_operand" ""))]
15576 "TARGET_USE_FANCY_MATH_387
15577 && flag_unsafe_math_optimizations"
15579 rtx copy = gen_reg_rtx (XFmode);
15580 emit_move_insn (copy, operands[1]);
15581 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15585 (define_expand "atanxf2"
15586 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15587 (unspec:XF [(match_dup 2)
15588 (match_operand:XF 1 "register_operand" "")]
15590 (clobber (match_scratch:XF 3 ""))])]
15591 "TARGET_USE_FANCY_MATH_387
15592 && flag_unsafe_math_optimizations"
15594 operands[2] = gen_reg_rtx (XFmode);
15595 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15598 (define_expand "asindf2"
15599 [(set (match_dup 2)
15600 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15601 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15602 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15603 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15604 (parallel [(set (match_dup 7)
15605 (unspec:XF [(match_dup 6) (match_dup 2)]
15607 (clobber (match_scratch:XF 8 ""))])
15608 (set (match_operand:DF 0 "register_operand" "")
15609 (float_truncate:DF (match_dup 7)))]
15610 "TARGET_USE_FANCY_MATH_387
15611 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15612 && flag_unsafe_math_optimizations"
15616 for (i=2; i<8; i++)
15617 operands[i] = gen_reg_rtx (XFmode);
15619 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15622 (define_expand "asinsf2"
15623 [(set (match_dup 2)
15624 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15625 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15626 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15627 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15628 (parallel [(set (match_dup 7)
15629 (unspec:XF [(match_dup 6) (match_dup 2)]
15631 (clobber (match_scratch:XF 8 ""))])
15632 (set (match_operand:SF 0 "register_operand" "")
15633 (float_truncate:SF (match_dup 7)))]
15634 "TARGET_USE_FANCY_MATH_387
15635 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15636 && flag_unsafe_math_optimizations"
15640 for (i=2; i<8; i++)
15641 operands[i] = gen_reg_rtx (XFmode);
15643 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15646 (define_expand "asinxf2"
15647 [(set (match_dup 2)
15648 (mult:XF (match_operand:XF 1 "register_operand" "")
15650 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15651 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15652 (parallel [(set (match_operand:XF 0 "register_operand" "")
15653 (unspec:XF [(match_dup 5) (match_dup 1)]
15655 (clobber (match_scratch:XF 6 ""))])]
15656 "TARGET_USE_FANCY_MATH_387
15657 && flag_unsafe_math_optimizations"
15661 for (i=2; i<6; i++)
15662 operands[i] = gen_reg_rtx (XFmode);
15664 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15667 (define_expand "acosdf2"
15668 [(set (match_dup 2)
15669 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15670 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15671 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15672 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15673 (parallel [(set (match_dup 7)
15674 (unspec:XF [(match_dup 2) (match_dup 6)]
15676 (clobber (match_scratch:XF 8 ""))])
15677 (set (match_operand:DF 0 "register_operand" "")
15678 (float_truncate:DF (match_dup 7)))]
15679 "TARGET_USE_FANCY_MATH_387
15680 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15681 && flag_unsafe_math_optimizations"
15685 for (i=2; i<8; i++)
15686 operands[i] = gen_reg_rtx (XFmode);
15688 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15691 (define_expand "acossf2"
15692 [(set (match_dup 2)
15693 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15694 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15695 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15696 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15697 (parallel [(set (match_dup 7)
15698 (unspec:XF [(match_dup 2) (match_dup 6)]
15700 (clobber (match_scratch:XF 8 ""))])
15701 (set (match_operand:SF 0 "register_operand" "")
15702 (float_truncate:SF (match_dup 7)))]
15703 "TARGET_USE_FANCY_MATH_387
15704 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15705 && flag_unsafe_math_optimizations"
15709 for (i=2; i<8; i++)
15710 operands[i] = gen_reg_rtx (XFmode);
15712 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15715 (define_expand "acosxf2"
15716 [(set (match_dup 2)
15717 (mult:XF (match_operand:XF 1 "register_operand" "")
15719 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15720 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15721 (parallel [(set (match_operand:XF 0 "register_operand" "")
15722 (unspec:XF [(match_dup 1) (match_dup 5)]
15724 (clobber (match_scratch:XF 6 ""))])]
15725 "TARGET_USE_FANCY_MATH_387
15726 && flag_unsafe_math_optimizations"
15730 for (i=2; i<6; i++)
15731 operands[i] = gen_reg_rtx (XFmode);
15733 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15736 (define_insn "fyl2x_xf3"
15737 [(set (match_operand:XF 0 "register_operand" "=f")
15738 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15739 (match_operand:XF 1 "register_operand" "u")]
15741 (clobber (match_scratch:XF 3 "=1"))]
15742 "TARGET_USE_FANCY_MATH_387
15743 && flag_unsafe_math_optimizations"
15745 [(set_attr "type" "fpspc")
15746 (set_attr "mode" "XF")])
15748 (define_expand "logsf2"
15749 [(set (match_dup 2)
15750 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15751 (parallel [(set (match_dup 4)
15752 (unspec:XF [(match_dup 2)
15753 (match_dup 3)] UNSPEC_FYL2X))
15754 (clobber (match_scratch:XF 5 ""))])
15755 (set (match_operand:SF 0 "register_operand" "")
15756 (float_truncate:SF (match_dup 4)))]
15757 "TARGET_USE_FANCY_MATH_387
15758 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15759 && flag_unsafe_math_optimizations"
15763 operands[2] = gen_reg_rtx (XFmode);
15764 operands[3] = gen_reg_rtx (XFmode);
15765 operands[4] = gen_reg_rtx (XFmode);
15767 temp = standard_80387_constant_rtx (4); /* fldln2 */
15768 emit_move_insn (operands[3], temp);
15771 (define_expand "logdf2"
15772 [(set (match_dup 2)
15773 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15774 (parallel [(set (match_dup 4)
15775 (unspec:XF [(match_dup 2)
15776 (match_dup 3)] UNSPEC_FYL2X))
15777 (clobber (match_scratch:XF 5 ""))])
15778 (set (match_operand:DF 0 "register_operand" "")
15779 (float_truncate:DF (match_dup 4)))]
15780 "TARGET_USE_FANCY_MATH_387
15781 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15782 && flag_unsafe_math_optimizations"
15786 operands[2] = gen_reg_rtx (XFmode);
15787 operands[3] = gen_reg_rtx (XFmode);
15788 operands[4] = gen_reg_rtx (XFmode);
15790 temp = standard_80387_constant_rtx (4); /* fldln2 */
15791 emit_move_insn (operands[3], temp);
15794 (define_expand "logxf2"
15795 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15796 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15797 (match_dup 2)] UNSPEC_FYL2X))
15798 (clobber (match_scratch:XF 3 ""))])]
15799 "TARGET_USE_FANCY_MATH_387
15800 && flag_unsafe_math_optimizations"
15804 operands[2] = gen_reg_rtx (XFmode);
15805 temp = standard_80387_constant_rtx (4); /* fldln2 */
15806 emit_move_insn (operands[2], temp);
15809 (define_expand "log10sf2"
15810 [(set (match_dup 2)
15811 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15812 (parallel [(set (match_dup 4)
15813 (unspec:XF [(match_dup 2)
15814 (match_dup 3)] UNSPEC_FYL2X))
15815 (clobber (match_scratch:XF 5 ""))])
15816 (set (match_operand:SF 0 "register_operand" "")
15817 (float_truncate:SF (match_dup 4)))]
15818 "TARGET_USE_FANCY_MATH_387
15819 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15820 && flag_unsafe_math_optimizations"
15824 operands[2] = gen_reg_rtx (XFmode);
15825 operands[3] = gen_reg_rtx (XFmode);
15826 operands[4] = gen_reg_rtx (XFmode);
15828 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15829 emit_move_insn (operands[3], temp);
15832 (define_expand "log10df2"
15833 [(set (match_dup 2)
15834 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15835 (parallel [(set (match_dup 4)
15836 (unspec:XF [(match_dup 2)
15837 (match_dup 3)] UNSPEC_FYL2X))
15838 (clobber (match_scratch:XF 5 ""))])
15839 (set (match_operand:DF 0 "register_operand" "")
15840 (float_truncate:DF (match_dup 4)))]
15841 "TARGET_USE_FANCY_MATH_387
15842 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15843 && flag_unsafe_math_optimizations"
15847 operands[2] = gen_reg_rtx (XFmode);
15848 operands[3] = gen_reg_rtx (XFmode);
15849 operands[4] = gen_reg_rtx (XFmode);
15851 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15852 emit_move_insn (operands[3], temp);
15855 (define_expand "log10xf2"
15856 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15857 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15858 (match_dup 2)] UNSPEC_FYL2X))
15859 (clobber (match_scratch:XF 3 ""))])]
15860 "TARGET_USE_FANCY_MATH_387
15861 && flag_unsafe_math_optimizations"
15865 operands[2] = gen_reg_rtx (XFmode);
15866 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15867 emit_move_insn (operands[2], temp);
15870 (define_expand "log2sf2"
15871 [(set (match_dup 2)
15872 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15873 (parallel [(set (match_dup 4)
15874 (unspec:XF [(match_dup 2)
15875 (match_dup 3)] UNSPEC_FYL2X))
15876 (clobber (match_scratch:XF 5 ""))])
15877 (set (match_operand:SF 0 "register_operand" "")
15878 (float_truncate:SF (match_dup 4)))]
15879 "TARGET_USE_FANCY_MATH_387
15880 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15881 && flag_unsafe_math_optimizations"
15883 operands[2] = gen_reg_rtx (XFmode);
15884 operands[3] = gen_reg_rtx (XFmode);
15885 operands[4] = gen_reg_rtx (XFmode);
15887 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15890 (define_expand "log2df2"
15891 [(set (match_dup 2)
15892 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15893 (parallel [(set (match_dup 4)
15894 (unspec:XF [(match_dup 2)
15895 (match_dup 3)] UNSPEC_FYL2X))
15896 (clobber (match_scratch:XF 5 ""))])
15897 (set (match_operand:DF 0 "register_operand" "")
15898 (float_truncate:DF (match_dup 4)))]
15899 "TARGET_USE_FANCY_MATH_387
15900 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15901 && flag_unsafe_math_optimizations"
15903 operands[2] = gen_reg_rtx (XFmode);
15904 operands[3] = gen_reg_rtx (XFmode);
15905 operands[4] = gen_reg_rtx (XFmode);
15907 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15910 (define_expand "log2xf2"
15911 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15912 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15913 (match_dup 2)] UNSPEC_FYL2X))
15914 (clobber (match_scratch:XF 3 ""))])]
15915 "TARGET_USE_FANCY_MATH_387
15916 && flag_unsafe_math_optimizations"
15918 operands[2] = gen_reg_rtx (XFmode);
15919 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15922 (define_insn "fyl2xp1_xf3"
15923 [(set (match_operand:XF 0 "register_operand" "=f")
15924 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15925 (match_operand:XF 1 "register_operand" "u")]
15927 (clobber (match_scratch:XF 3 "=1"))]
15928 "TARGET_USE_FANCY_MATH_387
15929 && flag_unsafe_math_optimizations"
15931 [(set_attr "type" "fpspc")
15932 (set_attr "mode" "XF")])
15934 (define_expand "log1psf2"
15935 [(use (match_operand:SF 0 "register_operand" ""))
15936 (use (match_operand:SF 1 "register_operand" ""))]
15937 "TARGET_USE_FANCY_MATH_387
15938 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15939 && flag_unsafe_math_optimizations"
15941 rtx op0 = gen_reg_rtx (XFmode);
15942 rtx op1 = gen_reg_rtx (XFmode);
15944 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15945 ix86_emit_i387_log1p (op0, op1);
15946 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15950 (define_expand "log1pdf2"
15951 [(use (match_operand:DF 0 "register_operand" ""))
15952 (use (match_operand:DF 1 "register_operand" ""))]
15953 "TARGET_USE_FANCY_MATH_387
15954 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15955 && flag_unsafe_math_optimizations"
15957 rtx op0 = gen_reg_rtx (XFmode);
15958 rtx op1 = gen_reg_rtx (XFmode);
15960 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15961 ix86_emit_i387_log1p (op0, op1);
15962 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15966 (define_expand "log1pxf2"
15967 [(use (match_operand:XF 0 "register_operand" ""))
15968 (use (match_operand:XF 1 "register_operand" ""))]
15969 "TARGET_USE_FANCY_MATH_387
15970 && flag_unsafe_math_optimizations"
15972 ix86_emit_i387_log1p (operands[0], operands[1]);
15976 (define_insn "*fxtractxf3"
15977 [(set (match_operand:XF 0 "register_operand" "=f")
15978 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15979 UNSPEC_XTRACT_FRACT))
15980 (set (match_operand:XF 1 "register_operand" "=u")
15981 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15982 "TARGET_USE_FANCY_MATH_387
15983 && flag_unsafe_math_optimizations"
15985 [(set_attr "type" "fpspc")
15986 (set_attr "mode" "XF")])
15988 (define_expand "logbsf2"
15989 [(set (match_dup 2)
15990 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15991 (parallel [(set (match_dup 3)
15992 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15994 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15995 (set (match_operand:SF 0 "register_operand" "")
15996 (float_truncate:SF (match_dup 4)))]
15997 "TARGET_USE_FANCY_MATH_387
15998 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15999 && flag_unsafe_math_optimizations"
16001 operands[2] = gen_reg_rtx (XFmode);
16002 operands[3] = gen_reg_rtx (XFmode);
16003 operands[4] = gen_reg_rtx (XFmode);
16006 (define_expand "logbdf2"
16007 [(set (match_dup 2)
16008 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16009 (parallel [(set (match_dup 3)
16010 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16012 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16013 (set (match_operand:DF 0 "register_operand" "")
16014 (float_truncate:DF (match_dup 4)))]
16015 "TARGET_USE_FANCY_MATH_387
16016 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16017 && flag_unsafe_math_optimizations"
16019 operands[2] = gen_reg_rtx (XFmode);
16020 operands[3] = gen_reg_rtx (XFmode);
16021 operands[4] = gen_reg_rtx (XFmode);
16024 (define_expand "logbxf2"
16025 [(parallel [(set (match_dup 2)
16026 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16027 UNSPEC_XTRACT_FRACT))
16028 (set (match_operand:XF 0 "register_operand" "")
16029 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16030 "TARGET_USE_FANCY_MATH_387
16031 && flag_unsafe_math_optimizations"
16033 operands[2] = gen_reg_rtx (XFmode);
16036 (define_expand "ilogbsi2"
16037 [(parallel [(set (match_dup 2)
16038 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16039 UNSPEC_XTRACT_FRACT))
16040 (set (match_operand:XF 3 "register_operand" "")
16041 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16042 (parallel [(set (match_operand:SI 0 "register_operand" "")
16043 (fix:SI (match_dup 3)))
16044 (clobber (reg:CC FLAGS_REG))])]
16045 "TARGET_USE_FANCY_MATH_387
16046 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16047 && flag_unsafe_math_optimizations"
16049 operands[2] = gen_reg_rtx (XFmode);
16050 operands[3] = gen_reg_rtx (XFmode);
16053 (define_insn "*f2xm1xf2"
16054 [(set (match_operand:XF 0 "register_operand" "=f")
16055 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16057 "TARGET_USE_FANCY_MATH_387
16058 && flag_unsafe_math_optimizations"
16060 [(set_attr "type" "fpspc")
16061 (set_attr "mode" "XF")])
16063 (define_insn "*fscalexf4"
16064 [(set (match_operand:XF 0 "register_operand" "=f")
16065 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16066 (match_operand:XF 3 "register_operand" "1")]
16067 UNSPEC_FSCALE_FRACT))
16068 (set (match_operand:XF 1 "register_operand" "=u")
16069 (unspec:XF [(match_dup 2) (match_dup 3)]
16070 UNSPEC_FSCALE_EXP))]
16071 "TARGET_USE_FANCY_MATH_387
16072 && flag_unsafe_math_optimizations"
16074 [(set_attr "type" "fpspc")
16075 (set_attr "mode" "XF")])
16077 (define_expand "expsf2"
16078 [(set (match_dup 2)
16079 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16080 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16081 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16082 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16083 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16084 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16085 (parallel [(set (match_dup 10)
16086 (unspec:XF [(match_dup 9) (match_dup 5)]
16087 UNSPEC_FSCALE_FRACT))
16088 (set (match_dup 11)
16089 (unspec:XF [(match_dup 9) (match_dup 5)]
16090 UNSPEC_FSCALE_EXP))])
16091 (set (match_operand:SF 0 "register_operand" "")
16092 (float_truncate:SF (match_dup 10)))]
16093 "TARGET_USE_FANCY_MATH_387
16094 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16095 && flag_unsafe_math_optimizations"
16100 for (i=2; i<12; i++)
16101 operands[i] = gen_reg_rtx (XFmode);
16102 temp = standard_80387_constant_rtx (5); /* fldl2e */
16103 emit_move_insn (operands[3], temp);
16104 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16107 (define_expand "expdf2"
16108 [(set (match_dup 2)
16109 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16110 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16111 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16112 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16113 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16114 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16115 (parallel [(set (match_dup 10)
16116 (unspec:XF [(match_dup 9) (match_dup 5)]
16117 UNSPEC_FSCALE_FRACT))
16118 (set (match_dup 11)
16119 (unspec:XF [(match_dup 9) (match_dup 5)]
16120 UNSPEC_FSCALE_EXP))])
16121 (set (match_operand:DF 0 "register_operand" "")
16122 (float_truncate:DF (match_dup 10)))]
16123 "TARGET_USE_FANCY_MATH_387
16124 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16125 && flag_unsafe_math_optimizations"
16130 for (i=2; i<12; i++)
16131 operands[i] = gen_reg_rtx (XFmode);
16132 temp = standard_80387_constant_rtx (5); /* fldl2e */
16133 emit_move_insn (operands[3], temp);
16134 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16137 (define_expand "expxf2"
16138 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16140 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16141 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16142 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16143 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16144 (parallel [(set (match_operand:XF 0 "register_operand" "")
16145 (unspec:XF [(match_dup 8) (match_dup 4)]
16146 UNSPEC_FSCALE_FRACT))
16148 (unspec:XF [(match_dup 8) (match_dup 4)]
16149 UNSPEC_FSCALE_EXP))])]
16150 "TARGET_USE_FANCY_MATH_387
16151 && flag_unsafe_math_optimizations"
16156 for (i=2; i<10; i++)
16157 operands[i] = gen_reg_rtx (XFmode);
16158 temp = standard_80387_constant_rtx (5); /* fldl2e */
16159 emit_move_insn (operands[2], temp);
16160 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16163 (define_expand "exp10sf2"
16164 [(set (match_dup 2)
16165 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16166 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16167 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16168 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16169 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16170 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16171 (parallel [(set (match_dup 10)
16172 (unspec:XF [(match_dup 9) (match_dup 5)]
16173 UNSPEC_FSCALE_FRACT))
16174 (set (match_dup 11)
16175 (unspec:XF [(match_dup 9) (match_dup 5)]
16176 UNSPEC_FSCALE_EXP))])
16177 (set (match_operand:SF 0 "register_operand" "")
16178 (float_truncate:SF (match_dup 10)))]
16179 "TARGET_USE_FANCY_MATH_387
16180 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16181 && flag_unsafe_math_optimizations"
16186 for (i=2; i<12; i++)
16187 operands[i] = gen_reg_rtx (XFmode);
16188 temp = standard_80387_constant_rtx (6); /* fldl2t */
16189 emit_move_insn (operands[3], temp);
16190 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16193 (define_expand "exp10df2"
16194 [(set (match_dup 2)
16195 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16196 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16197 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16198 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16199 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16200 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16201 (parallel [(set (match_dup 10)
16202 (unspec:XF [(match_dup 9) (match_dup 5)]
16203 UNSPEC_FSCALE_FRACT))
16204 (set (match_dup 11)
16205 (unspec:XF [(match_dup 9) (match_dup 5)]
16206 UNSPEC_FSCALE_EXP))])
16207 (set (match_operand:DF 0 "register_operand" "")
16208 (float_truncate:DF (match_dup 10)))]
16209 "TARGET_USE_FANCY_MATH_387
16210 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16211 && flag_unsafe_math_optimizations"
16216 for (i=2; i<12; i++)
16217 operands[i] = gen_reg_rtx (XFmode);
16218 temp = standard_80387_constant_rtx (6); /* fldl2t */
16219 emit_move_insn (operands[3], temp);
16220 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16223 (define_expand "exp10xf2"
16224 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16226 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16227 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16228 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16229 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16230 (parallel [(set (match_operand:XF 0 "register_operand" "")
16231 (unspec:XF [(match_dup 8) (match_dup 4)]
16232 UNSPEC_FSCALE_FRACT))
16234 (unspec:XF [(match_dup 8) (match_dup 4)]
16235 UNSPEC_FSCALE_EXP))])]
16236 "TARGET_USE_FANCY_MATH_387
16237 && flag_unsafe_math_optimizations"
16242 for (i=2; i<10; i++)
16243 operands[i] = gen_reg_rtx (XFmode);
16244 temp = standard_80387_constant_rtx (6); /* fldl2t */
16245 emit_move_insn (operands[2], temp);
16246 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16249 (define_expand "exp2sf2"
16250 [(set (match_dup 2)
16251 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16252 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16253 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16254 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16255 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16256 (parallel [(set (match_dup 8)
16257 (unspec:XF [(match_dup 7) (match_dup 3)]
16258 UNSPEC_FSCALE_FRACT))
16260 (unspec:XF [(match_dup 7) (match_dup 3)]
16261 UNSPEC_FSCALE_EXP))])
16262 (set (match_operand:SF 0 "register_operand" "")
16263 (float_truncate:SF (match_dup 8)))]
16264 "TARGET_USE_FANCY_MATH_387
16265 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16266 && flag_unsafe_math_optimizations"
16270 for (i=2; i<10; i++)
16271 operands[i] = gen_reg_rtx (XFmode);
16272 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16275 (define_expand "exp2df2"
16276 [(set (match_dup 2)
16277 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16278 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16279 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16280 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16281 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16282 (parallel [(set (match_dup 8)
16283 (unspec:XF [(match_dup 7) (match_dup 3)]
16284 UNSPEC_FSCALE_FRACT))
16286 (unspec:XF [(match_dup 7) (match_dup 3)]
16287 UNSPEC_FSCALE_EXP))])
16288 (set (match_operand:DF 0 "register_operand" "")
16289 (float_truncate:DF (match_dup 8)))]
16290 "TARGET_USE_FANCY_MATH_387
16291 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16292 && flag_unsafe_math_optimizations"
16296 for (i=2; i<10; i++)
16297 operands[i] = gen_reg_rtx (XFmode);
16298 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16301 (define_expand "exp2xf2"
16302 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16303 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16304 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16305 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16306 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16307 (parallel [(set (match_operand:XF 0 "register_operand" "")
16308 (unspec:XF [(match_dup 7) (match_dup 3)]
16309 UNSPEC_FSCALE_FRACT))
16311 (unspec:XF [(match_dup 7) (match_dup 3)]
16312 UNSPEC_FSCALE_EXP))])]
16313 "TARGET_USE_FANCY_MATH_387
16314 && flag_unsafe_math_optimizations"
16318 for (i=2; i<9; i++)
16319 operands[i] = gen_reg_rtx (XFmode);
16320 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16323 (define_expand "expm1df2"
16324 [(set (match_dup 2)
16325 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16326 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16327 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16328 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16329 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16330 (parallel [(set (match_dup 8)
16331 (unspec:XF [(match_dup 7) (match_dup 5)]
16332 UNSPEC_FSCALE_FRACT))
16334 (unspec:XF [(match_dup 7) (match_dup 5)]
16335 UNSPEC_FSCALE_EXP))])
16336 (parallel [(set (match_dup 11)
16337 (unspec:XF [(match_dup 10) (match_dup 9)]
16338 UNSPEC_FSCALE_FRACT))
16339 (set (match_dup 12)
16340 (unspec:XF [(match_dup 10) (match_dup 9)]
16341 UNSPEC_FSCALE_EXP))])
16342 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16343 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16344 (set (match_operand:DF 0 "register_operand" "")
16345 (float_truncate:DF (match_dup 14)))]
16346 "TARGET_USE_FANCY_MATH_387
16347 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
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_USE_FANCY_MATH_387
16384 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16385 && flag_unsafe_math_optimizations"
16390 for (i=2; i<15; i++)
16391 operands[i] = gen_reg_rtx (XFmode);
16392 temp = standard_80387_constant_rtx (5); /* fldl2e */
16393 emit_move_insn (operands[3], temp);
16394 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16397 (define_expand "expm1xf2"
16398 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16400 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16401 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16402 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16403 (parallel [(set (match_dup 7)
16404 (unspec:XF [(match_dup 6) (match_dup 4)]
16405 UNSPEC_FSCALE_FRACT))
16407 (unspec:XF [(match_dup 6) (match_dup 4)]
16408 UNSPEC_FSCALE_EXP))])
16409 (parallel [(set (match_dup 10)
16410 (unspec:XF [(match_dup 9) (match_dup 8)]
16411 UNSPEC_FSCALE_FRACT))
16412 (set (match_dup 11)
16413 (unspec:XF [(match_dup 9) (match_dup 8)]
16414 UNSPEC_FSCALE_EXP))])
16415 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16416 (set (match_operand:XF 0 "register_operand" "")
16417 (plus:XF (match_dup 12) (match_dup 7)))]
16418 "TARGET_USE_FANCY_MATH_387
16419 && flag_unsafe_math_optimizations"
16424 for (i=2; i<13; i++)
16425 operands[i] = gen_reg_rtx (XFmode);
16426 temp = standard_80387_constant_rtx (5); /* fldl2e */
16427 emit_move_insn (operands[2], temp);
16428 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16431 (define_expand "ldexpdf3"
16432 [(set (match_dup 3)
16433 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16435 (float:XF (match_operand:SI 2 "register_operand" "")))
16436 (parallel [(set (match_dup 5)
16437 (unspec:XF [(match_dup 3) (match_dup 4)]
16438 UNSPEC_FSCALE_FRACT))
16440 (unspec:XF [(match_dup 3) (match_dup 4)]
16441 UNSPEC_FSCALE_EXP))])
16442 (set (match_operand:DF 0 "register_operand" "")
16443 (float_truncate:DF (match_dup 5)))]
16444 "TARGET_USE_FANCY_MATH_387
16445 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16446 && flag_unsafe_math_optimizations"
16450 for (i=3; i<7; i++)
16451 operands[i] = gen_reg_rtx (XFmode);
16454 (define_expand "ldexpsf3"
16455 [(set (match_dup 3)
16456 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16458 (float:XF (match_operand:SI 2 "register_operand" "")))
16459 (parallel [(set (match_dup 5)
16460 (unspec:XF [(match_dup 3) (match_dup 4)]
16461 UNSPEC_FSCALE_FRACT))
16463 (unspec:XF [(match_dup 3) (match_dup 4)]
16464 UNSPEC_FSCALE_EXP))])
16465 (set (match_operand:SF 0 "register_operand" "")
16466 (float_truncate:SF (match_dup 5)))]
16467 "TARGET_USE_FANCY_MATH_387
16468 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16469 && flag_unsafe_math_optimizations"
16473 for (i=3; i<7; i++)
16474 operands[i] = gen_reg_rtx (XFmode);
16477 (define_expand "ldexpxf3"
16478 [(set (match_dup 3)
16479 (float:XF (match_operand:SI 2 "register_operand" "")))
16480 (parallel [(set (match_operand:XF 0 " register_operand" "")
16481 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16483 UNSPEC_FSCALE_FRACT))
16485 (unspec:XF [(match_dup 1) (match_dup 3)]
16486 UNSPEC_FSCALE_EXP))])]
16487 "TARGET_USE_FANCY_MATH_387
16488 && flag_unsafe_math_optimizations"
16492 for (i=3; i<5; i++)
16493 operands[i] = gen_reg_rtx (XFmode);
16497 (define_insn "frndintxf2"
16498 [(set (match_operand:XF 0 "register_operand" "=f")
16499 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16501 "TARGET_USE_FANCY_MATH_387
16502 && flag_unsafe_math_optimizations"
16504 [(set_attr "type" "fpspc")
16505 (set_attr "mode" "XF")])
16507 (define_expand "rintdf2"
16508 [(use (match_operand:DF 0 "register_operand" ""))
16509 (use (match_operand:DF 1 "register_operand" ""))]
16510 "TARGET_USE_FANCY_MATH_387
16511 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16512 && flag_unsafe_math_optimizations"
16514 rtx op0 = gen_reg_rtx (XFmode);
16515 rtx op1 = gen_reg_rtx (XFmode);
16517 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16518 emit_insn (gen_frndintxf2 (op0, op1));
16520 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16524 (define_expand "rintsf2"
16525 [(use (match_operand:SF 0 "register_operand" ""))
16526 (use (match_operand:SF 1 "register_operand" ""))]
16527 "TARGET_USE_FANCY_MATH_387
16528 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16529 && flag_unsafe_math_optimizations"
16531 rtx op0 = gen_reg_rtx (XFmode);
16532 rtx op1 = gen_reg_rtx (XFmode);
16534 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16535 emit_insn (gen_frndintxf2 (op0, op1));
16537 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16541 (define_expand "rintxf2"
16542 [(use (match_operand:XF 0 "register_operand" ""))
16543 (use (match_operand:XF 1 "register_operand" ""))]
16544 "TARGET_USE_FANCY_MATH_387
16545 && flag_unsafe_math_optimizations"
16547 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16551 (define_insn_and_split "*fistdi2_1"
16552 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16553 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16555 "TARGET_USE_FANCY_MATH_387
16556 && flag_unsafe_math_optimizations
16557 && !(reload_completed || reload_in_progress)"
16562 if (memory_operand (operands[0], VOIDmode))
16563 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16566 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16567 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16572 [(set_attr "type" "fpspc")
16573 (set_attr "mode" "DI")])
16575 (define_insn "fistdi2"
16576 [(set (match_operand:DI 0 "memory_operand" "=m")
16577 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16579 (clobber (match_scratch:XF 2 "=&1f"))]
16580 "TARGET_USE_FANCY_MATH_387
16581 && flag_unsafe_math_optimizations"
16582 "* return output_fix_trunc (insn, operands, 0);"
16583 [(set_attr "type" "fpspc")
16584 (set_attr "mode" "DI")])
16586 (define_insn "fistdi2_with_temp"
16587 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16588 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16590 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16591 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16592 "TARGET_USE_FANCY_MATH_387
16593 && flag_unsafe_math_optimizations"
16595 [(set_attr "type" "fpspc")
16596 (set_attr "mode" "DI")])
16599 [(set (match_operand:DI 0 "register_operand" "")
16600 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16602 (clobber (match_operand:DI 2 "memory_operand" ""))
16603 (clobber (match_scratch 3 ""))]
16605 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16606 (clobber (match_dup 3))])
16607 (set (match_dup 0) (match_dup 2))]
16611 [(set (match_operand:DI 0 "memory_operand" "")
16612 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16614 (clobber (match_operand:DI 2 "memory_operand" ""))
16615 (clobber (match_scratch 3 ""))]
16617 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16618 (clobber (match_dup 3))])]
16621 (define_insn_and_split "*fist<mode>2_1"
16622 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16623 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16625 "TARGET_USE_FANCY_MATH_387
16626 && flag_unsafe_math_optimizations
16627 && !(reload_completed || reload_in_progress)"
16632 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16633 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16637 [(set_attr "type" "fpspc")
16638 (set_attr "mode" "<MODE>")])
16640 (define_insn "fist<mode>2"
16641 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16642 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16644 "TARGET_USE_FANCY_MATH_387
16645 && flag_unsafe_math_optimizations"
16646 "* return output_fix_trunc (insn, operands, 0);"
16647 [(set_attr "type" "fpspc")
16648 (set_attr "mode" "<MODE>")])
16650 (define_insn "fist<mode>2_with_temp"
16651 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16652 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16654 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16655 "TARGET_USE_FANCY_MATH_387
16656 && flag_unsafe_math_optimizations"
16658 [(set_attr "type" "fpspc")
16659 (set_attr "mode" "<MODE>")])
16662 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16663 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16665 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16667 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16669 (set (match_dup 0) (match_dup 2))]
16673 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16674 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16676 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16678 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16682 (define_expand "lrint<mode>2"
16683 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16684 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16686 "TARGET_USE_FANCY_MATH_387
16687 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16688 && flag_unsafe_math_optimizations"
16691 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16692 (define_insn_and_split "frndintxf2_floor"
16693 [(set (match_operand:XF 0 "register_operand" "=f")
16694 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16695 UNSPEC_FRNDINT_FLOOR))
16696 (clobber (reg:CC FLAGS_REG))]
16697 "TARGET_USE_FANCY_MATH_387
16698 && flag_unsafe_math_optimizations
16699 && !(reload_completed || reload_in_progress)"
16704 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16706 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16707 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16709 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16710 operands[2], operands[3]));
16713 [(set_attr "type" "frndint")
16714 (set_attr "i387_cw" "floor")
16715 (set_attr "mode" "XF")])
16717 (define_insn "frndintxf2_floor_i387"
16718 [(set (match_operand:XF 0 "register_operand" "=f")
16719 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16720 UNSPEC_FRNDINT_FLOOR))
16721 (use (match_operand:HI 2 "memory_operand" "m"))
16722 (use (match_operand:HI 3 "memory_operand" "m"))]
16723 "TARGET_USE_FANCY_MATH_387
16724 && flag_unsafe_math_optimizations"
16725 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16726 [(set_attr "type" "frndint")
16727 (set_attr "i387_cw" "floor")
16728 (set_attr "mode" "XF")])
16730 (define_expand "floorxf2"
16731 [(use (match_operand:XF 0 "register_operand" ""))
16732 (use (match_operand:XF 1 "register_operand" ""))]
16733 "TARGET_USE_FANCY_MATH_387
16734 && flag_unsafe_math_optimizations"
16736 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16740 (define_expand "floordf2"
16741 [(use (match_operand:DF 0 "register_operand" ""))
16742 (use (match_operand:DF 1 "register_operand" ""))]
16743 "TARGET_USE_FANCY_MATH_387
16744 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16745 && flag_unsafe_math_optimizations"
16747 rtx op0 = gen_reg_rtx (XFmode);
16748 rtx op1 = gen_reg_rtx (XFmode);
16750 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16751 emit_insn (gen_frndintxf2_floor (op0, op1));
16753 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16757 (define_expand "floorsf2"
16758 [(use (match_operand:SF 0 "register_operand" ""))
16759 (use (match_operand:SF 1 "register_operand" ""))]
16760 "TARGET_USE_FANCY_MATH_387
16761 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16762 && flag_unsafe_math_optimizations"
16764 rtx op0 = gen_reg_rtx (XFmode);
16765 rtx op1 = gen_reg_rtx (XFmode);
16767 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16768 emit_insn (gen_frndintxf2_floor (op0, op1));
16770 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16774 (define_insn_and_split "*fist<mode>2_floor_1"
16775 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16776 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16777 UNSPEC_FIST_FLOOR))
16778 (clobber (reg:CC FLAGS_REG))]
16779 "TARGET_USE_FANCY_MATH_387
16780 && flag_unsafe_math_optimizations
16781 && !(reload_completed || reload_in_progress)"
16786 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16788 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16789 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16790 if (memory_operand (operands[0], VOIDmode))
16791 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16792 operands[2], operands[3]));
16795 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16796 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16797 operands[2], operands[3],
16802 [(set_attr "type" "fistp")
16803 (set_attr "i387_cw" "floor")
16804 (set_attr "mode" "<MODE>")])
16806 (define_insn "fistdi2_floor"
16807 [(set (match_operand:DI 0 "memory_operand" "=m")
16808 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16809 UNSPEC_FIST_FLOOR))
16810 (use (match_operand:HI 2 "memory_operand" "m"))
16811 (use (match_operand:HI 3 "memory_operand" "m"))
16812 (clobber (match_scratch:XF 4 "=&1f"))]
16813 "TARGET_USE_FANCY_MATH_387
16814 && flag_unsafe_math_optimizations"
16815 "* return output_fix_trunc (insn, operands, 0);"
16816 [(set_attr "type" "fistp")
16817 (set_attr "i387_cw" "floor")
16818 (set_attr "mode" "DI")])
16820 (define_insn "fistdi2_floor_with_temp"
16821 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16822 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16823 UNSPEC_FIST_FLOOR))
16824 (use (match_operand:HI 2 "memory_operand" "m,m"))
16825 (use (match_operand:HI 3 "memory_operand" "m,m"))
16826 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16827 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16828 "TARGET_USE_FANCY_MATH_387
16829 && flag_unsafe_math_optimizations"
16831 [(set_attr "type" "fistp")
16832 (set_attr "i387_cw" "floor")
16833 (set_attr "mode" "DI")])
16836 [(set (match_operand:DI 0 "register_operand" "")
16837 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16838 UNSPEC_FIST_FLOOR))
16839 (use (match_operand:HI 2 "memory_operand" ""))
16840 (use (match_operand:HI 3 "memory_operand" ""))
16841 (clobber (match_operand:DI 4 "memory_operand" ""))
16842 (clobber (match_scratch 5 ""))]
16844 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16845 (use (match_dup 2))
16846 (use (match_dup 3))
16847 (clobber (match_dup 5))])
16848 (set (match_dup 0) (match_dup 4))]
16852 [(set (match_operand:DI 0 "memory_operand" "")
16853 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16854 UNSPEC_FIST_FLOOR))
16855 (use (match_operand:HI 2 "memory_operand" ""))
16856 (use (match_operand:HI 3 "memory_operand" ""))
16857 (clobber (match_operand:DI 4 "memory_operand" ""))
16858 (clobber (match_scratch 5 ""))]
16860 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16861 (use (match_dup 2))
16862 (use (match_dup 3))
16863 (clobber (match_dup 5))])]
16866 (define_insn "fist<mode>2_floor"
16867 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16868 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16869 UNSPEC_FIST_FLOOR))
16870 (use (match_operand:HI 2 "memory_operand" "m"))
16871 (use (match_operand:HI 3 "memory_operand" "m"))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && flag_unsafe_math_optimizations"
16874 "* return output_fix_trunc (insn, operands, 0);"
16875 [(set_attr "type" "fistp")
16876 (set_attr "i387_cw" "floor")
16877 (set_attr "mode" "<MODE>")])
16879 (define_insn "fist<mode>2_floor_with_temp"
16880 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16881 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16882 UNSPEC_FIST_FLOOR))
16883 (use (match_operand:HI 2 "memory_operand" "m,m"))
16884 (use (match_operand:HI 3 "memory_operand" "m,m"))
16885 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16886 "TARGET_USE_FANCY_MATH_387
16887 && flag_unsafe_math_optimizations"
16889 [(set_attr "type" "fistp")
16890 (set_attr "i387_cw" "floor")
16891 (set_attr "mode" "<MODE>")])
16894 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16895 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16896 UNSPEC_FIST_FLOOR))
16897 (use (match_operand:HI 2 "memory_operand" ""))
16898 (use (match_operand:HI 3 "memory_operand" ""))
16899 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16901 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16902 UNSPEC_FIST_FLOOR))
16903 (use (match_dup 2))
16904 (use (match_dup 3))])
16905 (set (match_dup 0) (match_dup 4))]
16909 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16910 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16911 UNSPEC_FIST_FLOOR))
16912 (use (match_operand:HI 2 "memory_operand" ""))
16913 (use (match_operand:HI 3 "memory_operand" ""))
16914 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16916 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16917 UNSPEC_FIST_FLOOR))
16918 (use (match_dup 2))
16919 (use (match_dup 3))])]
16922 (define_expand "lfloor<mode>2"
16923 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16924 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16925 UNSPEC_FIST_FLOOR))
16926 (clobber (reg:CC FLAGS_REG))])]
16927 "TARGET_USE_FANCY_MATH_387
16928 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16929 && flag_unsafe_math_optimizations"
16932 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16933 (define_insn_and_split "frndintxf2_ceil"
16934 [(set (match_operand:XF 0 "register_operand" "=f")
16935 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16936 UNSPEC_FRNDINT_CEIL))
16937 (clobber (reg:CC FLAGS_REG))]
16938 "TARGET_USE_FANCY_MATH_387
16939 && flag_unsafe_math_optimizations
16940 && !(reload_completed || reload_in_progress)"
16945 ix86_optimize_mode_switching[I387_CEIL] = 1;
16947 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16948 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16950 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16951 operands[2], operands[3]));
16954 [(set_attr "type" "frndint")
16955 (set_attr "i387_cw" "ceil")
16956 (set_attr "mode" "XF")])
16958 (define_insn "frndintxf2_ceil_i387"
16959 [(set (match_operand:XF 0 "register_operand" "=f")
16960 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16961 UNSPEC_FRNDINT_CEIL))
16962 (use (match_operand:HI 2 "memory_operand" "m"))
16963 (use (match_operand:HI 3 "memory_operand" "m"))]
16964 "TARGET_USE_FANCY_MATH_387
16965 && flag_unsafe_math_optimizations"
16966 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16967 [(set_attr "type" "frndint")
16968 (set_attr "i387_cw" "ceil")
16969 (set_attr "mode" "XF")])
16971 (define_expand "ceilxf2"
16972 [(use (match_operand:XF 0 "register_operand" ""))
16973 (use (match_operand:XF 1 "register_operand" ""))]
16974 "TARGET_USE_FANCY_MATH_387
16975 && flag_unsafe_math_optimizations"
16977 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16981 (define_expand "ceildf2"
16982 [(use (match_operand:DF 0 "register_operand" ""))
16983 (use (match_operand:DF 1 "register_operand" ""))]
16984 "TARGET_USE_FANCY_MATH_387
16985 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16986 && flag_unsafe_math_optimizations"
16988 rtx op0 = gen_reg_rtx (XFmode);
16989 rtx op1 = gen_reg_rtx (XFmode);
16991 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16992 emit_insn (gen_frndintxf2_ceil (op0, op1));
16994 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16998 (define_expand "ceilsf2"
16999 [(use (match_operand:SF 0 "register_operand" ""))
17000 (use (match_operand:SF 1 "register_operand" ""))]
17001 "TARGET_USE_FANCY_MATH_387
17002 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17003 && flag_unsafe_math_optimizations"
17005 rtx op0 = gen_reg_rtx (XFmode);
17006 rtx op1 = gen_reg_rtx (XFmode);
17008 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17009 emit_insn (gen_frndintxf2_ceil (op0, op1));
17011 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17015 (define_insn_and_split "*fist<mode>2_ceil_1"
17016 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17017 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17019 (clobber (reg:CC FLAGS_REG))]
17020 "TARGET_USE_FANCY_MATH_387
17021 && flag_unsafe_math_optimizations
17022 && !(reload_completed || reload_in_progress)"
17027 ix86_optimize_mode_switching[I387_CEIL] = 1;
17029 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17030 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17031 if (memory_operand (operands[0], VOIDmode))
17032 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17033 operands[2], operands[3]));
17036 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17037 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17038 operands[2], operands[3],
17043 [(set_attr "type" "fistp")
17044 (set_attr "i387_cw" "ceil")
17045 (set_attr "mode" "<MODE>")])
17047 (define_insn "fistdi2_ceil"
17048 [(set (match_operand:DI 0 "memory_operand" "=m")
17049 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17051 (use (match_operand:HI 2 "memory_operand" "m"))
17052 (use (match_operand:HI 3 "memory_operand" "m"))
17053 (clobber (match_scratch:XF 4 "=&1f"))]
17054 "TARGET_USE_FANCY_MATH_387
17055 && flag_unsafe_math_optimizations"
17056 "* return output_fix_trunc (insn, operands, 0);"
17057 [(set_attr "type" "fistp")
17058 (set_attr "i387_cw" "ceil")
17059 (set_attr "mode" "DI")])
17061 (define_insn "fistdi2_ceil_with_temp"
17062 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17063 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17065 (use (match_operand:HI 2 "memory_operand" "m,m"))
17066 (use (match_operand:HI 3 "memory_operand" "m,m"))
17067 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17068 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17069 "TARGET_USE_FANCY_MATH_387
17070 && flag_unsafe_math_optimizations"
17072 [(set_attr "type" "fistp")
17073 (set_attr "i387_cw" "ceil")
17074 (set_attr "mode" "DI")])
17077 [(set (match_operand:DI 0 "register_operand" "")
17078 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17080 (use (match_operand:HI 2 "memory_operand" ""))
17081 (use (match_operand:HI 3 "memory_operand" ""))
17082 (clobber (match_operand:DI 4 "memory_operand" ""))
17083 (clobber (match_scratch 5 ""))]
17085 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17086 (use (match_dup 2))
17087 (use (match_dup 3))
17088 (clobber (match_dup 5))])
17089 (set (match_dup 0) (match_dup 4))]
17093 [(set (match_operand:DI 0 "memory_operand" "")
17094 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17096 (use (match_operand:HI 2 "memory_operand" ""))
17097 (use (match_operand:HI 3 "memory_operand" ""))
17098 (clobber (match_operand:DI 4 "memory_operand" ""))
17099 (clobber (match_scratch 5 ""))]
17101 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17102 (use (match_dup 2))
17103 (use (match_dup 3))
17104 (clobber (match_dup 5))])]
17107 (define_insn "fist<mode>2_ceil"
17108 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17109 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17111 (use (match_operand:HI 2 "memory_operand" "m"))
17112 (use (match_operand:HI 3 "memory_operand" "m"))]
17113 "TARGET_USE_FANCY_MATH_387
17114 && flag_unsafe_math_optimizations"
17115 "* return output_fix_trunc (insn, operands, 0);"
17116 [(set_attr "type" "fistp")
17117 (set_attr "i387_cw" "ceil")
17118 (set_attr "mode" "<MODE>")])
17120 (define_insn "fist<mode>2_ceil_with_temp"
17121 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17122 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17124 (use (match_operand:HI 2 "memory_operand" "m,m"))
17125 (use (match_operand:HI 3 "memory_operand" "m,m"))
17126 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17127 "TARGET_USE_FANCY_MATH_387
17128 && flag_unsafe_math_optimizations"
17130 [(set_attr "type" "fistp")
17131 (set_attr "i387_cw" "ceil")
17132 (set_attr "mode" "<MODE>")])
17135 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17136 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17138 (use (match_operand:HI 2 "memory_operand" ""))
17139 (use (match_operand:HI 3 "memory_operand" ""))
17140 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17142 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17144 (use (match_dup 2))
17145 (use (match_dup 3))])
17146 (set (match_dup 0) (match_dup 4))]
17150 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17151 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17153 (use (match_operand:HI 2 "memory_operand" ""))
17154 (use (match_operand:HI 3 "memory_operand" ""))
17155 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17157 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17159 (use (match_dup 2))
17160 (use (match_dup 3))])]
17163 (define_expand "lceil<mode>2"
17164 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17165 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17167 (clobber (reg:CC FLAGS_REG))])]
17168 "TARGET_USE_FANCY_MATH_387
17169 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17170 && flag_unsafe_math_optimizations"
17173 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17174 (define_insn_and_split "frndintxf2_trunc"
17175 [(set (match_operand:XF 0 "register_operand" "=f")
17176 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17177 UNSPEC_FRNDINT_TRUNC))
17178 (clobber (reg:CC FLAGS_REG))]
17179 "TARGET_USE_FANCY_MATH_387
17180 && flag_unsafe_math_optimizations
17181 && !(reload_completed || reload_in_progress)"
17186 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17188 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17189 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17191 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17192 operands[2], operands[3]));
17195 [(set_attr "type" "frndint")
17196 (set_attr "i387_cw" "trunc")
17197 (set_attr "mode" "XF")])
17199 (define_insn "frndintxf2_trunc_i387"
17200 [(set (match_operand:XF 0 "register_operand" "=f")
17201 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17202 UNSPEC_FRNDINT_TRUNC))
17203 (use (match_operand:HI 2 "memory_operand" "m"))
17204 (use (match_operand:HI 3 "memory_operand" "m"))]
17205 "TARGET_USE_FANCY_MATH_387
17206 && flag_unsafe_math_optimizations"
17207 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17208 [(set_attr "type" "frndint")
17209 (set_attr "i387_cw" "trunc")
17210 (set_attr "mode" "XF")])
17212 (define_expand "btruncxf2"
17213 [(use (match_operand:XF 0 "register_operand" ""))
17214 (use (match_operand:XF 1 "register_operand" ""))]
17215 "TARGET_USE_FANCY_MATH_387
17216 && flag_unsafe_math_optimizations"
17218 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17222 (define_expand "btruncdf2"
17223 [(use (match_operand:DF 0 "register_operand" ""))
17224 (use (match_operand:DF 1 "register_operand" ""))]
17225 "TARGET_USE_FANCY_MATH_387
17226 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17227 && flag_unsafe_math_optimizations"
17229 rtx op0 = gen_reg_rtx (XFmode);
17230 rtx op1 = gen_reg_rtx (XFmode);
17232 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17233 emit_insn (gen_frndintxf2_trunc (op0, op1));
17235 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17239 (define_expand "btruncsf2"
17240 [(use (match_operand:SF 0 "register_operand" ""))
17241 (use (match_operand:SF 1 "register_operand" ""))]
17242 "TARGET_USE_FANCY_MATH_387
17243 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17244 && flag_unsafe_math_optimizations"
17246 rtx op0 = gen_reg_rtx (XFmode);
17247 rtx op1 = gen_reg_rtx (XFmode);
17249 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17250 emit_insn (gen_frndintxf2_trunc (op0, op1));
17252 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17256 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17257 (define_insn_and_split "frndintxf2_mask_pm"
17258 [(set (match_operand:XF 0 "register_operand" "=f")
17259 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17260 UNSPEC_FRNDINT_MASK_PM))
17261 (clobber (reg:CC FLAGS_REG))]
17262 "TARGET_USE_FANCY_MATH_387
17263 && flag_unsafe_math_optimizations
17264 && !(reload_completed || reload_in_progress)"
17269 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17271 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17272 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17274 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17275 operands[2], operands[3]));
17278 [(set_attr "type" "frndint")
17279 (set_attr "i387_cw" "mask_pm")
17280 (set_attr "mode" "XF")])
17282 (define_insn "frndintxf2_mask_pm_i387"
17283 [(set (match_operand:XF 0 "register_operand" "=f")
17284 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17285 UNSPEC_FRNDINT_MASK_PM))
17286 (use (match_operand:HI 2 "memory_operand" "m"))
17287 (use (match_operand:HI 3 "memory_operand" "m"))]
17288 "TARGET_USE_FANCY_MATH_387
17289 && flag_unsafe_math_optimizations"
17290 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17291 [(set_attr "type" "frndint")
17292 (set_attr "i387_cw" "mask_pm")
17293 (set_attr "mode" "XF")])
17295 (define_expand "nearbyintxf2"
17296 [(use (match_operand:XF 0 "register_operand" ""))
17297 (use (match_operand:XF 1 "register_operand" ""))]
17298 "TARGET_USE_FANCY_MATH_387
17299 && flag_unsafe_math_optimizations"
17301 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17306 (define_expand "nearbyintdf2"
17307 [(use (match_operand:DF 0 "register_operand" ""))
17308 (use (match_operand:DF 1 "register_operand" ""))]
17309 "TARGET_USE_FANCY_MATH_387
17310 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17311 && flag_unsafe_math_optimizations"
17313 rtx op0 = gen_reg_rtx (XFmode);
17314 rtx op1 = gen_reg_rtx (XFmode);
17316 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17317 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17319 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17323 (define_expand "nearbyintsf2"
17324 [(use (match_operand:SF 0 "register_operand" ""))
17325 (use (match_operand:SF 1 "register_operand" ""))]
17326 "TARGET_USE_FANCY_MATH_387
17327 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17328 && flag_unsafe_math_optimizations"
17330 rtx op0 = gen_reg_rtx (XFmode);
17331 rtx op1 = gen_reg_rtx (XFmode);
17333 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17334 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17336 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17341 ;; Block operation instructions
17344 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17347 [(set_attr "type" "cld")])
17349 (define_expand "movmemsi"
17350 [(use (match_operand:BLK 0 "memory_operand" ""))
17351 (use (match_operand:BLK 1 "memory_operand" ""))
17352 (use (match_operand:SI 2 "nonmemory_operand" ""))
17353 (use (match_operand:SI 3 "const_int_operand" ""))]
17354 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17356 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17362 (define_expand "movmemdi"
17363 [(use (match_operand:BLK 0 "memory_operand" ""))
17364 (use (match_operand:BLK 1 "memory_operand" ""))
17365 (use (match_operand:DI 2 "nonmemory_operand" ""))
17366 (use (match_operand:DI 3 "const_int_operand" ""))]
17369 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17375 ;; Most CPUs don't like single string operations
17376 ;; Handle this case here to simplify previous expander.
17378 (define_expand "strmov"
17379 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17380 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17381 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17382 (clobber (reg:CC FLAGS_REG))])
17383 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17384 (clobber (reg:CC FLAGS_REG))])]
17387 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17389 /* If .md ever supports :P for Pmode, these can be directly
17390 in the pattern above. */
17391 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17392 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17394 if (TARGET_SINGLE_STRINGOP || optimize_size)
17396 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17397 operands[2], operands[3],
17398 operands[5], operands[6]));
17402 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17405 (define_expand "strmov_singleop"
17406 [(parallel [(set (match_operand 1 "memory_operand" "")
17407 (match_operand 3 "memory_operand" ""))
17408 (set (match_operand 0 "register_operand" "")
17409 (match_operand 4 "" ""))
17410 (set (match_operand 2 "register_operand" "")
17411 (match_operand 5 "" ""))
17412 (use (reg:SI DIRFLAG_REG))])]
17413 "TARGET_SINGLE_STRINGOP || optimize_size"
17416 (define_insn "*strmovdi_rex_1"
17417 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17418 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17419 (set (match_operand:DI 0 "register_operand" "=D")
17420 (plus:DI (match_dup 2)
17422 (set (match_operand:DI 1 "register_operand" "=S")
17423 (plus:DI (match_dup 3)
17425 (use (reg:SI DIRFLAG_REG))]
17426 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17428 [(set_attr "type" "str")
17429 (set_attr "mode" "DI")
17430 (set_attr "memory" "both")])
17432 (define_insn "*strmovsi_1"
17433 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17434 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17435 (set (match_operand:SI 0 "register_operand" "=D")
17436 (plus:SI (match_dup 2)
17438 (set (match_operand:SI 1 "register_operand" "=S")
17439 (plus:SI (match_dup 3)
17441 (use (reg:SI DIRFLAG_REG))]
17442 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17444 [(set_attr "type" "str")
17445 (set_attr "mode" "SI")
17446 (set_attr "memory" "both")])
17448 (define_insn "*strmovsi_rex_1"
17449 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17450 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17451 (set (match_operand:DI 0 "register_operand" "=D")
17452 (plus:DI (match_dup 2)
17454 (set (match_operand:DI 1 "register_operand" "=S")
17455 (plus:DI (match_dup 3)
17457 (use (reg:SI DIRFLAG_REG))]
17458 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17460 [(set_attr "type" "str")
17461 (set_attr "mode" "SI")
17462 (set_attr "memory" "both")])
17464 (define_insn "*strmovhi_1"
17465 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17466 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17467 (set (match_operand:SI 0 "register_operand" "=D")
17468 (plus:SI (match_dup 2)
17470 (set (match_operand:SI 1 "register_operand" "=S")
17471 (plus:SI (match_dup 3)
17473 (use (reg:SI DIRFLAG_REG))]
17474 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17476 [(set_attr "type" "str")
17477 (set_attr "memory" "both")
17478 (set_attr "mode" "HI")])
17480 (define_insn "*strmovhi_rex_1"
17481 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17482 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17483 (set (match_operand:DI 0 "register_operand" "=D")
17484 (plus:DI (match_dup 2)
17486 (set (match_operand:DI 1 "register_operand" "=S")
17487 (plus:DI (match_dup 3)
17489 (use (reg:SI DIRFLAG_REG))]
17490 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17492 [(set_attr "type" "str")
17493 (set_attr "memory" "both")
17494 (set_attr "mode" "HI")])
17496 (define_insn "*strmovqi_1"
17497 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17498 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17499 (set (match_operand:SI 0 "register_operand" "=D")
17500 (plus:SI (match_dup 2)
17502 (set (match_operand:SI 1 "register_operand" "=S")
17503 (plus:SI (match_dup 3)
17505 (use (reg:SI DIRFLAG_REG))]
17506 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17508 [(set_attr "type" "str")
17509 (set_attr "memory" "both")
17510 (set_attr "mode" "QI")])
17512 (define_insn "*strmovqi_rex_1"
17513 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17514 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17515 (set (match_operand:DI 0 "register_operand" "=D")
17516 (plus:DI (match_dup 2)
17518 (set (match_operand:DI 1 "register_operand" "=S")
17519 (plus:DI (match_dup 3)
17521 (use (reg:SI DIRFLAG_REG))]
17522 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17524 [(set_attr "type" "str")
17525 (set_attr "memory" "both")
17526 (set_attr "mode" "QI")])
17528 (define_expand "rep_mov"
17529 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17530 (set (match_operand 0 "register_operand" "")
17531 (match_operand 5 "" ""))
17532 (set (match_operand 2 "register_operand" "")
17533 (match_operand 6 "" ""))
17534 (set (match_operand 1 "memory_operand" "")
17535 (match_operand 3 "memory_operand" ""))
17536 (use (match_dup 4))
17537 (use (reg:SI DIRFLAG_REG))])]
17541 (define_insn "*rep_movdi_rex64"
17542 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17543 (set (match_operand:DI 0 "register_operand" "=D")
17544 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17546 (match_operand:DI 3 "register_operand" "0")))
17547 (set (match_operand:DI 1 "register_operand" "=S")
17548 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17549 (match_operand:DI 4 "register_operand" "1")))
17550 (set (mem:BLK (match_dup 3))
17551 (mem:BLK (match_dup 4)))
17552 (use (match_dup 5))
17553 (use (reg:SI DIRFLAG_REG))]
17555 "{rep\;movsq|rep movsq}"
17556 [(set_attr "type" "str")
17557 (set_attr "prefix_rep" "1")
17558 (set_attr "memory" "both")
17559 (set_attr "mode" "DI")])
17561 (define_insn "*rep_movsi"
17562 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17563 (set (match_operand:SI 0 "register_operand" "=D")
17564 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17566 (match_operand:SI 3 "register_operand" "0")))
17567 (set (match_operand:SI 1 "register_operand" "=S")
17568 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17569 (match_operand:SI 4 "register_operand" "1")))
17570 (set (mem:BLK (match_dup 3))
17571 (mem:BLK (match_dup 4)))
17572 (use (match_dup 5))
17573 (use (reg:SI DIRFLAG_REG))]
17575 "{rep\;movsl|rep movsd}"
17576 [(set_attr "type" "str")
17577 (set_attr "prefix_rep" "1")
17578 (set_attr "memory" "both")
17579 (set_attr "mode" "SI")])
17581 (define_insn "*rep_movsi_rex64"
17582 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17583 (set (match_operand:DI 0 "register_operand" "=D")
17584 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17586 (match_operand:DI 3 "register_operand" "0")))
17587 (set (match_operand:DI 1 "register_operand" "=S")
17588 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17589 (match_operand:DI 4 "register_operand" "1")))
17590 (set (mem:BLK (match_dup 3))
17591 (mem:BLK (match_dup 4)))
17592 (use (match_dup 5))
17593 (use (reg:SI DIRFLAG_REG))]
17595 "{rep\;movsl|rep movsd}"
17596 [(set_attr "type" "str")
17597 (set_attr "prefix_rep" "1")
17598 (set_attr "memory" "both")
17599 (set_attr "mode" "SI")])
17601 (define_insn "*rep_movqi"
17602 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17603 (set (match_operand:SI 0 "register_operand" "=D")
17604 (plus:SI (match_operand:SI 3 "register_operand" "0")
17605 (match_operand:SI 5 "register_operand" "2")))
17606 (set (match_operand:SI 1 "register_operand" "=S")
17607 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17608 (set (mem:BLK (match_dup 3))
17609 (mem:BLK (match_dup 4)))
17610 (use (match_dup 5))
17611 (use (reg:SI DIRFLAG_REG))]
17613 "{rep\;movsb|rep movsb}"
17614 [(set_attr "type" "str")
17615 (set_attr "prefix_rep" "1")
17616 (set_attr "memory" "both")
17617 (set_attr "mode" "SI")])
17619 (define_insn "*rep_movqi_rex64"
17620 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17621 (set (match_operand:DI 0 "register_operand" "=D")
17622 (plus:DI (match_operand:DI 3 "register_operand" "0")
17623 (match_operand:DI 5 "register_operand" "2")))
17624 (set (match_operand:DI 1 "register_operand" "=S")
17625 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17626 (set (mem:BLK (match_dup 3))
17627 (mem:BLK (match_dup 4)))
17628 (use (match_dup 5))
17629 (use (reg:SI DIRFLAG_REG))]
17631 "{rep\;movsb|rep movsb}"
17632 [(set_attr "type" "str")
17633 (set_attr "prefix_rep" "1")
17634 (set_attr "memory" "both")
17635 (set_attr "mode" "SI")])
17637 (define_expand "setmemsi"
17638 [(use (match_operand:BLK 0 "memory_operand" ""))
17639 (use (match_operand:SI 1 "nonmemory_operand" ""))
17640 (use (match_operand 2 "const_int_operand" ""))
17641 (use (match_operand 3 "const_int_operand" ""))]
17644 /* If value to set is not zero, use the library routine. */
17645 if (operands[2] != const0_rtx)
17648 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17654 (define_expand "setmemdi"
17655 [(use (match_operand:BLK 0 "memory_operand" ""))
17656 (use (match_operand:DI 1 "nonmemory_operand" ""))
17657 (use (match_operand 2 "const_int_operand" ""))
17658 (use (match_operand 3 "const_int_operand" ""))]
17661 /* If value to set is not zero, use the library routine. */
17662 if (operands[2] != const0_rtx)
17665 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17671 ;; Most CPUs don't like single string operations
17672 ;; Handle this case here to simplify previous expander.
17674 (define_expand "strset"
17675 [(set (match_operand 1 "memory_operand" "")
17676 (match_operand 2 "register_operand" ""))
17677 (parallel [(set (match_operand 0 "register_operand" "")
17679 (clobber (reg:CC FLAGS_REG))])]
17682 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17683 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17685 /* If .md ever supports :P for Pmode, this can be directly
17686 in the pattern above. */
17687 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17688 GEN_INT (GET_MODE_SIZE (GET_MODE
17690 if (TARGET_SINGLE_STRINGOP || optimize_size)
17692 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17698 (define_expand "strset_singleop"
17699 [(parallel [(set (match_operand 1 "memory_operand" "")
17700 (match_operand 2 "register_operand" ""))
17701 (set (match_operand 0 "register_operand" "")
17702 (match_operand 3 "" ""))
17703 (use (reg:SI DIRFLAG_REG))])]
17704 "TARGET_SINGLE_STRINGOP || optimize_size"
17707 (define_insn "*strsetdi_rex_1"
17708 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17709 (match_operand:DI 2 "register_operand" "a"))
17710 (set (match_operand:DI 0 "register_operand" "=D")
17711 (plus:DI (match_dup 1)
17713 (use (reg:SI DIRFLAG_REG))]
17714 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17716 [(set_attr "type" "str")
17717 (set_attr "memory" "store")
17718 (set_attr "mode" "DI")])
17720 (define_insn "*strsetsi_1"
17721 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17722 (match_operand:SI 2 "register_operand" "a"))
17723 (set (match_operand:SI 0 "register_operand" "=D")
17724 (plus:SI (match_dup 1)
17726 (use (reg:SI DIRFLAG_REG))]
17727 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17729 [(set_attr "type" "str")
17730 (set_attr "memory" "store")
17731 (set_attr "mode" "SI")])
17733 (define_insn "*strsetsi_rex_1"
17734 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17735 (match_operand:SI 2 "register_operand" "a"))
17736 (set (match_operand:DI 0 "register_operand" "=D")
17737 (plus:DI (match_dup 1)
17739 (use (reg:SI DIRFLAG_REG))]
17740 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17742 [(set_attr "type" "str")
17743 (set_attr "memory" "store")
17744 (set_attr "mode" "SI")])
17746 (define_insn "*strsethi_1"
17747 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17748 (match_operand:HI 2 "register_operand" "a"))
17749 (set (match_operand:SI 0 "register_operand" "=D")
17750 (plus:SI (match_dup 1)
17752 (use (reg:SI DIRFLAG_REG))]
17753 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17755 [(set_attr "type" "str")
17756 (set_attr "memory" "store")
17757 (set_attr "mode" "HI")])
17759 (define_insn "*strsethi_rex_1"
17760 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17761 (match_operand:HI 2 "register_operand" "a"))
17762 (set (match_operand:DI 0 "register_operand" "=D")
17763 (plus:DI (match_dup 1)
17765 (use (reg:SI DIRFLAG_REG))]
17766 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17768 [(set_attr "type" "str")
17769 (set_attr "memory" "store")
17770 (set_attr "mode" "HI")])
17772 (define_insn "*strsetqi_1"
17773 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17774 (match_operand:QI 2 "register_operand" "a"))
17775 (set (match_operand:SI 0 "register_operand" "=D")
17776 (plus:SI (match_dup 1)
17778 (use (reg:SI DIRFLAG_REG))]
17779 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17781 [(set_attr "type" "str")
17782 (set_attr "memory" "store")
17783 (set_attr "mode" "QI")])
17785 (define_insn "*strsetqi_rex_1"
17786 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17787 (match_operand:QI 2 "register_operand" "a"))
17788 (set (match_operand:DI 0 "register_operand" "=D")
17789 (plus:DI (match_dup 1)
17791 (use (reg:SI DIRFLAG_REG))]
17792 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17794 [(set_attr "type" "str")
17795 (set_attr "memory" "store")
17796 (set_attr "mode" "QI")])
17798 (define_expand "rep_stos"
17799 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17800 (set (match_operand 0 "register_operand" "")
17801 (match_operand 4 "" ""))
17802 (set (match_operand 2 "memory_operand" "") (const_int 0))
17803 (use (match_operand 3 "register_operand" ""))
17804 (use (match_dup 1))
17805 (use (reg:SI DIRFLAG_REG))])]
17809 (define_insn "*rep_stosdi_rex64"
17810 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17811 (set (match_operand:DI 0 "register_operand" "=D")
17812 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17814 (match_operand:DI 3 "register_operand" "0")))
17815 (set (mem:BLK (match_dup 3))
17817 (use (match_operand:DI 2 "register_operand" "a"))
17818 (use (match_dup 4))
17819 (use (reg:SI DIRFLAG_REG))]
17821 "{rep\;stosq|rep stosq}"
17822 [(set_attr "type" "str")
17823 (set_attr "prefix_rep" "1")
17824 (set_attr "memory" "store")
17825 (set_attr "mode" "DI")])
17827 (define_insn "*rep_stossi"
17828 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17829 (set (match_operand:SI 0 "register_operand" "=D")
17830 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17832 (match_operand:SI 3 "register_operand" "0")))
17833 (set (mem:BLK (match_dup 3))
17835 (use (match_operand:SI 2 "register_operand" "a"))
17836 (use (match_dup 4))
17837 (use (reg:SI DIRFLAG_REG))]
17839 "{rep\;stosl|rep stosd}"
17840 [(set_attr "type" "str")
17841 (set_attr "prefix_rep" "1")
17842 (set_attr "memory" "store")
17843 (set_attr "mode" "SI")])
17845 (define_insn "*rep_stossi_rex64"
17846 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17847 (set (match_operand:DI 0 "register_operand" "=D")
17848 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17850 (match_operand:DI 3 "register_operand" "0")))
17851 (set (mem:BLK (match_dup 3))
17853 (use (match_operand:SI 2 "register_operand" "a"))
17854 (use (match_dup 4))
17855 (use (reg:SI DIRFLAG_REG))]
17857 "{rep\;stosl|rep stosd}"
17858 [(set_attr "type" "str")
17859 (set_attr "prefix_rep" "1")
17860 (set_attr "memory" "store")
17861 (set_attr "mode" "SI")])
17863 (define_insn "*rep_stosqi"
17864 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17865 (set (match_operand:SI 0 "register_operand" "=D")
17866 (plus:SI (match_operand:SI 3 "register_operand" "0")
17867 (match_operand:SI 4 "register_operand" "1")))
17868 (set (mem:BLK (match_dup 3))
17870 (use (match_operand:QI 2 "register_operand" "a"))
17871 (use (match_dup 4))
17872 (use (reg:SI DIRFLAG_REG))]
17874 "{rep\;stosb|rep stosb}"
17875 [(set_attr "type" "str")
17876 (set_attr "prefix_rep" "1")
17877 (set_attr "memory" "store")
17878 (set_attr "mode" "QI")])
17880 (define_insn "*rep_stosqi_rex64"
17881 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17882 (set (match_operand:DI 0 "register_operand" "=D")
17883 (plus:DI (match_operand:DI 3 "register_operand" "0")
17884 (match_operand:DI 4 "register_operand" "1")))
17885 (set (mem:BLK (match_dup 3))
17887 (use (match_operand:QI 2 "register_operand" "a"))
17888 (use (match_dup 4))
17889 (use (reg:SI DIRFLAG_REG))]
17891 "{rep\;stosb|rep stosb}"
17892 [(set_attr "type" "str")
17893 (set_attr "prefix_rep" "1")
17894 (set_attr "memory" "store")
17895 (set_attr "mode" "QI")])
17897 (define_expand "cmpstrnsi"
17898 [(set (match_operand:SI 0 "register_operand" "")
17899 (compare:SI (match_operand:BLK 1 "general_operand" "")
17900 (match_operand:BLK 2 "general_operand" "")))
17901 (use (match_operand 3 "general_operand" ""))
17902 (use (match_operand 4 "immediate_operand" ""))]
17903 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17905 rtx addr1, addr2, out, outlow, count, countreg, align;
17907 /* Can't use this if the user has appropriated esi or edi. */
17908 if (global_regs[4] || global_regs[5])
17912 if (GET_CODE (out) != REG)
17913 out = gen_reg_rtx (SImode);
17915 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17916 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17917 if (addr1 != XEXP (operands[1], 0))
17918 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17919 if (addr2 != XEXP (operands[2], 0))
17920 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17922 count = operands[3];
17923 countreg = ix86_zero_extend_to_Pmode (count);
17925 /* %%% Iff we are testing strict equality, we can use known alignment
17926 to good advantage. This may be possible with combine, particularly
17927 once cc0 is dead. */
17928 align = operands[4];
17930 emit_insn (gen_cld ());
17931 if (GET_CODE (count) == CONST_INT)
17933 if (INTVAL (count) == 0)
17935 emit_move_insn (operands[0], const0_rtx);
17938 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17939 operands[1], operands[2]));
17944 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17946 emit_insn (gen_cmpsi_1 (countreg, countreg));
17947 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17948 operands[1], operands[2]));
17951 outlow = gen_lowpart (QImode, out);
17952 emit_insn (gen_cmpintqi (outlow));
17953 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17955 if (operands[0] != out)
17956 emit_move_insn (operands[0], out);
17961 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17963 (define_expand "cmpintqi"
17964 [(set (match_dup 1)
17965 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17967 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17968 (parallel [(set (match_operand:QI 0 "register_operand" "")
17969 (minus:QI (match_dup 1)
17971 (clobber (reg:CC FLAGS_REG))])]
17973 "operands[1] = gen_reg_rtx (QImode);
17974 operands[2] = gen_reg_rtx (QImode);")
17976 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17977 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17979 (define_expand "cmpstrnqi_nz_1"
17980 [(parallel [(set (reg:CC FLAGS_REG)
17981 (compare:CC (match_operand 4 "memory_operand" "")
17982 (match_operand 5 "memory_operand" "")))
17983 (use (match_operand 2 "register_operand" ""))
17984 (use (match_operand:SI 3 "immediate_operand" ""))
17985 (use (reg:SI DIRFLAG_REG))
17986 (clobber (match_operand 0 "register_operand" ""))
17987 (clobber (match_operand 1 "register_operand" ""))
17988 (clobber (match_dup 2))])]
17992 (define_insn "*cmpstrnqi_nz_1"
17993 [(set (reg:CC FLAGS_REG)
17994 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17995 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17996 (use (match_operand:SI 6 "register_operand" "2"))
17997 (use (match_operand:SI 3 "immediate_operand" "i"))
17998 (use (reg:SI DIRFLAG_REG))
17999 (clobber (match_operand:SI 0 "register_operand" "=S"))
18000 (clobber (match_operand:SI 1 "register_operand" "=D"))
18001 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18004 [(set_attr "type" "str")
18005 (set_attr "mode" "QI")
18006 (set_attr "prefix_rep" "1")])
18008 (define_insn "*cmpstrnqi_nz_rex_1"
18009 [(set (reg:CC FLAGS_REG)
18010 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18011 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18012 (use (match_operand:DI 6 "register_operand" "2"))
18013 (use (match_operand:SI 3 "immediate_operand" "i"))
18014 (use (reg:SI DIRFLAG_REG))
18015 (clobber (match_operand:DI 0 "register_operand" "=S"))
18016 (clobber (match_operand:DI 1 "register_operand" "=D"))
18017 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18020 [(set_attr "type" "str")
18021 (set_attr "mode" "QI")
18022 (set_attr "prefix_rep" "1")])
18024 ;; The same, but the count is not known to not be zero.
18026 (define_expand "cmpstrnqi_1"
18027 [(parallel [(set (reg:CC FLAGS_REG)
18028 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18030 (compare:CC (match_operand 4 "memory_operand" "")
18031 (match_operand 5 "memory_operand" ""))
18033 (use (match_operand:SI 3 "immediate_operand" ""))
18034 (use (reg:CC FLAGS_REG))
18035 (use (reg:SI DIRFLAG_REG))
18036 (clobber (match_operand 0 "register_operand" ""))
18037 (clobber (match_operand 1 "register_operand" ""))
18038 (clobber (match_dup 2))])]
18042 (define_insn "*cmpstrnqi_1"
18043 [(set (reg:CC FLAGS_REG)
18044 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18046 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18047 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18049 (use (match_operand:SI 3 "immediate_operand" "i"))
18050 (use (reg:CC FLAGS_REG))
18051 (use (reg:SI DIRFLAG_REG))
18052 (clobber (match_operand:SI 0 "register_operand" "=S"))
18053 (clobber (match_operand:SI 1 "register_operand" "=D"))
18054 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18057 [(set_attr "type" "str")
18058 (set_attr "mode" "QI")
18059 (set_attr "prefix_rep" "1")])
18061 (define_insn "*cmpstrnqi_rex_1"
18062 [(set (reg:CC FLAGS_REG)
18063 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18065 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18066 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18068 (use (match_operand:SI 3 "immediate_operand" "i"))
18069 (use (reg:CC FLAGS_REG))
18070 (use (reg:SI DIRFLAG_REG))
18071 (clobber (match_operand:DI 0 "register_operand" "=S"))
18072 (clobber (match_operand:DI 1 "register_operand" "=D"))
18073 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18076 [(set_attr "type" "str")
18077 (set_attr "mode" "QI")
18078 (set_attr "prefix_rep" "1")])
18080 (define_expand "strlensi"
18081 [(set (match_operand:SI 0 "register_operand" "")
18082 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18083 (match_operand:QI 2 "immediate_operand" "")
18084 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18087 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18093 (define_expand "strlendi"
18094 [(set (match_operand:DI 0 "register_operand" "")
18095 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18096 (match_operand:QI 2 "immediate_operand" "")
18097 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18100 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18106 (define_expand "strlenqi_1"
18107 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18108 (use (reg:SI DIRFLAG_REG))
18109 (clobber (match_operand 1 "register_operand" ""))
18110 (clobber (reg:CC FLAGS_REG))])]
18114 (define_insn "*strlenqi_1"
18115 [(set (match_operand:SI 0 "register_operand" "=&c")
18116 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18117 (match_operand:QI 2 "register_operand" "a")
18118 (match_operand:SI 3 "immediate_operand" "i")
18119 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18120 (use (reg:SI DIRFLAG_REG))
18121 (clobber (match_operand:SI 1 "register_operand" "=D"))
18122 (clobber (reg:CC FLAGS_REG))]
18125 [(set_attr "type" "str")
18126 (set_attr "mode" "QI")
18127 (set_attr "prefix_rep" "1")])
18129 (define_insn "*strlenqi_rex_1"
18130 [(set (match_operand:DI 0 "register_operand" "=&c")
18131 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18132 (match_operand:QI 2 "register_operand" "a")
18133 (match_operand:DI 3 "immediate_operand" "i")
18134 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18135 (use (reg:SI DIRFLAG_REG))
18136 (clobber (match_operand:DI 1 "register_operand" "=D"))
18137 (clobber (reg:CC FLAGS_REG))]
18140 [(set_attr "type" "str")
18141 (set_attr "mode" "QI")
18142 (set_attr "prefix_rep" "1")])
18144 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18145 ;; handled in combine, but it is not currently up to the task.
18146 ;; When used for their truth value, the cmpstrn* expanders generate
18155 ;; The intermediate three instructions are unnecessary.
18157 ;; This one handles cmpstrn*_nz_1...
18160 (set (reg:CC FLAGS_REG)
18161 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18162 (mem:BLK (match_operand 5 "register_operand" ""))))
18163 (use (match_operand 6 "register_operand" ""))
18164 (use (match_operand:SI 3 "immediate_operand" ""))
18165 (use (reg:SI DIRFLAG_REG))
18166 (clobber (match_operand 0 "register_operand" ""))
18167 (clobber (match_operand 1 "register_operand" ""))
18168 (clobber (match_operand 2 "register_operand" ""))])
18169 (set (match_operand:QI 7 "register_operand" "")
18170 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18171 (set (match_operand:QI 8 "register_operand" "")
18172 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18173 (set (reg FLAGS_REG)
18174 (compare (match_dup 7) (match_dup 8)))
18176 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18178 (set (reg:CC FLAGS_REG)
18179 (compare:CC (mem:BLK (match_dup 4))
18180 (mem:BLK (match_dup 5))))
18181 (use (match_dup 6))
18182 (use (match_dup 3))
18183 (use (reg:SI DIRFLAG_REG))
18184 (clobber (match_dup 0))
18185 (clobber (match_dup 1))
18186 (clobber (match_dup 2))])]
18189 ;; ...and this one handles cmpstrn*_1.
18192 (set (reg:CC FLAGS_REG)
18193 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18195 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18196 (mem:BLK (match_operand 5 "register_operand" "")))
18198 (use (match_operand:SI 3 "immediate_operand" ""))
18199 (use (reg:CC FLAGS_REG))
18200 (use (reg:SI DIRFLAG_REG))
18201 (clobber (match_operand 0 "register_operand" ""))
18202 (clobber (match_operand 1 "register_operand" ""))
18203 (clobber (match_operand 2 "register_operand" ""))])
18204 (set (match_operand:QI 7 "register_operand" "")
18205 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18206 (set (match_operand:QI 8 "register_operand" "")
18207 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18208 (set (reg FLAGS_REG)
18209 (compare (match_dup 7) (match_dup 8)))
18211 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18213 (set (reg:CC FLAGS_REG)
18214 (if_then_else:CC (ne (match_dup 6)
18216 (compare:CC (mem:BLK (match_dup 4))
18217 (mem:BLK (match_dup 5)))
18219 (use (match_dup 3))
18220 (use (reg:CC FLAGS_REG))
18221 (use (reg:SI DIRFLAG_REG))
18222 (clobber (match_dup 0))
18223 (clobber (match_dup 1))
18224 (clobber (match_dup 2))])]
18229 ;; Conditional move instructions.
18231 (define_expand "movdicc"
18232 [(set (match_operand:DI 0 "register_operand" "")
18233 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18234 (match_operand:DI 2 "general_operand" "")
18235 (match_operand:DI 3 "general_operand" "")))]
18237 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18239 (define_insn "x86_movdicc_0_m1_rex64"
18240 [(set (match_operand:DI 0 "register_operand" "=r")
18241 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18244 (clobber (reg:CC FLAGS_REG))]
18247 ; Since we don't have the proper number of operands for an alu insn,
18248 ; fill in all the blanks.
18249 [(set_attr "type" "alu")
18250 (set_attr "pent_pair" "pu")
18251 (set_attr "memory" "none")
18252 (set_attr "imm_disp" "false")
18253 (set_attr "mode" "DI")
18254 (set_attr "length_immediate" "0")])
18256 (define_insn "*movdicc_c_rex64"
18257 [(set (match_operand:DI 0 "register_operand" "=r,r")
18258 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18259 [(reg FLAGS_REG) (const_int 0)])
18260 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18261 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18262 "TARGET_64BIT && TARGET_CMOVE
18263 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18265 cmov%O2%C1\t{%2, %0|%0, %2}
18266 cmov%O2%c1\t{%3, %0|%0, %3}"
18267 [(set_attr "type" "icmov")
18268 (set_attr "mode" "DI")])
18270 (define_expand "movsicc"
18271 [(set (match_operand:SI 0 "register_operand" "")
18272 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18273 (match_operand:SI 2 "general_operand" "")
18274 (match_operand:SI 3 "general_operand" "")))]
18276 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18278 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18279 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18280 ;; So just document what we're doing explicitly.
18282 (define_insn "x86_movsicc_0_m1"
18283 [(set (match_operand:SI 0 "register_operand" "=r")
18284 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18287 (clobber (reg:CC FLAGS_REG))]
18290 ; Since we don't have the proper number of operands for an alu insn,
18291 ; fill in all the blanks.
18292 [(set_attr "type" "alu")
18293 (set_attr "pent_pair" "pu")
18294 (set_attr "memory" "none")
18295 (set_attr "imm_disp" "false")
18296 (set_attr "mode" "SI")
18297 (set_attr "length_immediate" "0")])
18299 (define_insn "*movsicc_noc"
18300 [(set (match_operand:SI 0 "register_operand" "=r,r")
18301 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18302 [(reg FLAGS_REG) (const_int 0)])
18303 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18304 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18306 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18308 cmov%O2%C1\t{%2, %0|%0, %2}
18309 cmov%O2%c1\t{%3, %0|%0, %3}"
18310 [(set_attr "type" "icmov")
18311 (set_attr "mode" "SI")])
18313 (define_expand "movhicc"
18314 [(set (match_operand:HI 0 "register_operand" "")
18315 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18316 (match_operand:HI 2 "general_operand" "")
18317 (match_operand:HI 3 "general_operand" "")))]
18318 "TARGET_HIMODE_MATH"
18319 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18321 (define_insn "*movhicc_noc"
18322 [(set (match_operand:HI 0 "register_operand" "=r,r")
18323 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18324 [(reg FLAGS_REG) (const_int 0)])
18325 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18326 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18328 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18330 cmov%O2%C1\t{%2, %0|%0, %2}
18331 cmov%O2%c1\t{%3, %0|%0, %3}"
18332 [(set_attr "type" "icmov")
18333 (set_attr "mode" "HI")])
18335 (define_expand "movqicc"
18336 [(set (match_operand:QI 0 "register_operand" "")
18337 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18338 (match_operand:QI 2 "general_operand" "")
18339 (match_operand:QI 3 "general_operand" "")))]
18340 "TARGET_QIMODE_MATH"
18341 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18343 (define_insn_and_split "*movqicc_noc"
18344 [(set (match_operand:QI 0 "register_operand" "=r,r")
18345 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18346 [(match_operand 4 "flags_reg_operand" "")
18348 (match_operand:QI 2 "register_operand" "r,0")
18349 (match_operand:QI 3 "register_operand" "0,r")))]
18350 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18352 "&& reload_completed"
18353 [(set (match_dup 0)
18354 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18357 "operands[0] = gen_lowpart (SImode, operands[0]);
18358 operands[2] = gen_lowpart (SImode, operands[2]);
18359 operands[3] = gen_lowpart (SImode, operands[3]);"
18360 [(set_attr "type" "icmov")
18361 (set_attr "mode" "SI")])
18363 (define_expand "movsfcc"
18364 [(set (match_operand:SF 0 "register_operand" "")
18365 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18366 (match_operand:SF 2 "register_operand" "")
18367 (match_operand:SF 3 "register_operand" "")))]
18368 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18369 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18371 (define_insn "*movsfcc_1_387"
18372 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18373 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18374 [(reg FLAGS_REG) (const_int 0)])
18375 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18376 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18377 "TARGET_80387 && TARGET_CMOVE
18378 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18380 fcmov%F1\t{%2, %0|%0, %2}
18381 fcmov%f1\t{%3, %0|%0, %3}
18382 cmov%O2%C1\t{%2, %0|%0, %2}
18383 cmov%O2%c1\t{%3, %0|%0, %3}"
18384 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18385 (set_attr "mode" "SF,SF,SI,SI")])
18387 (define_expand "movdfcc"
18388 [(set (match_operand:DF 0 "register_operand" "")
18389 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18390 (match_operand:DF 2 "register_operand" "")
18391 (match_operand:DF 3 "register_operand" "")))]
18392 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18393 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18395 (define_insn "*movdfcc_1"
18396 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18397 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18398 [(reg FLAGS_REG) (const_int 0)])
18399 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18400 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18401 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18402 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18404 fcmov%F1\t{%2, %0|%0, %2}
18405 fcmov%f1\t{%3, %0|%0, %3}
18408 [(set_attr "type" "fcmov,fcmov,multi,multi")
18409 (set_attr "mode" "DF")])
18411 (define_insn "*movdfcc_1_rex64"
18412 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18413 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18414 [(reg FLAGS_REG) (const_int 0)])
18415 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18416 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18417 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18418 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18420 fcmov%F1\t{%2, %0|%0, %2}
18421 fcmov%f1\t{%3, %0|%0, %3}
18422 cmov%O2%C1\t{%2, %0|%0, %2}
18423 cmov%O2%c1\t{%3, %0|%0, %3}"
18424 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18425 (set_attr "mode" "DF")])
18428 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18429 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18430 [(match_operand 4 "flags_reg_operand" "")
18432 (match_operand:DF 2 "nonimmediate_operand" "")
18433 (match_operand:DF 3 "nonimmediate_operand" "")))]
18434 "!TARGET_64BIT && reload_completed"
18435 [(set (match_dup 2)
18436 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18440 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18443 "split_di (operands+2, 1, operands+5, operands+6);
18444 split_di (operands+3, 1, operands+7, operands+8);
18445 split_di (operands, 1, operands+2, operands+3);")
18447 (define_expand "movxfcc"
18448 [(set (match_operand:XF 0 "register_operand" "")
18449 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18450 (match_operand:XF 2 "register_operand" "")
18451 (match_operand:XF 3 "register_operand" "")))]
18452 "TARGET_80387 && TARGET_CMOVE"
18453 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18455 (define_insn "*movxfcc_1"
18456 [(set (match_operand:XF 0 "register_operand" "=f,f")
18457 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18458 [(reg FLAGS_REG) (const_int 0)])
18459 (match_operand:XF 2 "register_operand" "f,0")
18460 (match_operand:XF 3 "register_operand" "0,f")))]
18461 "TARGET_80387 && TARGET_CMOVE"
18463 fcmov%F1\t{%2, %0|%0, %2}
18464 fcmov%f1\t{%3, %0|%0, %3}"
18465 [(set_attr "type" "fcmov")
18466 (set_attr "mode" "XF")])
18468 ;; These versions of the min/max patterns are intentionally ignorant of
18469 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18470 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18471 ;; are undefined in this condition, we're certain this is correct.
18473 (define_insn "sminsf3"
18474 [(set (match_operand:SF 0 "register_operand" "=x")
18475 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18476 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18478 "minss\t{%2, %0|%0, %2}"
18479 [(set_attr "type" "sseadd")
18480 (set_attr "mode" "SF")])
18482 (define_insn "smaxsf3"
18483 [(set (match_operand:SF 0 "register_operand" "=x")
18484 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18485 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18487 "maxss\t{%2, %0|%0, %2}"
18488 [(set_attr "type" "sseadd")
18489 (set_attr "mode" "SF")])
18491 (define_insn "smindf3"
18492 [(set (match_operand:DF 0 "register_operand" "=x")
18493 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18494 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18495 "TARGET_SSE2 && TARGET_SSE_MATH"
18496 "minsd\t{%2, %0|%0, %2}"
18497 [(set_attr "type" "sseadd")
18498 (set_attr "mode" "DF")])
18500 (define_insn "smaxdf3"
18501 [(set (match_operand:DF 0 "register_operand" "=x")
18502 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18503 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18504 "TARGET_SSE2 && TARGET_SSE_MATH"
18505 "maxsd\t{%2, %0|%0, %2}"
18506 [(set_attr "type" "sseadd")
18507 (set_attr "mode" "DF")])
18509 ;; These versions of the min/max patterns implement exactly the operations
18510 ;; min = (op1 < op2 ? op1 : op2)
18511 ;; max = (!(op1 < op2) ? op1 : op2)
18512 ;; Their operands are not commutative, and thus they may be used in the
18513 ;; presence of -0.0 and NaN.
18515 (define_insn "*ieee_sminsf3"
18516 [(set (match_operand:SF 0 "register_operand" "=x")
18517 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18518 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18521 "minss\t{%2, %0|%0, %2}"
18522 [(set_attr "type" "sseadd")
18523 (set_attr "mode" "SF")])
18525 (define_insn "*ieee_smaxsf3"
18526 [(set (match_operand:SF 0 "register_operand" "=x")
18527 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18528 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18531 "maxss\t{%2, %0|%0, %2}"
18532 [(set_attr "type" "sseadd")
18533 (set_attr "mode" "SF")])
18535 (define_insn "*ieee_smindf3"
18536 [(set (match_operand:DF 0 "register_operand" "=x")
18537 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18538 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18540 "TARGET_SSE2 && TARGET_SSE_MATH"
18541 "minsd\t{%2, %0|%0, %2}"
18542 [(set_attr "type" "sseadd")
18543 (set_attr "mode" "DF")])
18545 (define_insn "*ieee_smaxdf3"
18546 [(set (match_operand:DF 0 "register_operand" "=x")
18547 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18548 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18550 "TARGET_SSE2 && TARGET_SSE_MATH"
18551 "maxsd\t{%2, %0|%0, %2}"
18552 [(set_attr "type" "sseadd")
18553 (set_attr "mode" "DF")])
18555 ;; Conditional addition patterns
18556 (define_expand "addqicc"
18557 [(match_operand:QI 0 "register_operand" "")
18558 (match_operand 1 "comparison_operator" "")
18559 (match_operand:QI 2 "register_operand" "")
18560 (match_operand:QI 3 "const_int_operand" "")]
18562 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18564 (define_expand "addhicc"
18565 [(match_operand:HI 0 "register_operand" "")
18566 (match_operand 1 "comparison_operator" "")
18567 (match_operand:HI 2 "register_operand" "")
18568 (match_operand:HI 3 "const_int_operand" "")]
18570 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18572 (define_expand "addsicc"
18573 [(match_operand:SI 0 "register_operand" "")
18574 (match_operand 1 "comparison_operator" "")
18575 (match_operand:SI 2 "register_operand" "")
18576 (match_operand:SI 3 "const_int_operand" "")]
18578 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18580 (define_expand "adddicc"
18581 [(match_operand:DI 0 "register_operand" "")
18582 (match_operand 1 "comparison_operator" "")
18583 (match_operand:DI 2 "register_operand" "")
18584 (match_operand:DI 3 "const_int_operand" "")]
18586 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18589 ;; Misc patterns (?)
18591 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18592 ;; Otherwise there will be nothing to keep
18594 ;; [(set (reg ebp) (reg esp))]
18595 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18596 ;; (clobber (eflags)]
18597 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18599 ;; in proper program order.
18600 (define_insn "pro_epilogue_adjust_stack_1"
18601 [(set (match_operand:SI 0 "register_operand" "=r,r")
18602 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18603 (match_operand:SI 2 "immediate_operand" "i,i")))
18604 (clobber (reg:CC FLAGS_REG))
18605 (clobber (mem:BLK (scratch)))]
18608 switch (get_attr_type (insn))
18611 return "mov{l}\t{%1, %0|%0, %1}";
18614 if (GET_CODE (operands[2]) == CONST_INT
18615 && (INTVAL (operands[2]) == 128
18616 || (INTVAL (operands[2]) < 0
18617 && INTVAL (operands[2]) != -128)))
18619 operands[2] = GEN_INT (-INTVAL (operands[2]));
18620 return "sub{l}\t{%2, %0|%0, %2}";
18622 return "add{l}\t{%2, %0|%0, %2}";
18625 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18626 return "lea{l}\t{%a2, %0|%0, %a2}";
18629 gcc_unreachable ();
18632 [(set (attr "type")
18633 (cond [(eq_attr "alternative" "0")
18634 (const_string "alu")
18635 (match_operand:SI 2 "const0_operand" "")
18636 (const_string "imov")
18638 (const_string "lea")))
18639 (set_attr "mode" "SI")])
18641 (define_insn "pro_epilogue_adjust_stack_rex64"
18642 [(set (match_operand:DI 0 "register_operand" "=r,r")
18643 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18644 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18645 (clobber (reg:CC FLAGS_REG))
18646 (clobber (mem:BLK (scratch)))]
18649 switch (get_attr_type (insn))
18652 return "mov{q}\t{%1, %0|%0, %1}";
18655 if (GET_CODE (operands[2]) == CONST_INT
18656 /* Avoid overflows. */
18657 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18658 && (INTVAL (operands[2]) == 128
18659 || (INTVAL (operands[2]) < 0
18660 && INTVAL (operands[2]) != -128)))
18662 operands[2] = GEN_INT (-INTVAL (operands[2]));
18663 return "sub{q}\t{%2, %0|%0, %2}";
18665 return "add{q}\t{%2, %0|%0, %2}";
18668 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18669 return "lea{q}\t{%a2, %0|%0, %a2}";
18672 gcc_unreachable ();
18675 [(set (attr "type")
18676 (cond [(eq_attr "alternative" "0")
18677 (const_string "alu")
18678 (match_operand:DI 2 "const0_operand" "")
18679 (const_string "imov")
18681 (const_string "lea")))
18682 (set_attr "mode" "DI")])
18684 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18685 [(set (match_operand:DI 0 "register_operand" "=r,r")
18686 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18687 (match_operand:DI 3 "immediate_operand" "i,i")))
18688 (use (match_operand:DI 2 "register_operand" "r,r"))
18689 (clobber (reg:CC FLAGS_REG))
18690 (clobber (mem:BLK (scratch)))]
18693 switch (get_attr_type (insn))
18696 return "add{q}\t{%2, %0|%0, %2}";
18699 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18700 return "lea{q}\t{%a2, %0|%0, %a2}";
18703 gcc_unreachable ();
18706 [(set_attr "type" "alu,lea")
18707 (set_attr "mode" "DI")])
18709 (define_expand "allocate_stack_worker"
18710 [(match_operand:SI 0 "register_operand" "")]
18711 "TARGET_STACK_PROBE"
18713 if (reload_completed)
18716 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18718 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18723 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18725 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18730 (define_insn "allocate_stack_worker_1"
18731 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18732 UNSPECV_STACK_PROBE)
18733 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18734 (clobber (match_scratch:SI 1 "=0"))
18735 (clobber (reg:CC FLAGS_REG))]
18736 "!TARGET_64BIT && TARGET_STACK_PROBE"
18738 [(set_attr "type" "multi")
18739 (set_attr "length" "5")])
18741 (define_expand "allocate_stack_worker_postreload"
18742 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18743 UNSPECV_STACK_PROBE)
18744 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18745 (clobber (match_dup 0))
18746 (clobber (reg:CC FLAGS_REG))])]
18750 (define_insn "allocate_stack_worker_rex64"
18751 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18752 UNSPECV_STACK_PROBE)
18753 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18754 (clobber (match_scratch:DI 1 "=0"))
18755 (clobber (reg:CC FLAGS_REG))]
18756 "TARGET_64BIT && TARGET_STACK_PROBE"
18758 [(set_attr "type" "multi")
18759 (set_attr "length" "5")])
18761 (define_expand "allocate_stack_worker_rex64_postreload"
18762 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18763 UNSPECV_STACK_PROBE)
18764 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18765 (clobber (match_dup 0))
18766 (clobber (reg:CC FLAGS_REG))])]
18770 (define_expand "allocate_stack"
18771 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18772 (minus:SI (reg:SI SP_REG)
18773 (match_operand:SI 1 "general_operand" "")))
18774 (clobber (reg:CC FLAGS_REG))])
18775 (parallel [(set (reg:SI SP_REG)
18776 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18777 (clobber (reg:CC FLAGS_REG))])]
18778 "TARGET_STACK_PROBE"
18780 #ifdef CHECK_STACK_LIMIT
18781 if (GET_CODE (operands[1]) == CONST_INT
18782 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18783 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18787 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18790 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18794 (define_expand "builtin_setjmp_receiver"
18795 [(label_ref (match_operand 0 "" ""))]
18796 "!TARGET_64BIT && flag_pic"
18798 emit_insn (gen_set_got (pic_offset_table_rtx));
18802 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18805 [(set (match_operand 0 "register_operand" "")
18806 (match_operator 3 "promotable_binary_operator"
18807 [(match_operand 1 "register_operand" "")
18808 (match_operand 2 "aligned_operand" "")]))
18809 (clobber (reg:CC FLAGS_REG))]
18810 "! TARGET_PARTIAL_REG_STALL && reload_completed
18811 && ((GET_MODE (operands[0]) == HImode
18812 && ((!optimize_size && !TARGET_FAST_PREFIX)
18813 || GET_CODE (operands[2]) != CONST_INT
18814 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18815 || (GET_MODE (operands[0]) == QImode
18816 && (TARGET_PROMOTE_QImode || optimize_size)))"
18817 [(parallel [(set (match_dup 0)
18818 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18819 (clobber (reg:CC FLAGS_REG))])]
18820 "operands[0] = gen_lowpart (SImode, operands[0]);
18821 operands[1] = gen_lowpart (SImode, operands[1]);
18822 if (GET_CODE (operands[3]) != ASHIFT)
18823 operands[2] = gen_lowpart (SImode, operands[2]);
18824 PUT_MODE (operands[3], SImode);")
18826 ; Promote the QImode tests, as i386 has encoding of the AND
18827 ; instruction with 32-bit sign-extended immediate and thus the
18828 ; instruction size is unchanged, except in the %eax case for
18829 ; which it is increased by one byte, hence the ! optimize_size.
18831 [(set (match_operand 0 "flags_reg_operand" "")
18832 (match_operator 2 "compare_operator"
18833 [(and (match_operand 3 "aligned_operand" "")
18834 (match_operand 4 "const_int_operand" ""))
18836 (set (match_operand 1 "register_operand" "")
18837 (and (match_dup 3) (match_dup 4)))]
18838 "! TARGET_PARTIAL_REG_STALL && reload_completed
18839 /* Ensure that the operand will remain sign-extended immediate. */
18840 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18842 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18843 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18844 [(parallel [(set (match_dup 0)
18845 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18848 (and:SI (match_dup 3) (match_dup 4)))])]
18851 = gen_int_mode (INTVAL (operands[4])
18852 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18853 operands[1] = gen_lowpart (SImode, operands[1]);
18854 operands[3] = gen_lowpart (SImode, operands[3]);
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.
18862 [(set (match_operand 0 "flags_reg_operand" "")
18863 (match_operator 1 "compare_operator"
18864 [(and (match_operand:HI 2 "aligned_operand" "")
18865 (match_operand:HI 3 "const_int_operand" ""))
18867 "! TARGET_PARTIAL_REG_STALL && reload_completed
18868 /* Ensure that the operand will remain sign-extended immediate. */
18869 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18870 && ! TARGET_FAST_PREFIX
18871 && ! optimize_size"
18872 [(set (match_dup 0)
18873 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18877 = gen_int_mode (INTVAL (operands[3])
18878 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18879 operands[2] = gen_lowpart (SImode, operands[2]);
18883 [(set (match_operand 0 "register_operand" "")
18884 (neg (match_operand 1 "register_operand" "")))
18885 (clobber (reg:CC FLAGS_REG))]
18886 "! TARGET_PARTIAL_REG_STALL && reload_completed
18887 && (GET_MODE (operands[0]) == HImode
18888 || (GET_MODE (operands[0]) == QImode
18889 && (TARGET_PROMOTE_QImode || optimize_size)))"
18890 [(parallel [(set (match_dup 0)
18891 (neg:SI (match_dup 1)))
18892 (clobber (reg:CC FLAGS_REG))])]
18893 "operands[0] = gen_lowpart (SImode, operands[0]);
18894 operands[1] = gen_lowpart (SImode, operands[1]);")
18897 [(set (match_operand 0 "register_operand" "")
18898 (not (match_operand 1 "register_operand" "")))]
18899 "! TARGET_PARTIAL_REG_STALL && reload_completed
18900 && (GET_MODE (operands[0]) == HImode
18901 || (GET_MODE (operands[0]) == QImode
18902 && (TARGET_PROMOTE_QImode || optimize_size)))"
18903 [(set (match_dup 0)
18904 (not:SI (match_dup 1)))]
18905 "operands[0] = gen_lowpart (SImode, operands[0]);
18906 operands[1] = gen_lowpart (SImode, operands[1]);")
18909 [(set (match_operand 0 "register_operand" "")
18910 (if_then_else (match_operator 1 "comparison_operator"
18911 [(reg FLAGS_REG) (const_int 0)])
18912 (match_operand 2 "register_operand" "")
18913 (match_operand 3 "register_operand" "")))]
18914 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18915 && (GET_MODE (operands[0]) == HImode
18916 || (GET_MODE (operands[0]) == QImode
18917 && (TARGET_PROMOTE_QImode || optimize_size)))"
18918 [(set (match_dup 0)
18919 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18920 "operands[0] = gen_lowpart (SImode, operands[0]);
18921 operands[2] = gen_lowpart (SImode, operands[2]);
18922 operands[3] = gen_lowpart (SImode, operands[3]);")
18925 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18926 ;; transform a complex memory operation into two memory to register operations.
18928 ;; Don't push memory operands
18930 [(set (match_operand:SI 0 "push_operand" "")
18931 (match_operand:SI 1 "memory_operand" ""))
18932 (match_scratch:SI 2 "r")]
18933 "!optimize_size && !TARGET_PUSH_MEMORY
18934 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18935 [(set (match_dup 2) (match_dup 1))
18936 (set (match_dup 0) (match_dup 2))]
18940 [(set (match_operand:DI 0 "push_operand" "")
18941 (match_operand:DI 1 "memory_operand" ""))
18942 (match_scratch:DI 2 "r")]
18943 "!optimize_size && !TARGET_PUSH_MEMORY
18944 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18945 [(set (match_dup 2) (match_dup 1))
18946 (set (match_dup 0) (match_dup 2))]
18949 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18952 [(set (match_operand:SF 0 "push_operand" "")
18953 (match_operand:SF 1 "memory_operand" ""))
18954 (match_scratch:SF 2 "r")]
18955 "!optimize_size && !TARGET_PUSH_MEMORY
18956 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18957 [(set (match_dup 2) (match_dup 1))
18958 (set (match_dup 0) (match_dup 2))]
18962 [(set (match_operand:HI 0 "push_operand" "")
18963 (match_operand:HI 1 "memory_operand" ""))
18964 (match_scratch:HI 2 "r")]
18965 "!optimize_size && !TARGET_PUSH_MEMORY
18966 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18967 [(set (match_dup 2) (match_dup 1))
18968 (set (match_dup 0) (match_dup 2))]
18972 [(set (match_operand:QI 0 "push_operand" "")
18973 (match_operand:QI 1 "memory_operand" ""))
18974 (match_scratch:QI 2 "q")]
18975 "!optimize_size && !TARGET_PUSH_MEMORY
18976 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18977 [(set (match_dup 2) (match_dup 1))
18978 (set (match_dup 0) (match_dup 2))]
18981 ;; Don't move an immediate directly to memory when the instruction
18984 [(match_scratch:SI 1 "r")
18985 (set (match_operand:SI 0 "memory_operand" "")
18988 && ! TARGET_USE_MOV0
18989 && TARGET_SPLIT_LONG_MOVES
18990 && get_attr_length (insn) >= ix86_cost->large_insn
18991 && peep2_regno_dead_p (0, FLAGS_REG)"
18992 [(parallel [(set (match_dup 1) (const_int 0))
18993 (clobber (reg:CC FLAGS_REG))])
18994 (set (match_dup 0) (match_dup 1))]
18998 [(match_scratch:HI 1 "r")
18999 (set (match_operand:HI 0 "memory_operand" "")
19002 && ! TARGET_USE_MOV0
19003 && TARGET_SPLIT_LONG_MOVES
19004 && get_attr_length (insn) >= ix86_cost->large_insn
19005 && peep2_regno_dead_p (0, FLAGS_REG)"
19006 [(parallel [(set (match_dup 2) (const_int 0))
19007 (clobber (reg:CC FLAGS_REG))])
19008 (set (match_dup 0) (match_dup 1))]
19009 "operands[2] = gen_lowpart (SImode, operands[1]);")
19012 [(match_scratch:QI 1 "q")
19013 (set (match_operand:QI 0 "memory_operand" "")
19016 && ! TARGET_USE_MOV0
19017 && TARGET_SPLIT_LONG_MOVES
19018 && get_attr_length (insn) >= ix86_cost->large_insn
19019 && peep2_regno_dead_p (0, FLAGS_REG)"
19020 [(parallel [(set (match_dup 2) (const_int 0))
19021 (clobber (reg:CC FLAGS_REG))])
19022 (set (match_dup 0) (match_dup 1))]
19023 "operands[2] = gen_lowpart (SImode, operands[1]);")
19026 [(match_scratch:SI 2 "r")
19027 (set (match_operand:SI 0 "memory_operand" "")
19028 (match_operand:SI 1 "immediate_operand" ""))]
19030 && get_attr_length (insn) >= ix86_cost->large_insn
19031 && TARGET_SPLIT_LONG_MOVES"
19032 [(set (match_dup 2) (match_dup 1))
19033 (set (match_dup 0) (match_dup 2))]
19037 [(match_scratch:HI 2 "r")
19038 (set (match_operand:HI 0 "memory_operand" "")
19039 (match_operand:HI 1 "immediate_operand" ""))]
19040 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19041 && TARGET_SPLIT_LONG_MOVES"
19042 [(set (match_dup 2) (match_dup 1))
19043 (set (match_dup 0) (match_dup 2))]
19047 [(match_scratch:QI 2 "q")
19048 (set (match_operand:QI 0 "memory_operand" "")
19049 (match_operand:QI 1 "immediate_operand" ""))]
19050 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19051 && TARGET_SPLIT_LONG_MOVES"
19052 [(set (match_dup 2) (match_dup 1))
19053 (set (match_dup 0) (match_dup 2))]
19056 ;; Don't compare memory with zero, load and use a test instead.
19058 [(set (match_operand 0 "flags_reg_operand" "")
19059 (match_operator 1 "compare_operator"
19060 [(match_operand:SI 2 "memory_operand" "")
19062 (match_scratch:SI 3 "r")]
19063 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19064 [(set (match_dup 3) (match_dup 2))
19065 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19068 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19069 ;; Don't split NOTs with a displacement operand, because resulting XOR
19070 ;; will not be pairable anyway.
19072 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19073 ;; represented using a modRM byte. The XOR replacement is long decoded,
19074 ;; so this split helps here as well.
19076 ;; Note: Can't do this as a regular split because we can't get proper
19077 ;; lifetime information then.
19080 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19081 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19083 && peep2_regno_dead_p (0, FLAGS_REG)
19084 && ((TARGET_PENTIUM
19085 && (GET_CODE (operands[0]) != MEM
19086 || !memory_displacement_operand (operands[0], SImode)))
19087 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19088 [(parallel [(set (match_dup 0)
19089 (xor:SI (match_dup 1) (const_int -1)))
19090 (clobber (reg:CC FLAGS_REG))])]
19094 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19095 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19097 && peep2_regno_dead_p (0, FLAGS_REG)
19098 && ((TARGET_PENTIUM
19099 && (GET_CODE (operands[0]) != MEM
19100 || !memory_displacement_operand (operands[0], HImode)))
19101 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19102 [(parallel [(set (match_dup 0)
19103 (xor:HI (match_dup 1) (const_int -1)))
19104 (clobber (reg:CC FLAGS_REG))])]
19108 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19109 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19111 && peep2_regno_dead_p (0, FLAGS_REG)
19112 && ((TARGET_PENTIUM
19113 && (GET_CODE (operands[0]) != MEM
19114 || !memory_displacement_operand (operands[0], QImode)))
19115 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19116 [(parallel [(set (match_dup 0)
19117 (xor:QI (match_dup 1) (const_int -1)))
19118 (clobber (reg:CC FLAGS_REG))])]
19121 ;; Non pairable "test imm, reg" instructions can be translated to
19122 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19123 ;; byte opcode instead of two, have a short form for byte operands),
19124 ;; so do it for other CPUs as well. Given that the value was dead,
19125 ;; this should not create any new dependencies. Pass on the sub-word
19126 ;; versions if we're concerned about partial register stalls.
19129 [(set (match_operand 0 "flags_reg_operand" "")
19130 (match_operator 1 "compare_operator"
19131 [(and:SI (match_operand:SI 2 "register_operand" "")
19132 (match_operand:SI 3 "immediate_operand" ""))
19134 "ix86_match_ccmode (insn, CCNOmode)
19135 && (true_regnum (operands[2]) != 0
19136 || (GET_CODE (operands[3]) == CONST_INT
19137 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19138 && peep2_reg_dead_p (1, operands[2])"
19140 [(set (match_dup 0)
19141 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19144 (and:SI (match_dup 2) (match_dup 3)))])]
19147 ;; We don't need to handle HImode case, because it will be promoted to SImode
19148 ;; on ! TARGET_PARTIAL_REG_STALL
19151 [(set (match_operand 0 "flags_reg_operand" "")
19152 (match_operator 1 "compare_operator"
19153 [(and:QI (match_operand:QI 2 "register_operand" "")
19154 (match_operand:QI 3 "immediate_operand" ""))
19156 "! TARGET_PARTIAL_REG_STALL
19157 && ix86_match_ccmode (insn, CCNOmode)
19158 && true_regnum (operands[2]) != 0
19159 && peep2_reg_dead_p (1, operands[2])"
19161 [(set (match_dup 0)
19162 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19165 (and:QI (match_dup 2) (match_dup 3)))])]
19169 [(set (match_operand 0 "flags_reg_operand" "")
19170 (match_operator 1 "compare_operator"
19173 (match_operand 2 "ext_register_operand" "")
19176 (match_operand 3 "const_int_operand" ""))
19178 "! TARGET_PARTIAL_REG_STALL
19179 && ix86_match_ccmode (insn, CCNOmode)
19180 && true_regnum (operands[2]) != 0
19181 && peep2_reg_dead_p (1, operands[2])"
19182 [(parallel [(set (match_dup 0)
19191 (set (zero_extract:SI (match_dup 2)
19202 ;; Don't do logical operations with memory inputs.
19204 [(match_scratch:SI 2 "r")
19205 (parallel [(set (match_operand:SI 0 "register_operand" "")
19206 (match_operator:SI 3 "arith_or_logical_operator"
19208 (match_operand:SI 1 "memory_operand" "")]))
19209 (clobber (reg:CC FLAGS_REG))])]
19210 "! optimize_size && ! TARGET_READ_MODIFY"
19211 [(set (match_dup 2) (match_dup 1))
19212 (parallel [(set (match_dup 0)
19213 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19214 (clobber (reg:CC FLAGS_REG))])]
19218 [(match_scratch:SI 2 "r")
19219 (parallel [(set (match_operand:SI 0 "register_operand" "")
19220 (match_operator:SI 3 "arith_or_logical_operator"
19221 [(match_operand:SI 1 "memory_operand" "")
19223 (clobber (reg:CC FLAGS_REG))])]
19224 "! optimize_size && ! TARGET_READ_MODIFY"
19225 [(set (match_dup 2) (match_dup 1))
19226 (parallel [(set (match_dup 0)
19227 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19228 (clobber (reg:CC FLAGS_REG))])]
19231 ; Don't do logical operations with memory outputs
19233 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19234 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19235 ; the same decoder scheduling characteristics as the original.
19238 [(match_scratch:SI 2 "r")
19239 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19240 (match_operator:SI 3 "arith_or_logical_operator"
19242 (match_operand:SI 1 "nonmemory_operand" "")]))
19243 (clobber (reg:CC FLAGS_REG))])]
19244 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19245 [(set (match_dup 2) (match_dup 0))
19246 (parallel [(set (match_dup 2)
19247 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19248 (clobber (reg:CC FLAGS_REG))])
19249 (set (match_dup 0) (match_dup 2))]
19253 [(match_scratch:SI 2 "r")
19254 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19255 (match_operator:SI 3 "arith_or_logical_operator"
19256 [(match_operand:SI 1 "nonmemory_operand" "")
19258 (clobber (reg:CC FLAGS_REG))])]
19259 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19260 [(set (match_dup 2) (match_dup 0))
19261 (parallel [(set (match_dup 2)
19262 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19263 (clobber (reg:CC FLAGS_REG))])
19264 (set (match_dup 0) (match_dup 2))]
19267 ;; Attempt to always use XOR for zeroing registers.
19269 [(set (match_operand 0 "register_operand" "")
19270 (match_operand 1 "const0_operand" ""))]
19271 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19272 && (! TARGET_USE_MOV0 || optimize_size)
19273 && GENERAL_REG_P (operands[0])
19274 && peep2_regno_dead_p (0, FLAGS_REG)"
19275 [(parallel [(set (match_dup 0) (const_int 0))
19276 (clobber (reg:CC FLAGS_REG))])]
19278 operands[0] = gen_lowpart (word_mode, operands[0]);
19282 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19284 "(GET_MODE (operands[0]) == QImode
19285 || GET_MODE (operands[0]) == HImode)
19286 && (! TARGET_USE_MOV0 || optimize_size)
19287 && peep2_regno_dead_p (0, FLAGS_REG)"
19288 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19289 (clobber (reg:CC FLAGS_REG))])])
19291 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19293 [(set (match_operand 0 "register_operand" "")
19295 "(GET_MODE (operands[0]) == HImode
19296 || GET_MODE (operands[0]) == SImode
19297 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19298 && (optimize_size || TARGET_PENTIUM)
19299 && peep2_regno_dead_p (0, FLAGS_REG)"
19300 [(parallel [(set (match_dup 0) (const_int -1))
19301 (clobber (reg:CC FLAGS_REG))])]
19302 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19305 ;; Attempt to convert simple leas to adds. These can be created by
19308 [(set (match_operand:SI 0 "register_operand" "")
19309 (plus:SI (match_dup 0)
19310 (match_operand:SI 1 "nonmemory_operand" "")))]
19311 "peep2_regno_dead_p (0, FLAGS_REG)"
19312 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19313 (clobber (reg:CC FLAGS_REG))])]
19317 [(set (match_operand:SI 0 "register_operand" "")
19318 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19319 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19320 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19321 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19322 (clobber (reg:CC FLAGS_REG))])]
19323 "operands[2] = gen_lowpart (SImode, operands[2]);")
19326 [(set (match_operand:DI 0 "register_operand" "")
19327 (plus:DI (match_dup 0)
19328 (match_operand:DI 1 "x86_64_general_operand" "")))]
19329 "peep2_regno_dead_p (0, FLAGS_REG)"
19330 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19331 (clobber (reg:CC FLAGS_REG))])]
19335 [(set (match_operand:SI 0 "register_operand" "")
19336 (mult:SI (match_dup 0)
19337 (match_operand:SI 1 "const_int_operand" "")))]
19338 "exact_log2 (INTVAL (operands[1])) >= 0
19339 && peep2_regno_dead_p (0, FLAGS_REG)"
19340 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19341 (clobber (reg:CC FLAGS_REG))])]
19342 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19345 [(set (match_operand:DI 0 "register_operand" "")
19346 (mult:DI (match_dup 0)
19347 (match_operand:DI 1 "const_int_operand" "")))]
19348 "exact_log2 (INTVAL (operands[1])) >= 0
19349 && peep2_regno_dead_p (0, FLAGS_REG)"
19350 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19351 (clobber (reg:CC FLAGS_REG))])]
19352 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19355 [(set (match_operand:SI 0 "register_operand" "")
19356 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19357 (match_operand:DI 2 "const_int_operand" "")) 0))]
19358 "exact_log2 (INTVAL (operands[2])) >= 0
19359 && REGNO (operands[0]) == REGNO (operands[1])
19360 && peep2_regno_dead_p (0, FLAGS_REG)"
19361 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19362 (clobber (reg:CC FLAGS_REG))])]
19363 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19365 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19366 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19367 ;; many CPUs it is also faster, since special hardware to avoid esp
19368 ;; dependencies is present.
19370 ;; While some of these conversions may be done using splitters, we use peepholes
19371 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19373 ;; Convert prologue esp subtractions to push.
19374 ;; We need register to push. In order to keep verify_flow_info happy we have
19376 ;; - use scratch and clobber it in order to avoid dependencies
19377 ;; - use already live register
19378 ;; We can't use the second way right now, since there is no reliable way how to
19379 ;; verify that given register is live. First choice will also most likely in
19380 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19381 ;; call clobbered registers are dead. We may want to use base pointer as an
19382 ;; alternative when no register is available later.
19385 [(match_scratch:SI 0 "r")
19386 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19387 (clobber (reg:CC FLAGS_REG))
19388 (clobber (mem:BLK (scratch)))])]
19389 "optimize_size || !TARGET_SUB_ESP_4"
19390 [(clobber (match_dup 0))
19391 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19392 (clobber (mem:BLK (scratch)))])])
19395 [(match_scratch:SI 0 "r")
19396 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19397 (clobber (reg:CC FLAGS_REG))
19398 (clobber (mem:BLK (scratch)))])]
19399 "optimize_size || !TARGET_SUB_ESP_8"
19400 [(clobber (match_dup 0))
19401 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19402 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19403 (clobber (mem:BLK (scratch)))])])
19405 ;; Convert esp subtractions to push.
19407 [(match_scratch:SI 0 "r")
19408 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19409 (clobber (reg:CC FLAGS_REG))])]
19410 "optimize_size || !TARGET_SUB_ESP_4"
19411 [(clobber (match_dup 0))
19412 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19415 [(match_scratch:SI 0 "r")
19416 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19417 (clobber (reg:CC FLAGS_REG))])]
19418 "optimize_size || !TARGET_SUB_ESP_8"
19419 [(clobber (match_dup 0))
19420 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19421 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19423 ;; Convert epilogue deallocator to pop.
19425 [(match_scratch:SI 0 "r")
19426 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19427 (clobber (reg:CC FLAGS_REG))
19428 (clobber (mem:BLK (scratch)))])]
19429 "optimize_size || !TARGET_ADD_ESP_4"
19430 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19431 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19432 (clobber (mem:BLK (scratch)))])]
19435 ;; Two pops case is tricky, since pop causes dependency on destination register.
19436 ;; We use two registers if available.
19438 [(match_scratch:SI 0 "r")
19439 (match_scratch:SI 1 "r")
19440 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19441 (clobber (reg:CC FLAGS_REG))
19442 (clobber (mem:BLK (scratch)))])]
19443 "optimize_size || !TARGET_ADD_ESP_8"
19444 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19445 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19446 (clobber (mem:BLK (scratch)))])
19447 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19448 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19452 [(match_scratch:SI 0 "r")
19453 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19454 (clobber (reg:CC FLAGS_REG))
19455 (clobber (mem:BLK (scratch)))])]
19457 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19458 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19459 (clobber (mem:BLK (scratch)))])
19460 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19461 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19464 ;; Convert esp additions to pop.
19466 [(match_scratch:SI 0 "r")
19467 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19468 (clobber (reg:CC FLAGS_REG))])]
19470 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19471 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19474 ;; Two pops case is tricky, since pop causes dependency on destination register.
19475 ;; We use two registers if available.
19477 [(match_scratch:SI 0 "r")
19478 (match_scratch:SI 1 "r")
19479 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19480 (clobber (reg:CC FLAGS_REG))])]
19482 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19483 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19484 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19485 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19489 [(match_scratch:SI 0 "r")
19490 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19491 (clobber (reg:CC FLAGS_REG))])]
19493 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19494 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19495 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19496 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19499 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19500 ;; required and register dies. Similarly for 128 to plus -128.
19502 [(set (match_operand 0 "flags_reg_operand" "")
19503 (match_operator 1 "compare_operator"
19504 [(match_operand 2 "register_operand" "")
19505 (match_operand 3 "const_int_operand" "")]))]
19506 "(INTVAL (operands[3]) == -1
19507 || INTVAL (operands[3]) == 1
19508 || INTVAL (operands[3]) == 128)
19509 && ix86_match_ccmode (insn, CCGCmode)
19510 && peep2_reg_dead_p (1, operands[2])"
19511 [(parallel [(set (match_dup 0)
19512 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19513 (clobber (match_dup 2))])]
19517 [(match_scratch:DI 0 "r")
19518 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19519 (clobber (reg:CC FLAGS_REG))
19520 (clobber (mem:BLK (scratch)))])]
19521 "optimize_size || !TARGET_SUB_ESP_4"
19522 [(clobber (match_dup 0))
19523 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19524 (clobber (mem:BLK (scratch)))])])
19527 [(match_scratch:DI 0 "r")
19528 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19529 (clobber (reg:CC FLAGS_REG))
19530 (clobber (mem:BLK (scratch)))])]
19531 "optimize_size || !TARGET_SUB_ESP_8"
19532 [(clobber (match_dup 0))
19533 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19534 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19535 (clobber (mem:BLK (scratch)))])])
19537 ;; Convert esp subtractions to push.
19539 [(match_scratch:DI 0 "r")
19540 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19541 (clobber (reg:CC FLAGS_REG))])]
19542 "optimize_size || !TARGET_SUB_ESP_4"
19543 [(clobber (match_dup 0))
19544 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19547 [(match_scratch:DI 0 "r")
19548 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19549 (clobber (reg:CC FLAGS_REG))])]
19550 "optimize_size || !TARGET_SUB_ESP_8"
19551 [(clobber (match_dup 0))
19552 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19553 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19555 ;; Convert epilogue deallocator to pop.
19557 [(match_scratch:DI 0 "r")
19558 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19559 (clobber (reg:CC FLAGS_REG))
19560 (clobber (mem:BLK (scratch)))])]
19561 "optimize_size || !TARGET_ADD_ESP_4"
19562 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19563 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19564 (clobber (mem:BLK (scratch)))])]
19567 ;; Two pops case is tricky, since pop causes dependency on destination register.
19568 ;; We use two registers if available.
19570 [(match_scratch:DI 0 "r")
19571 (match_scratch:DI 1 "r")
19572 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19573 (clobber (reg:CC FLAGS_REG))
19574 (clobber (mem:BLK (scratch)))])]
19575 "optimize_size || !TARGET_ADD_ESP_8"
19576 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19577 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19578 (clobber (mem:BLK (scratch)))])
19579 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19580 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19584 [(match_scratch:DI 0 "r")
19585 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19586 (clobber (reg:CC FLAGS_REG))
19587 (clobber (mem:BLK (scratch)))])]
19589 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19590 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19591 (clobber (mem:BLK (scratch)))])
19592 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19593 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19596 ;; Convert esp additions to pop.
19598 [(match_scratch:DI 0 "r")
19599 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19600 (clobber (reg:CC FLAGS_REG))])]
19602 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19603 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
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))])]
19614 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19615 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19616 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19617 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19621 [(match_scratch:DI 0 "r")
19622 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19623 (clobber (reg:CC FLAGS_REG))])]
19625 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19626 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19627 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19628 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19631 ;; Convert imul by three, five and nine into lea
19634 [(set (match_operand:SI 0 "register_operand" "")
19635 (mult:SI (match_operand:SI 1 "register_operand" "")
19636 (match_operand:SI 2 "const_int_operand" "")))
19637 (clobber (reg:CC FLAGS_REG))])]
19638 "INTVAL (operands[2]) == 3
19639 || INTVAL (operands[2]) == 5
19640 || INTVAL (operands[2]) == 9"
19641 [(set (match_dup 0)
19642 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19644 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19648 [(set (match_operand:SI 0 "register_operand" "")
19649 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19650 (match_operand:SI 2 "const_int_operand" "")))
19651 (clobber (reg:CC FLAGS_REG))])]
19653 && (INTVAL (operands[2]) == 3
19654 || INTVAL (operands[2]) == 5
19655 || INTVAL (operands[2]) == 9)"
19656 [(set (match_dup 0) (match_dup 1))
19658 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19660 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19664 [(set (match_operand:DI 0 "register_operand" "")
19665 (mult:DI (match_operand:DI 1 "register_operand" "")
19666 (match_operand:DI 2 "const_int_operand" "")))
19667 (clobber (reg:CC FLAGS_REG))])]
19669 && (INTVAL (operands[2]) == 3
19670 || INTVAL (operands[2]) == 5
19671 || INTVAL (operands[2]) == 9)"
19672 [(set (match_dup 0)
19673 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19675 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19679 [(set (match_operand:DI 0 "register_operand" "")
19680 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19681 (match_operand:DI 2 "const_int_operand" "")))
19682 (clobber (reg:CC FLAGS_REG))])]
19685 && (INTVAL (operands[2]) == 3
19686 || INTVAL (operands[2]) == 5
19687 || INTVAL (operands[2]) == 9)"
19688 [(set (match_dup 0) (match_dup 1))
19690 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19692 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19694 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19695 ;; imul $32bit_imm, reg, reg is direct decoded.
19697 [(match_scratch:DI 3 "r")
19698 (parallel [(set (match_operand:DI 0 "register_operand" "")
19699 (mult:DI (match_operand:DI 1 "memory_operand" "")
19700 (match_operand:DI 2 "immediate_operand" "")))
19701 (clobber (reg:CC FLAGS_REG))])]
19702 "TARGET_K8 && !optimize_size
19703 && (GET_CODE (operands[2]) != CONST_INT
19704 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19705 [(set (match_dup 3) (match_dup 1))
19706 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19707 (clobber (reg:CC FLAGS_REG))])]
19711 [(match_scratch:SI 3 "r")
19712 (parallel [(set (match_operand:SI 0 "register_operand" "")
19713 (mult:SI (match_operand:SI 1 "memory_operand" "")
19714 (match_operand:SI 2 "immediate_operand" "")))
19715 (clobber (reg:CC FLAGS_REG))])]
19716 "TARGET_K8 && !optimize_size
19717 && (GET_CODE (operands[2]) != CONST_INT
19718 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19719 [(set (match_dup 3) (match_dup 1))
19720 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19721 (clobber (reg:CC FLAGS_REG))])]
19725 [(match_scratch:SI 3 "r")
19726 (parallel [(set (match_operand:DI 0 "register_operand" "")
19728 (mult:SI (match_operand:SI 1 "memory_operand" "")
19729 (match_operand:SI 2 "immediate_operand" ""))))
19730 (clobber (reg:CC FLAGS_REG))])]
19731 "TARGET_K8 && !optimize_size
19732 && (GET_CODE (operands[2]) != CONST_INT
19733 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19734 [(set (match_dup 3) (match_dup 1))
19735 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19736 (clobber (reg:CC FLAGS_REG))])]
19739 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19740 ;; Convert it into imul reg, reg
19741 ;; It would be better to force assembler to encode instruction using long
19742 ;; immediate, but there is apparently no way to do so.
19744 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19745 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19746 (match_operand:DI 2 "const_int_operand" "")))
19747 (clobber (reg:CC FLAGS_REG))])
19748 (match_scratch:DI 3 "r")]
19749 "TARGET_K8 && !optimize_size
19750 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19751 [(set (match_dup 3) (match_dup 2))
19752 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19753 (clobber (reg:CC FLAGS_REG))])]
19755 if (!rtx_equal_p (operands[0], operands[1]))
19756 emit_move_insn (operands[0], operands[1]);
19760 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19761 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19762 (match_operand:SI 2 "const_int_operand" "")))
19763 (clobber (reg:CC FLAGS_REG))])
19764 (match_scratch:SI 3 "r")]
19765 "TARGET_K8 && !optimize_size
19766 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19767 [(set (match_dup 3) (match_dup 2))
19768 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19769 (clobber (reg:CC FLAGS_REG))])]
19771 if (!rtx_equal_p (operands[0], operands[1]))
19772 emit_move_insn (operands[0], operands[1]);
19776 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19777 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19778 (match_operand:HI 2 "immediate_operand" "")))
19779 (clobber (reg:CC FLAGS_REG))])
19780 (match_scratch:HI 3 "r")]
19781 "TARGET_K8 && !optimize_size"
19782 [(set (match_dup 3) (match_dup 2))
19783 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19784 (clobber (reg:CC FLAGS_REG))])]
19786 if (!rtx_equal_p (operands[0], operands[1]))
19787 emit_move_insn (operands[0], operands[1]);
19790 ;; After splitting up read-modify operations, array accesses with memory
19791 ;; operands might end up in form:
19793 ;; movl 4(%esp), %edx
19795 ;; instead of pre-splitting:
19797 ;; addl 4(%esp), %eax
19799 ;; movl 4(%esp), %edx
19800 ;; leal (%edx,%eax,4), %eax
19803 [(parallel [(set (match_operand 0 "register_operand" "")
19804 (ashift (match_operand 1 "register_operand" "")
19805 (match_operand 2 "const_int_operand" "")))
19806 (clobber (reg:CC FLAGS_REG))])
19807 (set (match_operand 3 "register_operand")
19808 (match_operand 4 "x86_64_general_operand" ""))
19809 (parallel [(set (match_operand 5 "register_operand" "")
19810 (plus (match_operand 6 "register_operand" "")
19811 (match_operand 7 "register_operand" "")))
19812 (clobber (reg:CC FLAGS_REG))])]
19813 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19814 /* Validate MODE for lea. */
19815 && ((!TARGET_PARTIAL_REG_STALL
19816 && (GET_MODE (operands[0]) == QImode
19817 || GET_MODE (operands[0]) == HImode))
19818 || GET_MODE (operands[0]) == SImode
19819 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19820 /* We reorder load and the shift. */
19821 && !rtx_equal_p (operands[1], operands[3])
19822 && !reg_overlap_mentioned_p (operands[0], operands[4])
19823 /* Last PLUS must consist of operand 0 and 3. */
19824 && !rtx_equal_p (operands[0], operands[3])
19825 && (rtx_equal_p (operands[3], operands[6])
19826 || rtx_equal_p (operands[3], operands[7]))
19827 && (rtx_equal_p (operands[0], operands[6])
19828 || rtx_equal_p (operands[0], operands[7]))
19829 /* The intermediate operand 0 must die or be same as output. */
19830 && (rtx_equal_p (operands[0], operands[5])
19831 || peep2_reg_dead_p (3, operands[0]))"
19832 [(set (match_dup 3) (match_dup 4))
19833 (set (match_dup 0) (match_dup 1))]
19835 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19836 int scale = 1 << INTVAL (operands[2]);
19837 rtx index = gen_lowpart (Pmode, operands[1]);
19838 rtx base = gen_lowpart (Pmode, operands[3]);
19839 rtx dest = gen_lowpart (mode, operands[5]);
19841 operands[1] = gen_rtx_PLUS (Pmode, base,
19842 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19844 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19845 operands[0] = dest;
19848 ;; Call-value patterns last so that the wildcard operand does not
19849 ;; disrupt insn-recog's switch tables.
19851 (define_insn "*call_value_pop_0"
19852 [(set (match_operand 0 "" "")
19853 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19854 (match_operand:SI 2 "" "")))
19855 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19856 (match_operand:SI 3 "immediate_operand" "")))]
19859 if (SIBLING_CALL_P (insn))
19862 return "call\t%P1";
19864 [(set_attr "type" "callv")])
19866 (define_insn "*call_value_pop_1"
19867 [(set (match_operand 0 "" "")
19868 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19869 (match_operand:SI 2 "" "")))
19870 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19871 (match_operand:SI 3 "immediate_operand" "i")))]
19874 if (constant_call_address_operand (operands[1], Pmode))
19876 if (SIBLING_CALL_P (insn))
19879 return "call\t%P1";
19881 if (SIBLING_CALL_P (insn))
19884 return "call\t%A1";
19886 [(set_attr "type" "callv")])
19888 (define_insn "*call_value_0"
19889 [(set (match_operand 0 "" "")
19890 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19891 (match_operand:SI 2 "" "")))]
19894 if (SIBLING_CALL_P (insn))
19897 return "call\t%P1";
19899 [(set_attr "type" "callv")])
19901 (define_insn "*call_value_0_rex64"
19902 [(set (match_operand 0 "" "")
19903 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19904 (match_operand:DI 2 "const_int_operand" "")))]
19907 if (SIBLING_CALL_P (insn))
19910 return "call\t%P1";
19912 [(set_attr "type" "callv")])
19914 (define_insn "*call_value_1"
19915 [(set (match_operand 0 "" "")
19916 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19917 (match_operand:SI 2 "" "")))]
19918 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19920 if (constant_call_address_operand (operands[1], Pmode))
19921 return "call\t%P1";
19922 return "call\t%A1";
19924 [(set_attr "type" "callv")])
19926 (define_insn "*sibcall_value_1"
19927 [(set (match_operand 0 "" "")
19928 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19929 (match_operand:SI 2 "" "")))]
19930 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19932 if (constant_call_address_operand (operands[1], Pmode))
19936 [(set_attr "type" "callv")])
19938 (define_insn "*call_value_1_rex64"
19939 [(set (match_operand 0 "" "")
19940 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19941 (match_operand:DI 2 "" "")))]
19942 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19944 if (constant_call_address_operand (operands[1], Pmode))
19945 return "call\t%P1";
19946 return "call\t%A1";
19948 [(set_attr "type" "callv")])
19950 (define_insn "*sibcall_value_1_rex64"
19951 [(set (match_operand 0 "" "")
19952 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19953 (match_operand:DI 2 "" "")))]
19954 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19956 [(set_attr "type" "callv")])
19958 (define_insn "*sibcall_value_1_rex64_v"
19959 [(set (match_operand 0 "" "")
19960 (call (mem:QI (reg:DI 40))
19961 (match_operand:DI 1 "" "")))]
19962 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19964 [(set_attr "type" "callv")])
19966 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19967 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19968 ;; caught for use by garbage collectors and the like. Using an insn that
19969 ;; maps to SIGILL makes it more likely the program will rightfully die.
19970 ;; Keeping with tradition, "6" is in honor of #UD.
19971 (define_insn "trap"
19972 [(trap_if (const_int 1) (const_int 6))]
19975 [(set_attr "length" "2")])
19977 (define_expand "sse_prologue_save"
19978 [(parallel [(set (match_operand:BLK 0 "" "")
19979 (unspec:BLK [(reg:DI 21)
19986 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19987 (use (match_operand:DI 1 "register_operand" ""))
19988 (use (match_operand:DI 2 "immediate_operand" ""))
19989 (use (label_ref:DI (match_operand 3 "" "")))])]
19993 (define_insn "*sse_prologue_save_insn"
19994 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19995 (match_operand:DI 4 "const_int_operand" "n")))
19996 (unspec:BLK [(reg:DI 21)
20003 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20004 (use (match_operand:DI 1 "register_operand" "r"))
20005 (use (match_operand:DI 2 "const_int_operand" "i"))
20006 (use (label_ref:DI (match_operand 3 "" "X")))]
20008 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20009 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20013 operands[0] = gen_rtx_MEM (Pmode,
20014 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20015 output_asm_insn (\"jmp\\t%A1\", operands);
20016 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20018 operands[4] = adjust_address (operands[0], DImode, i*16);
20019 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20020 PUT_MODE (operands[4], TImode);
20021 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20022 output_asm_insn (\"rex\", operands);
20023 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20025 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20026 CODE_LABEL_NUMBER (operands[3]));
20030 [(set_attr "type" "other")
20031 (set_attr "length_immediate" "0")
20032 (set_attr "length_address" "0")
20033 (set_attr "length" "135")
20034 (set_attr "memory" "store")
20035 (set_attr "modrm" "0")
20036 (set_attr "mode" "DI")])
20038 (define_expand "prefetch"
20039 [(prefetch (match_operand 0 "address_operand" "")
20040 (match_operand:SI 1 "const_int_operand" "")
20041 (match_operand:SI 2 "const_int_operand" ""))]
20042 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20044 int rw = INTVAL (operands[1]);
20045 int locality = INTVAL (operands[2]);
20047 gcc_assert (rw == 0 || rw == 1);
20048 gcc_assert (locality >= 0 && locality <= 3);
20049 gcc_assert (GET_MODE (operands[0]) == Pmode
20050 || GET_MODE (operands[0]) == VOIDmode);
20052 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20053 supported by SSE counterpart or the SSE prefetch is not available
20054 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20056 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20057 operands[2] = GEN_INT (3);
20059 operands[1] = const0_rtx;
20062 (define_insn "*prefetch_sse"
20063 [(prefetch (match_operand:SI 0 "address_operand" "p")
20065 (match_operand:SI 1 "const_int_operand" ""))]
20066 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20068 static const char * const patterns[4] = {
20069 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20072 int locality = INTVAL (operands[1]);
20073 gcc_assert (locality >= 0 && locality <= 3);
20075 return patterns[locality];
20077 [(set_attr "type" "sse")
20078 (set_attr "memory" "none")])
20080 (define_insn "*prefetch_sse_rex"
20081 [(prefetch (match_operand:DI 0 "address_operand" "p")
20083 (match_operand:SI 1 "const_int_operand" ""))]
20084 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20086 static const char * const patterns[4] = {
20087 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20090 int locality = INTVAL (operands[1]);
20091 gcc_assert (locality >= 0 && locality <= 3);
20093 return patterns[locality];
20095 [(set_attr "type" "sse")
20096 (set_attr "memory" "none")])
20098 (define_insn "*prefetch_3dnow"
20099 [(prefetch (match_operand:SI 0 "address_operand" "p")
20100 (match_operand:SI 1 "const_int_operand" "n")
20102 "TARGET_3DNOW && !TARGET_64BIT"
20104 if (INTVAL (operands[1]) == 0)
20105 return "prefetch\t%a0";
20107 return "prefetchw\t%a0";
20109 [(set_attr "type" "mmx")
20110 (set_attr "memory" "none")])
20112 (define_insn "*prefetch_3dnow_rex"
20113 [(prefetch (match_operand:DI 0 "address_operand" "p")
20114 (match_operand:SI 1 "const_int_operand" "n")
20116 "TARGET_3DNOW && TARGET_64BIT"
20118 if (INTVAL (operands[1]) == 0)
20119 return "prefetch\t%a0";
20121 return "prefetchw\t%a0";
20123 [(set_attr "type" "mmx")
20124 (set_attr "memory" "none")])
20126 (define_expand "stack_protect_set"
20127 [(match_operand 0 "memory_operand" "")
20128 (match_operand 1 "memory_operand" "")]
20131 #ifdef TARGET_THREAD_SSP_OFFSET
20133 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20134 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20136 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20137 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20140 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20142 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20147 (define_insn "stack_protect_set_si"
20148 [(set (match_operand:SI 0 "memory_operand" "=m")
20149 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20150 (set (match_scratch:SI 2 "=&r") (const_int 0))
20151 (clobber (reg:CC FLAGS_REG))]
20153 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20154 [(set_attr "type" "multi")])
20156 (define_insn "stack_protect_set_di"
20157 [(set (match_operand:DI 0 "memory_operand" "=m")
20158 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20159 (set (match_scratch:DI 2 "=&r") (const_int 0))
20160 (clobber (reg:CC FLAGS_REG))]
20162 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20163 [(set_attr "type" "multi")])
20165 (define_insn "stack_tls_protect_set_si"
20166 [(set (match_operand:SI 0 "memory_operand" "=m")
20167 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20168 (set (match_scratch:SI 2 "=&r") (const_int 0))
20169 (clobber (reg:CC FLAGS_REG))]
20171 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20172 [(set_attr "type" "multi")])
20174 (define_insn "stack_tls_protect_set_di"
20175 [(set (match_operand:DI 0 "memory_operand" "=m")
20176 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20177 (set (match_scratch:DI 2 "=&r") (const_int 0))
20178 (clobber (reg:CC FLAGS_REG))]
20180 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20181 [(set_attr "type" "multi")])
20183 (define_expand "stack_protect_test"
20184 [(match_operand 0 "memory_operand" "")
20185 (match_operand 1 "memory_operand" "")
20186 (match_operand 2 "" "")]
20189 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20190 ix86_compare_op0 = operands[0];
20191 ix86_compare_op1 = operands[1];
20192 ix86_compare_emitted = flags;
20194 #ifdef TARGET_THREAD_SSP_OFFSET
20196 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20197 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20199 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20200 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20203 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20205 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20207 emit_jump_insn (gen_beq (operands[2]));
20211 (define_insn "stack_protect_test_si"
20212 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20213 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20214 (match_operand:SI 2 "memory_operand" "m")]
20216 (clobber (match_scratch:SI 3 "=&r"))]
20218 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20219 [(set_attr "type" "multi")])
20221 (define_insn "stack_protect_test_di"
20222 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20223 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20224 (match_operand:DI 2 "memory_operand" "m")]
20226 (clobber (match_scratch:DI 3 "=&r"))]
20228 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20229 [(set_attr "type" "multi")])
20231 (define_insn "stack_tls_protect_test_si"
20232 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20233 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20234 (match_operand:SI 2 "const_int_operand" "i")]
20235 UNSPEC_SP_TLS_TEST))
20236 (clobber (match_scratch:SI 3 "=r"))]
20238 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20239 [(set_attr "type" "multi")])
20241 (define_insn "stack_tls_protect_test_di"
20242 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20243 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20244 (match_operand:DI 2 "const_int_operand" "i")]
20245 UNSPEC_SP_TLS_TEST))
20246 (clobber (match_scratch:DI 3 "=r"))]
20248 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20249 [(set_attr "type" "multi")])
20253 (include "sync.md")