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 && INTVAL (operands[1]) > 0
7869 && INTVAL (operands[2]) >= 0
7870 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7871 && (GET_MODE (operands[0]) == SImode
7872 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7873 || GET_MODE (operands[0]) == HImode
7874 || GET_MODE (operands[0]) == QImode)"
7877 (define_insn "*testqi_ext_3_rex64"
7878 [(set (reg FLAGS_REG)
7879 (compare (zero_extract:DI
7880 (match_operand 0 "nonimmediate_operand" "rm")
7881 (match_operand:DI 1 "const_int_operand" "")
7882 (match_operand:DI 2 "const_int_operand" ""))
7885 && ix86_match_ccmode (insn, CCNOmode)
7886 && INTVAL (operands[1]) > 0
7887 && INTVAL (operands[2]) >= 0
7888 /* Ensure that resulting mask is zero or sign extended operand. */
7889 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7890 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7891 && INTVAL (operands[1]) > 32))
7892 && (GET_MODE (operands[0]) == SImode
7893 || GET_MODE (operands[0]) == DImode
7894 || GET_MODE (operands[0]) == HImode
7895 || GET_MODE (operands[0]) == QImode)"
7899 [(set (match_operand 0 "flags_reg_operand" "")
7900 (match_operator 1 "compare_operator"
7902 (match_operand 2 "nonimmediate_operand" "")
7903 (match_operand 3 "const_int_operand" "")
7904 (match_operand 4 "const_int_operand" ""))
7906 "ix86_match_ccmode (insn, CCNOmode)"
7907 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7909 rtx val = operands[2];
7910 HOST_WIDE_INT len = INTVAL (operands[3]);
7911 HOST_WIDE_INT pos = INTVAL (operands[4]);
7913 enum machine_mode mode, submode;
7915 mode = GET_MODE (val);
7916 if (GET_CODE (val) == MEM)
7918 /* ??? Combine likes to put non-volatile mem extractions in QImode
7919 no matter the size of the test. So find a mode that works. */
7920 if (! MEM_VOLATILE_P (val))
7922 mode = smallest_mode_for_size (pos + len, MODE_INT);
7923 val = adjust_address (val, mode, 0);
7926 else if (GET_CODE (val) == SUBREG
7927 && (submode = GET_MODE (SUBREG_REG (val)),
7928 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7929 && pos + len <= GET_MODE_BITSIZE (submode))
7931 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7933 val = SUBREG_REG (val);
7935 else if (mode == HImode && pos + len <= 8)
7937 /* Small HImode tests can be converted to QImode. */
7939 val = gen_lowpart (QImode, val);
7942 if (len == HOST_BITS_PER_WIDE_INT)
7945 mask = ((HOST_WIDE_INT)1 << len) - 1;
7948 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7951 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7952 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7953 ;; this is relatively important trick.
7954 ;; Do the conversion only post-reload to avoid limiting of the register class
7957 [(set (match_operand 0 "flags_reg_operand" "")
7958 (match_operator 1 "compare_operator"
7959 [(and (match_operand 2 "register_operand" "")
7960 (match_operand 3 "const_int_operand" ""))
7963 && QI_REG_P (operands[2])
7964 && GET_MODE (operands[2]) != QImode
7965 && ((ix86_match_ccmode (insn, CCZmode)
7966 && !(INTVAL (operands[3]) & ~(255 << 8)))
7967 || (ix86_match_ccmode (insn, CCNOmode)
7968 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7971 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7974 "operands[2] = gen_lowpart (SImode, operands[2]);
7975 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7978 [(set (match_operand 0 "flags_reg_operand" "")
7979 (match_operator 1 "compare_operator"
7980 [(and (match_operand 2 "nonimmediate_operand" "")
7981 (match_operand 3 "const_int_operand" ""))
7984 && GET_MODE (operands[2]) != QImode
7985 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7986 && ((ix86_match_ccmode (insn, CCZmode)
7987 && !(INTVAL (operands[3]) & ~255))
7988 || (ix86_match_ccmode (insn, CCNOmode)
7989 && !(INTVAL (operands[3]) & ~127)))"
7991 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7993 "operands[2] = gen_lowpart (QImode, operands[2]);
7994 operands[3] = gen_lowpart (QImode, operands[3]);")
7997 ;; %%% This used to optimize known byte-wide and operations to memory,
7998 ;; and sometimes to QImode registers. If this is considered useful,
7999 ;; it should be done with splitters.
8001 (define_expand "anddi3"
8002 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8003 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8004 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8005 (clobber (reg:CC FLAGS_REG))]
8007 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8009 (define_insn "*anddi_1_rex64"
8010 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8011 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8012 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8013 (clobber (reg:CC FLAGS_REG))]
8014 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8016 switch (get_attr_type (insn))
8020 enum machine_mode mode;
8022 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8023 if (INTVAL (operands[2]) == 0xff)
8027 gcc_assert (INTVAL (operands[2]) == 0xffff);
8031 operands[1] = gen_lowpart (mode, operands[1]);
8033 return "movz{bq|x}\t{%1,%0|%0, %1}";
8035 return "movz{wq|x}\t{%1,%0|%0, %1}";
8039 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8040 if (get_attr_mode (insn) == MODE_SI)
8041 return "and{l}\t{%k2, %k0|%k0, %k2}";
8043 return "and{q}\t{%2, %0|%0, %2}";
8046 [(set_attr "type" "alu,alu,alu,imovx")
8047 (set_attr "length_immediate" "*,*,*,0")
8048 (set_attr "mode" "SI,DI,DI,DI")])
8050 (define_insn "*anddi_2"
8051 [(set (reg FLAGS_REG)
8052 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8053 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8055 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8056 (and:DI (match_dup 1) (match_dup 2)))]
8057 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8058 && ix86_binary_operator_ok (AND, DImode, operands)"
8060 and{l}\t{%k2, %k0|%k0, %k2}
8061 and{q}\t{%2, %0|%0, %2}
8062 and{q}\t{%2, %0|%0, %2}"
8063 [(set_attr "type" "alu")
8064 (set_attr "mode" "SI,DI,DI")])
8066 (define_expand "andsi3"
8067 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8068 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8069 (match_operand:SI 2 "general_operand" "")))
8070 (clobber (reg:CC FLAGS_REG))]
8072 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8074 (define_insn "*andsi_1"
8075 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8076 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8077 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8078 (clobber (reg:CC FLAGS_REG))]
8079 "ix86_binary_operator_ok (AND, SImode, operands)"
8081 switch (get_attr_type (insn))
8085 enum machine_mode mode;
8087 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8088 if (INTVAL (operands[2]) == 0xff)
8092 gcc_assert (INTVAL (operands[2]) == 0xffff);
8096 operands[1] = gen_lowpart (mode, operands[1]);
8098 return "movz{bl|x}\t{%1,%0|%0, %1}";
8100 return "movz{wl|x}\t{%1,%0|%0, %1}";
8104 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8105 return "and{l}\t{%2, %0|%0, %2}";
8108 [(set_attr "type" "alu,alu,imovx")
8109 (set_attr "length_immediate" "*,*,0")
8110 (set_attr "mode" "SI")])
8113 [(set (match_operand 0 "register_operand" "")
8115 (const_int -65536)))
8116 (clobber (reg:CC FLAGS_REG))]
8117 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8118 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8119 "operands[1] = gen_lowpart (HImode, operands[0]);")
8122 [(set (match_operand 0 "ext_register_operand" "")
8125 (clobber (reg:CC FLAGS_REG))]
8126 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8127 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8128 "operands[1] = gen_lowpart (QImode, operands[0]);")
8131 [(set (match_operand 0 "ext_register_operand" "")
8133 (const_int -65281)))
8134 (clobber (reg:CC FLAGS_REG))]
8135 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8136 [(parallel [(set (zero_extract:SI (match_dup 0)
8140 (zero_extract:SI (match_dup 0)
8143 (zero_extract:SI (match_dup 0)
8146 (clobber (reg:CC FLAGS_REG))])]
8147 "operands[0] = gen_lowpart (SImode, operands[0]);")
8149 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8150 (define_insn "*andsi_1_zext"
8151 [(set (match_operand:DI 0 "register_operand" "=r")
8153 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8154 (match_operand:SI 2 "general_operand" "rim"))))
8155 (clobber (reg:CC FLAGS_REG))]
8156 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8157 "and{l}\t{%2, %k0|%k0, %2}"
8158 [(set_attr "type" "alu")
8159 (set_attr "mode" "SI")])
8161 (define_insn "*andsi_2"
8162 [(set (reg FLAGS_REG)
8163 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8164 (match_operand:SI 2 "general_operand" "rim,ri"))
8166 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8167 (and:SI (match_dup 1) (match_dup 2)))]
8168 "ix86_match_ccmode (insn, CCNOmode)
8169 && ix86_binary_operator_ok (AND, SImode, operands)"
8170 "and{l}\t{%2, %0|%0, %2}"
8171 [(set_attr "type" "alu")
8172 (set_attr "mode" "SI")])
8174 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8175 (define_insn "*andsi_2_zext"
8176 [(set (reg FLAGS_REG)
8177 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8178 (match_operand:SI 2 "general_operand" "rim"))
8180 (set (match_operand:DI 0 "register_operand" "=r")
8181 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8182 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8183 && ix86_binary_operator_ok (AND, SImode, operands)"
8184 "and{l}\t{%2, %k0|%k0, %2}"
8185 [(set_attr "type" "alu")
8186 (set_attr "mode" "SI")])
8188 (define_expand "andhi3"
8189 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8190 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8191 (match_operand:HI 2 "general_operand" "")))
8192 (clobber (reg:CC FLAGS_REG))]
8193 "TARGET_HIMODE_MATH"
8194 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8196 (define_insn "*andhi_1"
8197 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8198 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8199 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8200 (clobber (reg:CC FLAGS_REG))]
8201 "ix86_binary_operator_ok (AND, HImode, operands)"
8203 switch (get_attr_type (insn))
8206 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8207 gcc_assert (INTVAL (operands[2]) == 0xff);
8208 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8211 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8213 return "and{w}\t{%2, %0|%0, %2}";
8216 [(set_attr "type" "alu,alu,imovx")
8217 (set_attr "length_immediate" "*,*,0")
8218 (set_attr "mode" "HI,HI,SI")])
8220 (define_insn "*andhi_2"
8221 [(set (reg FLAGS_REG)
8222 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8223 (match_operand:HI 2 "general_operand" "rim,ri"))
8225 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8226 (and:HI (match_dup 1) (match_dup 2)))]
8227 "ix86_match_ccmode (insn, CCNOmode)
8228 && ix86_binary_operator_ok (AND, HImode, operands)"
8229 "and{w}\t{%2, %0|%0, %2}"
8230 [(set_attr "type" "alu")
8231 (set_attr "mode" "HI")])
8233 (define_expand "andqi3"
8234 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8235 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8236 (match_operand:QI 2 "general_operand" "")))
8237 (clobber (reg:CC FLAGS_REG))]
8238 "TARGET_QIMODE_MATH"
8239 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8241 ;; %%% Potential partial reg stall on alternative 2. What to do?
8242 (define_insn "*andqi_1"
8243 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8244 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8245 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8246 (clobber (reg:CC FLAGS_REG))]
8247 "ix86_binary_operator_ok (AND, QImode, operands)"
8249 and{b}\t{%2, %0|%0, %2}
8250 and{b}\t{%2, %0|%0, %2}
8251 and{l}\t{%k2, %k0|%k0, %k2}"
8252 [(set_attr "type" "alu")
8253 (set_attr "mode" "QI,QI,SI")])
8255 (define_insn "*andqi_1_slp"
8256 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8257 (and:QI (match_dup 0)
8258 (match_operand:QI 1 "general_operand" "qi,qmi")))
8259 (clobber (reg:CC FLAGS_REG))]
8260 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8261 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8262 "and{b}\t{%1, %0|%0, %1}"
8263 [(set_attr "type" "alu1")
8264 (set_attr "mode" "QI")])
8266 (define_insn "*andqi_2_maybe_si"
8267 [(set (reg FLAGS_REG)
8269 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8270 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8272 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8273 (and:QI (match_dup 1) (match_dup 2)))]
8274 "ix86_binary_operator_ok (AND, QImode, operands)
8275 && ix86_match_ccmode (insn,
8276 GET_CODE (operands[2]) == CONST_INT
8277 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8279 if (which_alternative == 2)
8281 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8282 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8283 return "and{l}\t{%2, %k0|%k0, %2}";
8285 return "and{b}\t{%2, %0|%0, %2}";
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "QI,QI,SI")])
8290 (define_insn "*andqi_2"
8291 [(set (reg FLAGS_REG)
8293 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8294 (match_operand:QI 2 "general_operand" "qim,qi"))
8296 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8297 (and:QI (match_dup 1) (match_dup 2)))]
8298 "ix86_match_ccmode (insn, CCNOmode)
8299 && ix86_binary_operator_ok (AND, QImode, operands)"
8300 "and{b}\t{%2, %0|%0, %2}"
8301 [(set_attr "type" "alu")
8302 (set_attr "mode" "QI")])
8304 (define_insn "*andqi_2_slp"
8305 [(set (reg FLAGS_REG)
8307 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8308 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8310 (set (strict_low_part (match_dup 0))
8311 (and:QI (match_dup 0) (match_dup 1)))]
8312 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8313 && ix86_match_ccmode (insn, CCNOmode)
8314 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8315 "and{b}\t{%1, %0|%0, %1}"
8316 [(set_attr "type" "alu1")
8317 (set_attr "mode" "QI")])
8319 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8320 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8321 ;; for a QImode operand, which of course failed.
8323 (define_insn "andqi_ext_0"
8324 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8329 (match_operand 1 "ext_register_operand" "0")
8332 (match_operand 2 "const_int_operand" "n")))
8333 (clobber (reg:CC FLAGS_REG))]
8335 "and{b}\t{%2, %h0|%h0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "length_immediate" "1")
8338 (set_attr "mode" "QI")])
8340 ;; Generated by peephole translating test to and. This shows up
8341 ;; often in fp comparisons.
8343 (define_insn "*andqi_ext_0_cc"
8344 [(set (reg FLAGS_REG)
8348 (match_operand 1 "ext_register_operand" "0")
8351 (match_operand 2 "const_int_operand" "n"))
8353 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8362 "ix86_match_ccmode (insn, CCNOmode)"
8363 "and{b}\t{%2, %h0|%h0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "length_immediate" "1")
8366 (set_attr "mode" "QI")])
8368 (define_insn "*andqi_ext_1"
8369 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8374 (match_operand 1 "ext_register_operand" "0")
8378 (match_operand:QI 2 "general_operand" "Qm"))))
8379 (clobber (reg:CC FLAGS_REG))]
8381 "and{b}\t{%2, %h0|%h0, %2}"
8382 [(set_attr "type" "alu")
8383 (set_attr "length_immediate" "0")
8384 (set_attr "mode" "QI")])
8386 (define_insn "*andqi_ext_1_rex64"
8387 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8392 (match_operand 1 "ext_register_operand" "0")
8396 (match_operand 2 "ext_register_operand" "Q"))))
8397 (clobber (reg:CC FLAGS_REG))]
8399 "and{b}\t{%2, %h0|%h0, %2}"
8400 [(set_attr "type" "alu")
8401 (set_attr "length_immediate" "0")
8402 (set_attr "mode" "QI")])
8404 (define_insn "*andqi_ext_2"
8405 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8410 (match_operand 1 "ext_register_operand" "%0")
8414 (match_operand 2 "ext_register_operand" "Q")
8417 (clobber (reg:CC FLAGS_REG))]
8419 "and{b}\t{%h2, %h0|%h0, %h2}"
8420 [(set_attr "type" "alu")
8421 (set_attr "length_immediate" "0")
8422 (set_attr "mode" "QI")])
8424 ;; Convert wide AND instructions with immediate operand to shorter QImode
8425 ;; equivalents when possible.
8426 ;; Don't do the splitting with memory operands, since it introduces risk
8427 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8428 ;; for size, but that can (should?) be handled by generic code instead.
8430 [(set (match_operand 0 "register_operand" "")
8431 (and (match_operand 1 "register_operand" "")
8432 (match_operand 2 "const_int_operand" "")))
8433 (clobber (reg:CC FLAGS_REG))]
8435 && QI_REG_P (operands[0])
8436 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8437 && !(~INTVAL (operands[2]) & ~(255 << 8))
8438 && GET_MODE (operands[0]) != QImode"
8439 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8440 (and:SI (zero_extract:SI (match_dup 1)
8441 (const_int 8) (const_int 8))
8443 (clobber (reg:CC FLAGS_REG))])]
8444 "operands[0] = gen_lowpart (SImode, operands[0]);
8445 operands[1] = gen_lowpart (SImode, operands[1]);
8446 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8448 ;; Since AND can be encoded with sign extended immediate, this is only
8449 ;; profitable when 7th bit is not set.
8451 [(set (match_operand 0 "register_operand" "")
8452 (and (match_operand 1 "general_operand" "")
8453 (match_operand 2 "const_int_operand" "")))
8454 (clobber (reg:CC FLAGS_REG))]
8456 && ANY_QI_REG_P (operands[0])
8457 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8458 && !(~INTVAL (operands[2]) & ~255)
8459 && !(INTVAL (operands[2]) & 128)
8460 && GET_MODE (operands[0]) != QImode"
8461 [(parallel [(set (strict_low_part (match_dup 0))
8462 (and:QI (match_dup 1)
8464 (clobber (reg:CC FLAGS_REG))])]
8465 "operands[0] = gen_lowpart (QImode, operands[0]);
8466 operands[1] = gen_lowpart (QImode, operands[1]);
8467 operands[2] = gen_lowpart (QImode, operands[2]);")
8469 ;; Logical inclusive OR instructions
8471 ;; %%% This used to optimize known byte-wide and operations to memory.
8472 ;; If this is considered useful, it should be done with splitters.
8474 (define_expand "iordi3"
8475 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8476 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8477 (match_operand:DI 2 "x86_64_general_operand" "")))
8478 (clobber (reg:CC FLAGS_REG))]
8480 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8482 (define_insn "*iordi_1_rex64"
8483 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8484 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8485 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8486 (clobber (reg:CC FLAGS_REG))]
8488 && ix86_binary_operator_ok (IOR, DImode, operands)"
8489 "or{q}\t{%2, %0|%0, %2}"
8490 [(set_attr "type" "alu")
8491 (set_attr "mode" "DI")])
8493 (define_insn "*iordi_2_rex64"
8494 [(set (reg FLAGS_REG)
8495 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8496 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8498 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8499 (ior:DI (match_dup 1) (match_dup 2)))]
8501 && ix86_match_ccmode (insn, CCNOmode)
8502 && ix86_binary_operator_ok (IOR, DImode, operands)"
8503 "or{q}\t{%2, %0|%0, %2}"
8504 [(set_attr "type" "alu")
8505 (set_attr "mode" "DI")])
8507 (define_insn "*iordi_3_rex64"
8508 [(set (reg FLAGS_REG)
8509 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8510 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8512 (clobber (match_scratch:DI 0 "=r"))]
8514 && ix86_match_ccmode (insn, CCNOmode)
8515 && ix86_binary_operator_ok (IOR, DImode, operands)"
8516 "or{q}\t{%2, %0|%0, %2}"
8517 [(set_attr "type" "alu")
8518 (set_attr "mode" "DI")])
8521 (define_expand "iorsi3"
8522 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8523 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8524 (match_operand:SI 2 "general_operand" "")))
8525 (clobber (reg:CC FLAGS_REG))]
8527 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8529 (define_insn "*iorsi_1"
8530 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8531 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8532 (match_operand:SI 2 "general_operand" "ri,rmi")))
8533 (clobber (reg:CC FLAGS_REG))]
8534 "ix86_binary_operator_ok (IOR, SImode, operands)"
8535 "or{l}\t{%2, %0|%0, %2}"
8536 [(set_attr "type" "alu")
8537 (set_attr "mode" "SI")])
8539 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8540 (define_insn "*iorsi_1_zext"
8541 [(set (match_operand:DI 0 "register_operand" "=rm")
8543 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8544 (match_operand:SI 2 "general_operand" "rim"))))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8547 "or{l}\t{%2, %k0|%k0, %2}"
8548 [(set_attr "type" "alu")
8549 (set_attr "mode" "SI")])
8551 (define_insn "*iorsi_1_zext_imm"
8552 [(set (match_operand:DI 0 "register_operand" "=rm")
8553 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8554 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8555 (clobber (reg:CC FLAGS_REG))]
8557 "or{l}\t{%2, %k0|%k0, %2}"
8558 [(set_attr "type" "alu")
8559 (set_attr "mode" "SI")])
8561 (define_insn "*iorsi_2"
8562 [(set (reg FLAGS_REG)
8563 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8564 (match_operand:SI 2 "general_operand" "rim,ri"))
8566 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8567 (ior:SI (match_dup 1) (match_dup 2)))]
8568 "ix86_match_ccmode (insn, CCNOmode)
8569 && ix86_binary_operator_ok (IOR, SImode, operands)"
8570 "or{l}\t{%2, %0|%0, %2}"
8571 [(set_attr "type" "alu")
8572 (set_attr "mode" "SI")])
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 ;; ??? Special case for immediate operand is missing - it is tricky.
8576 (define_insn "*iorsi_2_zext"
8577 [(set (reg FLAGS_REG)
8578 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579 (match_operand:SI 2 "general_operand" "rim"))
8581 (set (match_operand:DI 0 "register_operand" "=r")
8582 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584 && ix86_binary_operator_ok (IOR, SImode, operands)"
8585 "or{l}\t{%2, %k0|%k0, %2}"
8586 [(set_attr "type" "alu")
8587 (set_attr "mode" "SI")])
8589 (define_insn "*iorsi_2_zext_imm"
8590 [(set (reg FLAGS_REG)
8591 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8592 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8594 (set (match_operand:DI 0 "register_operand" "=r")
8595 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8596 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8597 && ix86_binary_operator_ok (IOR, SImode, operands)"
8598 "or{l}\t{%2, %k0|%k0, %2}"
8599 [(set_attr "type" "alu")
8600 (set_attr "mode" "SI")])
8602 (define_insn "*iorsi_3"
8603 [(set (reg FLAGS_REG)
8604 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8605 (match_operand:SI 2 "general_operand" "rim"))
8607 (clobber (match_scratch:SI 0 "=r"))]
8608 "ix86_match_ccmode (insn, CCNOmode)
8609 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8610 "or{l}\t{%2, %0|%0, %2}"
8611 [(set_attr "type" "alu")
8612 (set_attr "mode" "SI")])
8614 (define_expand "iorhi3"
8615 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8616 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8617 (match_operand:HI 2 "general_operand" "")))
8618 (clobber (reg:CC FLAGS_REG))]
8619 "TARGET_HIMODE_MATH"
8620 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8622 (define_insn "*iorhi_1"
8623 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8624 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8625 (match_operand:HI 2 "general_operand" "rmi,ri")))
8626 (clobber (reg:CC FLAGS_REG))]
8627 "ix86_binary_operator_ok (IOR, HImode, operands)"
8628 "or{w}\t{%2, %0|%0, %2}"
8629 [(set_attr "type" "alu")
8630 (set_attr "mode" "HI")])
8632 (define_insn "*iorhi_2"
8633 [(set (reg FLAGS_REG)
8634 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8635 (match_operand:HI 2 "general_operand" "rim,ri"))
8637 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8638 (ior:HI (match_dup 1) (match_dup 2)))]
8639 "ix86_match_ccmode (insn, CCNOmode)
8640 && ix86_binary_operator_ok (IOR, HImode, operands)"
8641 "or{w}\t{%2, %0|%0, %2}"
8642 [(set_attr "type" "alu")
8643 (set_attr "mode" "HI")])
8645 (define_insn "*iorhi_3"
8646 [(set (reg FLAGS_REG)
8647 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8648 (match_operand:HI 2 "general_operand" "rim"))
8650 (clobber (match_scratch:HI 0 "=r"))]
8651 "ix86_match_ccmode (insn, CCNOmode)
8652 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8653 "or{w}\t{%2, %0|%0, %2}"
8654 [(set_attr "type" "alu")
8655 (set_attr "mode" "HI")])
8657 (define_expand "iorqi3"
8658 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8659 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8660 (match_operand:QI 2 "general_operand" "")))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "TARGET_QIMODE_MATH"
8663 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8665 ;; %%% Potential partial reg stall on alternative 2. What to do?
8666 (define_insn "*iorqi_1"
8667 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8668 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8669 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8670 (clobber (reg:CC FLAGS_REG))]
8671 "ix86_binary_operator_ok (IOR, QImode, operands)"
8673 or{b}\t{%2, %0|%0, %2}
8674 or{b}\t{%2, %0|%0, %2}
8675 or{l}\t{%k2, %k0|%k0, %k2}"
8676 [(set_attr "type" "alu")
8677 (set_attr "mode" "QI,QI,SI")])
8679 (define_insn "*iorqi_1_slp"
8680 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8681 (ior:QI (match_dup 0)
8682 (match_operand:QI 1 "general_operand" "qmi,qi")))
8683 (clobber (reg:CC FLAGS_REG))]
8684 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8685 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8686 "or{b}\t{%1, %0|%0, %1}"
8687 [(set_attr "type" "alu1")
8688 (set_attr "mode" "QI")])
8690 (define_insn "*iorqi_2"
8691 [(set (reg FLAGS_REG)
8692 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8693 (match_operand:QI 2 "general_operand" "qim,qi"))
8695 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8696 (ior:QI (match_dup 1) (match_dup 2)))]
8697 "ix86_match_ccmode (insn, CCNOmode)
8698 && ix86_binary_operator_ok (IOR, QImode, operands)"
8699 "or{b}\t{%2, %0|%0, %2}"
8700 [(set_attr "type" "alu")
8701 (set_attr "mode" "QI")])
8703 (define_insn "*iorqi_2_slp"
8704 [(set (reg FLAGS_REG)
8705 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8706 (match_operand:QI 1 "general_operand" "qim,qi"))
8708 (set (strict_low_part (match_dup 0))
8709 (ior:QI (match_dup 0) (match_dup 1)))]
8710 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8711 && ix86_match_ccmode (insn, CCNOmode)
8712 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8713 "or{b}\t{%1, %0|%0, %1}"
8714 [(set_attr "type" "alu1")
8715 (set_attr "mode" "QI")])
8717 (define_insn "*iorqi_3"
8718 [(set (reg FLAGS_REG)
8719 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8720 (match_operand:QI 2 "general_operand" "qim"))
8722 (clobber (match_scratch:QI 0 "=q"))]
8723 "ix86_match_ccmode (insn, CCNOmode)
8724 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8725 "or{b}\t{%2, %0|%0, %2}"
8726 [(set_attr "type" "alu")
8727 (set_attr "mode" "QI")])
8729 (define_insn "iorqi_ext_0"
8730 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8735 (match_operand 1 "ext_register_operand" "0")
8738 (match_operand 2 "const_int_operand" "n")))
8739 (clobber (reg:CC FLAGS_REG))]
8740 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8741 "or{b}\t{%2, %h0|%h0, %2}"
8742 [(set_attr "type" "alu")
8743 (set_attr "length_immediate" "1")
8744 (set_attr "mode" "QI")])
8746 (define_insn "*iorqi_ext_1"
8747 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8752 (match_operand 1 "ext_register_operand" "0")
8756 (match_operand:QI 2 "general_operand" "Qm"))))
8757 (clobber (reg:CC FLAGS_REG))]
8759 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8760 "or{b}\t{%2, %h0|%h0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "length_immediate" "0")
8763 (set_attr "mode" "QI")])
8765 (define_insn "*iorqi_ext_1_rex64"
8766 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8771 (match_operand 1 "ext_register_operand" "0")
8775 (match_operand 2 "ext_register_operand" "Q"))))
8776 (clobber (reg:CC FLAGS_REG))]
8778 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8779 "or{b}\t{%2, %h0|%h0, %2}"
8780 [(set_attr "type" "alu")
8781 (set_attr "length_immediate" "0")
8782 (set_attr "mode" "QI")])
8784 (define_insn "*iorqi_ext_2"
8785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8789 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8792 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8795 (clobber (reg:CC FLAGS_REG))]
8796 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8797 "ior{b}\t{%h2, %h0|%h0, %h2}"
8798 [(set_attr "type" "alu")
8799 (set_attr "length_immediate" "0")
8800 (set_attr "mode" "QI")])
8803 [(set (match_operand 0 "register_operand" "")
8804 (ior (match_operand 1 "register_operand" "")
8805 (match_operand 2 "const_int_operand" "")))
8806 (clobber (reg:CC FLAGS_REG))]
8808 && QI_REG_P (operands[0])
8809 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8810 && !(INTVAL (operands[2]) & ~(255 << 8))
8811 && GET_MODE (operands[0]) != QImode"
8812 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8813 (ior:SI (zero_extract:SI (match_dup 1)
8814 (const_int 8) (const_int 8))
8816 (clobber (reg:CC FLAGS_REG))])]
8817 "operands[0] = gen_lowpart (SImode, operands[0]);
8818 operands[1] = gen_lowpart (SImode, operands[1]);
8819 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8821 ;; Since OR can be encoded with sign extended immediate, this is only
8822 ;; profitable when 7th bit is set.
8824 [(set (match_operand 0 "register_operand" "")
8825 (ior (match_operand 1 "general_operand" "")
8826 (match_operand 2 "const_int_operand" "")))
8827 (clobber (reg:CC FLAGS_REG))]
8829 && ANY_QI_REG_P (operands[0])
8830 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8831 && !(INTVAL (operands[2]) & ~255)
8832 && (INTVAL (operands[2]) & 128)
8833 && GET_MODE (operands[0]) != QImode"
8834 [(parallel [(set (strict_low_part (match_dup 0))
8835 (ior:QI (match_dup 1)
8837 (clobber (reg:CC FLAGS_REG))])]
8838 "operands[0] = gen_lowpart (QImode, operands[0]);
8839 operands[1] = gen_lowpart (QImode, operands[1]);
8840 operands[2] = gen_lowpart (QImode, operands[2]);")
8842 ;; Logical XOR instructions
8844 ;; %%% This used to optimize known byte-wide and operations to memory.
8845 ;; If this is considered useful, it should be done with splitters.
8847 (define_expand "xordi3"
8848 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8849 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8850 (match_operand:DI 2 "x86_64_general_operand" "")))
8851 (clobber (reg:CC FLAGS_REG))]
8853 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8855 (define_insn "*xordi_1_rex64"
8856 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8857 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8858 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8859 (clobber (reg:CC FLAGS_REG))]
8861 && ix86_binary_operator_ok (XOR, DImode, operands)"
8863 xor{q}\t{%2, %0|%0, %2}
8864 xor{q}\t{%2, %0|%0, %2}"
8865 [(set_attr "type" "alu")
8866 (set_attr "mode" "DI,DI")])
8868 (define_insn "*xordi_2_rex64"
8869 [(set (reg FLAGS_REG)
8870 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8871 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8873 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8874 (xor:DI (match_dup 1) (match_dup 2)))]
8876 && ix86_match_ccmode (insn, CCNOmode)
8877 && ix86_binary_operator_ok (XOR, DImode, operands)"
8879 xor{q}\t{%2, %0|%0, %2}
8880 xor{q}\t{%2, %0|%0, %2}"
8881 [(set_attr "type" "alu")
8882 (set_attr "mode" "DI,DI")])
8884 (define_insn "*xordi_3_rex64"
8885 [(set (reg FLAGS_REG)
8886 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8887 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8889 (clobber (match_scratch:DI 0 "=r"))]
8891 && ix86_match_ccmode (insn, CCNOmode)
8892 && ix86_binary_operator_ok (XOR, DImode, operands)"
8893 "xor{q}\t{%2, %0|%0, %2}"
8894 [(set_attr "type" "alu")
8895 (set_attr "mode" "DI")])
8897 (define_expand "xorsi3"
8898 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8899 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8900 (match_operand:SI 2 "general_operand" "")))
8901 (clobber (reg:CC FLAGS_REG))]
8903 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8905 (define_insn "*xorsi_1"
8906 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8907 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8908 (match_operand:SI 2 "general_operand" "ri,rm")))
8909 (clobber (reg:CC FLAGS_REG))]
8910 "ix86_binary_operator_ok (XOR, SImode, operands)"
8911 "xor{l}\t{%2, %0|%0, %2}"
8912 [(set_attr "type" "alu")
8913 (set_attr "mode" "SI")])
8915 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8916 ;; Add speccase for immediates
8917 (define_insn "*xorsi_1_zext"
8918 [(set (match_operand:DI 0 "register_operand" "=r")
8920 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8921 (match_operand:SI 2 "general_operand" "rim"))))
8922 (clobber (reg:CC FLAGS_REG))]
8923 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8924 "xor{l}\t{%2, %k0|%k0, %2}"
8925 [(set_attr "type" "alu")
8926 (set_attr "mode" "SI")])
8928 (define_insn "*xorsi_1_zext_imm"
8929 [(set (match_operand:DI 0 "register_operand" "=r")
8930 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8931 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8932 (clobber (reg:CC FLAGS_REG))]
8933 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8934 "xor{l}\t{%2, %k0|%k0, %2}"
8935 [(set_attr "type" "alu")
8936 (set_attr "mode" "SI")])
8938 (define_insn "*xorsi_2"
8939 [(set (reg FLAGS_REG)
8940 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8941 (match_operand:SI 2 "general_operand" "rim,ri"))
8943 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8944 (xor:SI (match_dup 1) (match_dup 2)))]
8945 "ix86_match_ccmode (insn, CCNOmode)
8946 && ix86_binary_operator_ok (XOR, SImode, operands)"
8947 "xor{l}\t{%2, %0|%0, %2}"
8948 [(set_attr "type" "alu")
8949 (set_attr "mode" "SI")])
8951 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8952 ;; ??? Special case for immediate operand is missing - it is tricky.
8953 (define_insn "*xorsi_2_zext"
8954 [(set (reg FLAGS_REG)
8955 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956 (match_operand:SI 2 "general_operand" "rim"))
8958 (set (match_operand:DI 0 "register_operand" "=r")
8959 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8960 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8961 && ix86_binary_operator_ok (XOR, SImode, operands)"
8962 "xor{l}\t{%2, %k0|%k0, %2}"
8963 [(set_attr "type" "alu")
8964 (set_attr "mode" "SI")])
8966 (define_insn "*xorsi_2_zext_imm"
8967 [(set (reg FLAGS_REG)
8968 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8969 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8971 (set (match_operand:DI 0 "register_operand" "=r")
8972 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8973 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8974 && ix86_binary_operator_ok (XOR, SImode, operands)"
8975 "xor{l}\t{%2, %k0|%k0, %2}"
8976 [(set_attr "type" "alu")
8977 (set_attr "mode" "SI")])
8979 (define_insn "*xorsi_3"
8980 [(set (reg FLAGS_REG)
8981 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8982 (match_operand:SI 2 "general_operand" "rim"))
8984 (clobber (match_scratch:SI 0 "=r"))]
8985 "ix86_match_ccmode (insn, CCNOmode)
8986 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8987 "xor{l}\t{%2, %0|%0, %2}"
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "SI")])
8991 (define_expand "xorhi3"
8992 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8993 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8994 (match_operand:HI 2 "general_operand" "")))
8995 (clobber (reg:CC FLAGS_REG))]
8996 "TARGET_HIMODE_MATH"
8997 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8999 (define_insn "*xorhi_1"
9000 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9001 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9002 (match_operand:HI 2 "general_operand" "rmi,ri")))
9003 (clobber (reg:CC FLAGS_REG))]
9004 "ix86_binary_operator_ok (XOR, HImode, operands)"
9005 "xor{w}\t{%2, %0|%0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "HI")])
9009 (define_insn "*xorhi_2"
9010 [(set (reg FLAGS_REG)
9011 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9012 (match_operand:HI 2 "general_operand" "rim,ri"))
9014 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9015 (xor:HI (match_dup 1) (match_dup 2)))]
9016 "ix86_match_ccmode (insn, CCNOmode)
9017 && ix86_binary_operator_ok (XOR, HImode, operands)"
9018 "xor{w}\t{%2, %0|%0, %2}"
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "HI")])
9022 (define_insn "*xorhi_3"
9023 [(set (reg FLAGS_REG)
9024 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9025 (match_operand:HI 2 "general_operand" "rim"))
9027 (clobber (match_scratch:HI 0 "=r"))]
9028 "ix86_match_ccmode (insn, CCNOmode)
9029 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9030 "xor{w}\t{%2, %0|%0, %2}"
9031 [(set_attr "type" "alu")
9032 (set_attr "mode" "HI")])
9034 (define_expand "xorqi3"
9035 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9036 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9037 (match_operand:QI 2 "general_operand" "")))
9038 (clobber (reg:CC FLAGS_REG))]
9039 "TARGET_QIMODE_MATH"
9040 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9042 ;; %%% Potential partial reg stall on alternative 2. What to do?
9043 (define_insn "*xorqi_1"
9044 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9045 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9046 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9047 (clobber (reg:CC FLAGS_REG))]
9048 "ix86_binary_operator_ok (XOR, QImode, operands)"
9050 xor{b}\t{%2, %0|%0, %2}
9051 xor{b}\t{%2, %0|%0, %2}
9052 xor{l}\t{%k2, %k0|%k0, %k2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "QI,QI,SI")])
9056 (define_insn "*xorqi_1_slp"
9057 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9058 (xor:QI (match_dup 0)
9059 (match_operand:QI 1 "general_operand" "qi,qmi")))
9060 (clobber (reg:CC FLAGS_REG))]
9061 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9062 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9063 "xor{b}\t{%1, %0|%0, %1}"
9064 [(set_attr "type" "alu1")
9065 (set_attr "mode" "QI")])
9067 (define_insn "xorqi_ext_0"
9068 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9073 (match_operand 1 "ext_register_operand" "0")
9076 (match_operand 2 "const_int_operand" "n")))
9077 (clobber (reg:CC FLAGS_REG))]
9078 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9079 "xor{b}\t{%2, %h0|%h0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "length_immediate" "1")
9082 (set_attr "mode" "QI")])
9084 (define_insn "*xorqi_ext_1"
9085 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9090 (match_operand 1 "ext_register_operand" "0")
9094 (match_operand:QI 2 "general_operand" "Qm"))))
9095 (clobber (reg:CC FLAGS_REG))]
9097 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9098 "xor{b}\t{%2, %h0|%h0, %2}"
9099 [(set_attr "type" "alu")
9100 (set_attr "length_immediate" "0")
9101 (set_attr "mode" "QI")])
9103 (define_insn "*xorqi_ext_1_rex64"
9104 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9109 (match_operand 1 "ext_register_operand" "0")
9113 (match_operand 2 "ext_register_operand" "Q"))))
9114 (clobber (reg:CC FLAGS_REG))]
9116 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9117 "xor{b}\t{%2, %h0|%h0, %2}"
9118 [(set_attr "type" "alu")
9119 (set_attr "length_immediate" "0")
9120 (set_attr "mode" "QI")])
9122 (define_insn "*xorqi_ext_2"
9123 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9127 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9130 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9133 (clobber (reg:CC FLAGS_REG))]
9134 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9135 "xor{b}\t{%h2, %h0|%h0, %h2}"
9136 [(set_attr "type" "alu")
9137 (set_attr "length_immediate" "0")
9138 (set_attr "mode" "QI")])
9140 (define_insn "*xorqi_cc_1"
9141 [(set (reg FLAGS_REG)
9143 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9144 (match_operand:QI 2 "general_operand" "qim,qi"))
9146 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9147 (xor:QI (match_dup 1) (match_dup 2)))]
9148 "ix86_match_ccmode (insn, CCNOmode)
9149 && ix86_binary_operator_ok (XOR, QImode, operands)"
9150 "xor{b}\t{%2, %0|%0, %2}"
9151 [(set_attr "type" "alu")
9152 (set_attr "mode" "QI")])
9154 (define_insn "*xorqi_2_slp"
9155 [(set (reg FLAGS_REG)
9156 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9157 (match_operand:QI 1 "general_operand" "qim,qi"))
9159 (set (strict_low_part (match_dup 0))
9160 (xor:QI (match_dup 0) (match_dup 1)))]
9161 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9162 && ix86_match_ccmode (insn, CCNOmode)
9163 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9164 "xor{b}\t{%1, %0|%0, %1}"
9165 [(set_attr "type" "alu1")
9166 (set_attr "mode" "QI")])
9168 (define_insn "*xorqi_cc_2"
9169 [(set (reg FLAGS_REG)
9171 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9172 (match_operand:QI 2 "general_operand" "qim"))
9174 (clobber (match_scratch:QI 0 "=q"))]
9175 "ix86_match_ccmode (insn, CCNOmode)
9176 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9177 "xor{b}\t{%2, %0|%0, %2}"
9178 [(set_attr "type" "alu")
9179 (set_attr "mode" "QI")])
9181 (define_insn "*xorqi_cc_ext_1"
9182 [(set (reg FLAGS_REG)
9186 (match_operand 1 "ext_register_operand" "0")
9189 (match_operand:QI 2 "general_operand" "qmn"))
9191 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9195 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9197 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9198 "xor{b}\t{%2, %h0|%h0, %2}"
9199 [(set_attr "type" "alu")
9200 (set_attr "mode" "QI")])
9202 (define_insn "*xorqi_cc_ext_1_rex64"
9203 [(set (reg FLAGS_REG)
9207 (match_operand 1 "ext_register_operand" "0")
9210 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9212 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9216 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9218 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9219 "xor{b}\t{%2, %h0|%h0, %2}"
9220 [(set_attr "type" "alu")
9221 (set_attr "mode" "QI")])
9223 (define_expand "xorqi_cc_ext_1"
9225 (set (reg:CCNO FLAGS_REG)
9229 (match_operand 1 "ext_register_operand" "")
9232 (match_operand:QI 2 "general_operand" ""))
9234 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9238 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9244 [(set (match_operand 0 "register_operand" "")
9245 (xor (match_operand 1 "register_operand" "")
9246 (match_operand 2 "const_int_operand" "")))
9247 (clobber (reg:CC FLAGS_REG))]
9249 && QI_REG_P (operands[0])
9250 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9251 && !(INTVAL (operands[2]) & ~(255 << 8))
9252 && GET_MODE (operands[0]) != QImode"
9253 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9254 (xor:SI (zero_extract:SI (match_dup 1)
9255 (const_int 8) (const_int 8))
9257 (clobber (reg:CC FLAGS_REG))])]
9258 "operands[0] = gen_lowpart (SImode, operands[0]);
9259 operands[1] = gen_lowpart (SImode, operands[1]);
9260 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9262 ;; Since XOR can be encoded with sign extended immediate, this is only
9263 ;; profitable when 7th bit is set.
9265 [(set (match_operand 0 "register_operand" "")
9266 (xor (match_operand 1 "general_operand" "")
9267 (match_operand 2 "const_int_operand" "")))
9268 (clobber (reg:CC FLAGS_REG))]
9270 && ANY_QI_REG_P (operands[0])
9271 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9272 && !(INTVAL (operands[2]) & ~255)
9273 && (INTVAL (operands[2]) & 128)
9274 && GET_MODE (operands[0]) != QImode"
9275 [(parallel [(set (strict_low_part (match_dup 0))
9276 (xor:QI (match_dup 1)
9278 (clobber (reg:CC FLAGS_REG))])]
9279 "operands[0] = gen_lowpart (QImode, operands[0]);
9280 operands[1] = gen_lowpart (QImode, operands[1]);
9281 operands[2] = gen_lowpart (QImode, operands[2]);")
9283 ;; Negation instructions
9285 (define_expand "negti2"
9286 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9287 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9288 (clobber (reg:CC FLAGS_REG))])]
9290 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9292 (define_insn "*negti2_1"
9293 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9294 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9295 (clobber (reg:CC FLAGS_REG))]
9297 && ix86_unary_operator_ok (NEG, TImode, operands)"
9301 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9302 (neg:TI (match_operand:TI 1 "general_operand" "")))
9303 (clobber (reg:CC FLAGS_REG))]
9304 "TARGET_64BIT && reload_completed"
9306 [(set (reg:CCZ FLAGS_REG)
9307 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9308 (set (match_dup 0) (neg:DI (match_dup 2)))])
9311 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9314 (clobber (reg:CC FLAGS_REG))])
9317 (neg:DI (match_dup 1)))
9318 (clobber (reg:CC FLAGS_REG))])]
9319 "split_ti (operands+1, 1, operands+2, operands+3);
9320 split_ti (operands+0, 1, operands+0, operands+1);")
9322 (define_expand "negdi2"
9323 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9324 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9325 (clobber (reg:CC FLAGS_REG))])]
9327 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9329 (define_insn "*negdi2_1"
9330 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9331 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9332 (clobber (reg:CC FLAGS_REG))]
9334 && ix86_unary_operator_ok (NEG, DImode, operands)"
9338 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9339 (neg:DI (match_operand:DI 1 "general_operand" "")))
9340 (clobber (reg:CC FLAGS_REG))]
9341 "!TARGET_64BIT && reload_completed"
9343 [(set (reg:CCZ FLAGS_REG)
9344 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9345 (set (match_dup 0) (neg:SI (match_dup 2)))])
9348 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9351 (clobber (reg:CC FLAGS_REG))])
9354 (neg:SI (match_dup 1)))
9355 (clobber (reg:CC FLAGS_REG))])]
9356 "split_di (operands+1, 1, operands+2, operands+3);
9357 split_di (operands+0, 1, operands+0, operands+1);")
9359 (define_insn "*negdi2_1_rex64"
9360 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9361 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9362 (clobber (reg:CC FLAGS_REG))]
9363 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9365 [(set_attr "type" "negnot")
9366 (set_attr "mode" "DI")])
9368 ;; The problem with neg is that it does not perform (compare x 0),
9369 ;; it really performs (compare 0 x), which leaves us with the zero
9370 ;; flag being the only useful item.
9372 (define_insn "*negdi2_cmpz_rex64"
9373 [(set (reg:CCZ FLAGS_REG)
9374 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9376 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9377 (neg:DI (match_dup 1)))]
9378 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9380 [(set_attr "type" "negnot")
9381 (set_attr "mode" "DI")])
9384 (define_expand "negsi2"
9385 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9386 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9387 (clobber (reg:CC FLAGS_REG))])]
9389 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9391 (define_insn "*negsi2_1"
9392 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9393 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9394 (clobber (reg:CC FLAGS_REG))]
9395 "ix86_unary_operator_ok (NEG, SImode, operands)"
9397 [(set_attr "type" "negnot")
9398 (set_attr "mode" "SI")])
9400 ;; Combine is quite creative about this pattern.
9401 (define_insn "*negsi2_1_zext"
9402 [(set (match_operand:DI 0 "register_operand" "=r")
9403 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9406 (clobber (reg:CC FLAGS_REG))]
9407 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9409 [(set_attr "type" "negnot")
9410 (set_attr "mode" "SI")])
9412 ;; The problem with neg is that it does not perform (compare x 0),
9413 ;; it really performs (compare 0 x), which leaves us with the zero
9414 ;; flag being the only useful item.
9416 (define_insn "*negsi2_cmpz"
9417 [(set (reg:CCZ FLAGS_REG)
9418 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9420 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9421 (neg:SI (match_dup 1)))]
9422 "ix86_unary_operator_ok (NEG, SImode, operands)"
9424 [(set_attr "type" "negnot")
9425 (set_attr "mode" "SI")])
9427 (define_insn "*negsi2_cmpz_zext"
9428 [(set (reg:CCZ FLAGS_REG)
9429 (compare:CCZ (lshiftrt:DI
9431 (match_operand:DI 1 "register_operand" "0")
9435 (set (match_operand:DI 0 "register_operand" "=r")
9436 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9439 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9441 [(set_attr "type" "negnot")
9442 (set_attr "mode" "SI")])
9444 (define_expand "neghi2"
9445 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9446 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9447 (clobber (reg:CC FLAGS_REG))])]
9448 "TARGET_HIMODE_MATH"
9449 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9451 (define_insn "*neghi2_1"
9452 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9453 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9454 (clobber (reg:CC FLAGS_REG))]
9455 "ix86_unary_operator_ok (NEG, HImode, operands)"
9457 [(set_attr "type" "negnot")
9458 (set_attr "mode" "HI")])
9460 (define_insn "*neghi2_cmpz"
9461 [(set (reg:CCZ FLAGS_REG)
9462 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9464 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9465 (neg:HI (match_dup 1)))]
9466 "ix86_unary_operator_ok (NEG, HImode, operands)"
9468 [(set_attr "type" "negnot")
9469 (set_attr "mode" "HI")])
9471 (define_expand "negqi2"
9472 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9473 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9474 (clobber (reg:CC FLAGS_REG))])]
9475 "TARGET_QIMODE_MATH"
9476 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9478 (define_insn "*negqi2_1"
9479 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9480 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9481 (clobber (reg:CC FLAGS_REG))]
9482 "ix86_unary_operator_ok (NEG, QImode, operands)"
9484 [(set_attr "type" "negnot")
9485 (set_attr "mode" "QI")])
9487 (define_insn "*negqi2_cmpz"
9488 [(set (reg:CCZ FLAGS_REG)
9489 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9491 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9492 (neg:QI (match_dup 1)))]
9493 "ix86_unary_operator_ok (NEG, QImode, operands)"
9495 [(set_attr "type" "negnot")
9496 (set_attr "mode" "QI")])
9498 ;; Changing of sign for FP values is doable using integer unit too.
9500 (define_expand "negsf2"
9501 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9502 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9503 "TARGET_80387 || TARGET_SSE_MATH"
9504 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9506 (define_expand "abssf2"
9507 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9508 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9509 "TARGET_80387 || TARGET_SSE_MATH"
9510 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9512 (define_insn "*absnegsf2_mixed"
9513 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9514 (match_operator:SF 3 "absneg_operator"
9515 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9516 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9517 (clobber (reg:CC FLAGS_REG))]
9518 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9519 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9522 (define_insn "*absnegsf2_sse"
9523 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9524 (match_operator:SF 3 "absneg_operator"
9525 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9526 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9527 (clobber (reg:CC FLAGS_REG))]
9529 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9532 (define_insn "*absnegsf2_i387"
9533 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9534 (match_operator:SF 3 "absneg_operator"
9535 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9536 (use (match_operand 2 "" ""))
9537 (clobber (reg:CC FLAGS_REG))]
9538 "TARGET_80387 && !TARGET_SSE_MATH
9539 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9542 (define_expand "copysignsf3"
9543 [(match_operand:SF 0 "register_operand" "")
9544 (match_operand:SF 1 "nonmemory_operand" "")
9545 (match_operand:SF 2 "register_operand" "")]
9548 ix86_expand_copysign (operands);
9552 (define_insn_and_split "copysignsf3_const"
9553 [(set (match_operand:SF 0 "register_operand" "=x")
9555 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9556 (match_operand:SF 2 "register_operand" "0")
9557 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9561 "&& reload_completed"
9564 ix86_split_copysign_const (operands);
9568 (define_insn "copysignsf3_var"
9569 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9571 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9572 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9573 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9574 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9576 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9581 [(set (match_operand:SF 0 "register_operand" "")
9583 [(match_operand:SF 2 "register_operand" "")
9584 (match_operand:SF 3 "register_operand" "")
9585 (match_operand:V4SF 4 "" "")
9586 (match_operand:V4SF 5 "" "")]
9588 (clobber (match_scratch:V4SF 1 ""))]
9589 "TARGET_SSE_MATH && reload_completed"
9592 ix86_split_copysign_var (operands);
9596 (define_expand "negdf2"
9597 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9598 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9599 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9600 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9602 (define_expand "absdf2"
9603 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9604 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9605 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9606 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9608 (define_insn "*absnegdf2_mixed"
9609 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9610 (match_operator:DF 3 "absneg_operator"
9611 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9612 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9613 (clobber (reg:CC FLAGS_REG))]
9614 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9615 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9618 (define_insn "*absnegdf2_sse"
9619 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9620 (match_operator:DF 3 "absneg_operator"
9621 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9622 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9623 (clobber (reg:CC FLAGS_REG))]
9624 "TARGET_SSE2 && TARGET_SSE_MATH
9625 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9628 (define_insn "*absnegdf2_i387"
9629 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9630 (match_operator:DF 3 "absneg_operator"
9631 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9632 (use (match_operand 2 "" ""))
9633 (clobber (reg:CC FLAGS_REG))]
9634 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9635 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9638 (define_expand "copysigndf3"
9639 [(match_operand:DF 0 "register_operand" "")
9640 (match_operand:DF 1 "nonmemory_operand" "")
9641 (match_operand:DF 2 "register_operand" "")]
9642 "TARGET_SSE2 && TARGET_SSE_MATH"
9644 ix86_expand_copysign (operands);
9648 (define_insn_and_split "copysigndf3_const"
9649 [(set (match_operand:DF 0 "register_operand" "=x")
9651 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9652 (match_operand:DF 2 "register_operand" "0")
9653 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9655 "TARGET_SSE2 && TARGET_SSE_MATH"
9657 "&& reload_completed"
9660 ix86_split_copysign_const (operands);
9664 (define_insn "copysigndf3_var"
9665 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9667 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9668 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9669 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9670 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9672 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9673 "TARGET_SSE2 && TARGET_SSE_MATH"
9677 [(set (match_operand:DF 0 "register_operand" "")
9679 [(match_operand:DF 2 "register_operand" "")
9680 (match_operand:DF 3 "register_operand" "")
9681 (match_operand:V2DF 4 "" "")
9682 (match_operand:V2DF 5 "" "")]
9684 (clobber (match_scratch:V2DF 1 ""))]
9685 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9688 ix86_split_copysign_var (operands);
9692 (define_expand "negxf2"
9693 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9694 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9696 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9698 (define_expand "absxf2"
9699 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9700 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9702 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9704 (define_insn "*absnegxf2_i387"
9705 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9706 (match_operator:XF 3 "absneg_operator"
9707 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9708 (use (match_operand 2 "" ""))
9709 (clobber (reg:CC FLAGS_REG))]
9711 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9714 ;; Splitters for fp abs and neg.
9717 [(set (match_operand 0 "fp_register_operand" "")
9718 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9719 (use (match_operand 2 "" ""))
9720 (clobber (reg:CC FLAGS_REG))]
9722 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9725 [(set (match_operand 0 "register_operand" "")
9726 (match_operator 3 "absneg_operator"
9727 [(match_operand 1 "register_operand" "")]))
9728 (use (match_operand 2 "nonimmediate_operand" ""))
9729 (clobber (reg:CC FLAGS_REG))]
9730 "reload_completed && SSE_REG_P (operands[0])"
9731 [(set (match_dup 0) (match_dup 3))]
9733 enum machine_mode mode = GET_MODE (operands[0]);
9734 enum machine_mode vmode = GET_MODE (operands[2]);
9737 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9738 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9739 if (operands_match_p (operands[0], operands[2]))
9742 operands[1] = operands[2];
9745 if (GET_CODE (operands[3]) == ABS)
9746 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9748 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9753 [(set (match_operand:SF 0 "register_operand" "")
9754 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9755 (use (match_operand:V4SF 2 "" ""))
9756 (clobber (reg:CC FLAGS_REG))]
9758 [(parallel [(set (match_dup 0) (match_dup 1))
9759 (clobber (reg:CC FLAGS_REG))])]
9762 operands[0] = gen_lowpart (SImode, operands[0]);
9763 if (GET_CODE (operands[1]) == ABS)
9765 tmp = gen_int_mode (0x7fffffff, SImode);
9766 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9770 tmp = gen_int_mode (0x80000000, SImode);
9771 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9777 [(set (match_operand:DF 0 "register_operand" "")
9778 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9779 (use (match_operand 2 "" ""))
9780 (clobber (reg:CC FLAGS_REG))]
9782 [(parallel [(set (match_dup 0) (match_dup 1))
9783 (clobber (reg:CC FLAGS_REG))])]
9788 tmp = gen_lowpart (DImode, operands[0]);
9789 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9792 if (GET_CODE (operands[1]) == ABS)
9795 tmp = gen_rtx_NOT (DImode, tmp);
9799 operands[0] = gen_highpart (SImode, operands[0]);
9800 if (GET_CODE (operands[1]) == ABS)
9802 tmp = gen_int_mode (0x7fffffff, SImode);
9803 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9807 tmp = gen_int_mode (0x80000000, SImode);
9808 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9815 [(set (match_operand:XF 0 "register_operand" "")
9816 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9817 (use (match_operand 2 "" ""))
9818 (clobber (reg:CC FLAGS_REG))]
9820 [(parallel [(set (match_dup 0) (match_dup 1))
9821 (clobber (reg:CC FLAGS_REG))])]
9824 operands[0] = gen_rtx_REG (SImode,
9825 true_regnum (operands[0])
9826 + (TARGET_64BIT ? 1 : 2));
9827 if (GET_CODE (operands[1]) == ABS)
9829 tmp = GEN_INT (0x7fff);
9830 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9834 tmp = GEN_INT (0x8000);
9835 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9841 [(set (match_operand 0 "memory_operand" "")
9842 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9843 (use (match_operand 2 "" ""))
9844 (clobber (reg:CC FLAGS_REG))]
9846 [(parallel [(set (match_dup 0) (match_dup 1))
9847 (clobber (reg:CC FLAGS_REG))])]
9849 enum machine_mode mode = GET_MODE (operands[0]);
9850 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9853 operands[0] = adjust_address (operands[0], QImode, size - 1);
9854 if (GET_CODE (operands[1]) == ABS)
9856 tmp = gen_int_mode (0x7f, QImode);
9857 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9861 tmp = gen_int_mode (0x80, QImode);
9862 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9867 ;; Conditionalize these after reload. If they match before reload, we
9868 ;; lose the clobber and ability to use integer instructions.
9870 (define_insn "*negsf2_1"
9871 [(set (match_operand:SF 0 "register_operand" "=f")
9872 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9873 "TARGET_80387 && reload_completed"
9875 [(set_attr "type" "fsgn")
9876 (set_attr "mode" "SF")])
9878 (define_insn "*negdf2_1"
9879 [(set (match_operand:DF 0 "register_operand" "=f")
9880 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9881 "TARGET_80387 && reload_completed"
9883 [(set_attr "type" "fsgn")
9884 (set_attr "mode" "DF")])
9886 (define_insn "*negxf2_1"
9887 [(set (match_operand:XF 0 "register_operand" "=f")
9888 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9889 "TARGET_80387 && reload_completed"
9891 [(set_attr "type" "fsgn")
9892 (set_attr "mode" "XF")])
9894 (define_insn "*abssf2_1"
9895 [(set (match_operand:SF 0 "register_operand" "=f")
9896 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9897 "TARGET_80387 && reload_completed"
9899 [(set_attr "type" "fsgn")
9900 (set_attr "mode" "SF")])
9902 (define_insn "*absdf2_1"
9903 [(set (match_operand:DF 0 "register_operand" "=f")
9904 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9905 "TARGET_80387 && reload_completed"
9907 [(set_attr "type" "fsgn")
9908 (set_attr "mode" "DF")])
9910 (define_insn "*absxf2_1"
9911 [(set (match_operand:XF 0 "register_operand" "=f")
9912 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9913 "TARGET_80387 && reload_completed"
9915 [(set_attr "type" "fsgn")
9916 (set_attr "mode" "DF")])
9918 (define_insn "*negextendsfdf2"
9919 [(set (match_operand:DF 0 "register_operand" "=f")
9920 (neg:DF (float_extend:DF
9921 (match_operand:SF 1 "register_operand" "0"))))]
9922 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9924 [(set_attr "type" "fsgn")
9925 (set_attr "mode" "DF")])
9927 (define_insn "*negextenddfxf2"
9928 [(set (match_operand:XF 0 "register_operand" "=f")
9929 (neg:XF (float_extend:XF
9930 (match_operand:DF 1 "register_operand" "0"))))]
9933 [(set_attr "type" "fsgn")
9934 (set_attr "mode" "XF")])
9936 (define_insn "*negextendsfxf2"
9937 [(set (match_operand:XF 0 "register_operand" "=f")
9938 (neg:XF (float_extend:XF
9939 (match_operand:SF 1 "register_operand" "0"))))]
9942 [(set_attr "type" "fsgn")
9943 (set_attr "mode" "XF")])
9945 (define_insn "*absextendsfdf2"
9946 [(set (match_operand:DF 0 "register_operand" "=f")
9947 (abs:DF (float_extend:DF
9948 (match_operand:SF 1 "register_operand" "0"))))]
9949 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9951 [(set_attr "type" "fsgn")
9952 (set_attr "mode" "DF")])
9954 (define_insn "*absextenddfxf2"
9955 [(set (match_operand:XF 0 "register_operand" "=f")
9956 (abs:XF (float_extend:XF
9957 (match_operand:DF 1 "register_operand" "0"))))]
9960 [(set_attr "type" "fsgn")
9961 (set_attr "mode" "XF")])
9963 (define_insn "*absextendsfxf2"
9964 [(set (match_operand:XF 0 "register_operand" "=f")
9965 (abs:XF (float_extend:XF
9966 (match_operand:SF 1 "register_operand" "0"))))]
9969 [(set_attr "type" "fsgn")
9970 (set_attr "mode" "XF")])
9972 ;; One complement instructions
9974 (define_expand "one_cmpldi2"
9975 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9976 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9978 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9980 (define_insn "*one_cmpldi2_1_rex64"
9981 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9982 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9983 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9985 [(set_attr "type" "negnot")
9986 (set_attr "mode" "DI")])
9988 (define_insn "*one_cmpldi2_2_rex64"
9989 [(set (reg FLAGS_REG)
9990 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9992 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9993 (not:DI (match_dup 1)))]
9994 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9995 && ix86_unary_operator_ok (NOT, DImode, operands)"
9997 [(set_attr "type" "alu1")
9998 (set_attr "mode" "DI")])
10001 [(set (match_operand 0 "flags_reg_operand" "")
10002 (match_operator 2 "compare_operator"
10003 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10005 (set (match_operand:DI 1 "nonimmediate_operand" "")
10006 (not:DI (match_dup 3)))]
10007 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10008 [(parallel [(set (match_dup 0)
10010 [(xor:DI (match_dup 3) (const_int -1))
10013 (xor:DI (match_dup 3) (const_int -1)))])]
10016 (define_expand "one_cmplsi2"
10017 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10018 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10020 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10022 (define_insn "*one_cmplsi2_1"
10023 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10024 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10025 "ix86_unary_operator_ok (NOT, SImode, operands)"
10027 [(set_attr "type" "negnot")
10028 (set_attr "mode" "SI")])
10030 ;; ??? Currently never generated - xor is used instead.
10031 (define_insn "*one_cmplsi2_1_zext"
10032 [(set (match_operand:DI 0 "register_operand" "=r")
10033 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10034 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10036 [(set_attr "type" "negnot")
10037 (set_attr "mode" "SI")])
10039 (define_insn "*one_cmplsi2_2"
10040 [(set (reg FLAGS_REG)
10041 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10043 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10044 (not:SI (match_dup 1)))]
10045 "ix86_match_ccmode (insn, CCNOmode)
10046 && ix86_unary_operator_ok (NOT, SImode, operands)"
10048 [(set_attr "type" "alu1")
10049 (set_attr "mode" "SI")])
10052 [(set (match_operand 0 "flags_reg_operand" "")
10053 (match_operator 2 "compare_operator"
10054 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10056 (set (match_operand:SI 1 "nonimmediate_operand" "")
10057 (not:SI (match_dup 3)))]
10058 "ix86_match_ccmode (insn, CCNOmode)"
10059 [(parallel [(set (match_dup 0)
10060 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10063 (xor:SI (match_dup 3) (const_int -1)))])]
10066 ;; ??? Currently never generated - xor is used instead.
10067 (define_insn "*one_cmplsi2_2_zext"
10068 [(set (reg FLAGS_REG)
10069 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10071 (set (match_operand:DI 0 "register_operand" "=r")
10072 (zero_extend:DI (not:SI (match_dup 1))))]
10073 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10074 && ix86_unary_operator_ok (NOT, SImode, operands)"
10076 [(set_attr "type" "alu1")
10077 (set_attr "mode" "SI")])
10080 [(set (match_operand 0 "flags_reg_operand" "")
10081 (match_operator 2 "compare_operator"
10082 [(not:SI (match_operand:SI 3 "register_operand" ""))
10084 (set (match_operand:DI 1 "register_operand" "")
10085 (zero_extend:DI (not:SI (match_dup 3))))]
10086 "ix86_match_ccmode (insn, CCNOmode)"
10087 [(parallel [(set (match_dup 0)
10088 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10091 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10094 (define_expand "one_cmplhi2"
10095 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10096 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10097 "TARGET_HIMODE_MATH"
10098 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10100 (define_insn "*one_cmplhi2_1"
10101 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10102 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10103 "ix86_unary_operator_ok (NOT, HImode, operands)"
10105 [(set_attr "type" "negnot")
10106 (set_attr "mode" "HI")])
10108 (define_insn "*one_cmplhi2_2"
10109 [(set (reg FLAGS_REG)
10110 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10112 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10113 (not:HI (match_dup 1)))]
10114 "ix86_match_ccmode (insn, CCNOmode)
10115 && ix86_unary_operator_ok (NEG, HImode, operands)"
10117 [(set_attr "type" "alu1")
10118 (set_attr "mode" "HI")])
10121 [(set (match_operand 0 "flags_reg_operand" "")
10122 (match_operator 2 "compare_operator"
10123 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10125 (set (match_operand:HI 1 "nonimmediate_operand" "")
10126 (not:HI (match_dup 3)))]
10127 "ix86_match_ccmode (insn, CCNOmode)"
10128 [(parallel [(set (match_dup 0)
10129 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10132 (xor:HI (match_dup 3) (const_int -1)))])]
10135 ;; %%% Potential partial reg stall on alternative 1. What to do?
10136 (define_expand "one_cmplqi2"
10137 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10138 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10139 "TARGET_QIMODE_MATH"
10140 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10142 (define_insn "*one_cmplqi2_1"
10143 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10144 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10145 "ix86_unary_operator_ok (NOT, QImode, operands)"
10149 [(set_attr "type" "negnot")
10150 (set_attr "mode" "QI,SI")])
10152 (define_insn "*one_cmplqi2_2"
10153 [(set (reg FLAGS_REG)
10154 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10156 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10157 (not:QI (match_dup 1)))]
10158 "ix86_match_ccmode (insn, CCNOmode)
10159 && ix86_unary_operator_ok (NOT, QImode, operands)"
10161 [(set_attr "type" "alu1")
10162 (set_attr "mode" "QI")])
10165 [(set (match_operand 0 "flags_reg_operand" "")
10166 (match_operator 2 "compare_operator"
10167 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10169 (set (match_operand:QI 1 "nonimmediate_operand" "")
10170 (not:QI (match_dup 3)))]
10171 "ix86_match_ccmode (insn, CCNOmode)"
10172 [(parallel [(set (match_dup 0)
10173 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10176 (xor:QI (match_dup 3) (const_int -1)))])]
10179 ;; Arithmetic shift instructions
10181 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10182 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10183 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10184 ;; from the assembler input.
10186 ;; This instruction shifts the target reg/mem as usual, but instead of
10187 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10188 ;; is a left shift double, bits are taken from the high order bits of
10189 ;; reg, else if the insn is a shift right double, bits are taken from the
10190 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10191 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10193 ;; Since sh[lr]d does not change the `reg' operand, that is done
10194 ;; separately, making all shifts emit pairs of shift double and normal
10195 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10196 ;; support a 63 bit shift, each shift where the count is in a reg expands
10197 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10199 ;; If the shift count is a constant, we need never emit more than one
10200 ;; shift pair, instead using moves and sign extension for counts greater
10203 (define_expand "ashlti3"
10204 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10205 (ashift:TI (match_operand:TI 1 "register_operand" "")
10206 (match_operand:QI 2 "nonmemory_operand" "")))
10207 (clobber (reg:CC FLAGS_REG))])]
10210 if (! immediate_operand (operands[2], QImode))
10212 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10215 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10219 (define_insn "ashlti3_1"
10220 [(set (match_operand:TI 0 "register_operand" "=r")
10221 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10222 (match_operand:QI 2 "register_operand" "c")))
10223 (clobber (match_scratch:DI 3 "=&r"))
10224 (clobber (reg:CC FLAGS_REG))]
10227 [(set_attr "type" "multi")])
10229 (define_insn "*ashlti3_2"
10230 [(set (match_operand:TI 0 "register_operand" "=r")
10231 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10232 (match_operand:QI 2 "immediate_operand" "O")))
10233 (clobber (reg:CC FLAGS_REG))]
10236 [(set_attr "type" "multi")])
10239 [(set (match_operand:TI 0 "register_operand" "")
10240 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10241 (match_operand:QI 2 "register_operand" "")))
10242 (clobber (match_scratch:DI 3 ""))
10243 (clobber (reg:CC FLAGS_REG))]
10244 "TARGET_64BIT && reload_completed"
10246 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10249 [(set (match_operand:TI 0 "register_operand" "")
10250 (ashift:TI (match_operand:TI 1 "register_operand" "")
10251 (match_operand:QI 2 "immediate_operand" "")))
10252 (clobber (reg:CC FLAGS_REG))]
10253 "TARGET_64BIT && reload_completed"
10255 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10257 (define_insn "x86_64_shld"
10258 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10259 (ior:DI (ashift:DI (match_dup 0)
10260 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10261 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10262 (minus:QI (const_int 64) (match_dup 2)))))
10263 (clobber (reg:CC FLAGS_REG))]
10266 shld{q}\t{%2, %1, %0|%0, %1, %2}
10267 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10268 [(set_attr "type" "ishift")
10269 (set_attr "prefix_0f" "1")
10270 (set_attr "mode" "DI")
10271 (set_attr "athlon_decode" "vector")])
10273 (define_expand "x86_64_shift_adj"
10274 [(set (reg:CCZ FLAGS_REG)
10275 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10278 (set (match_operand:DI 0 "register_operand" "")
10279 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10280 (match_operand:DI 1 "register_operand" "")
10283 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10284 (match_operand:DI 3 "register_operand" "r")
10289 (define_expand "ashldi3"
10290 [(set (match_operand:DI 0 "shiftdi_operand" "")
10291 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10292 (match_operand:QI 2 "nonmemory_operand" "")))]
10294 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10296 (define_insn "*ashldi3_1_rex64"
10297 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10298 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10299 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10303 switch (get_attr_type (insn))
10306 gcc_assert (operands[2] == const1_rtx);
10307 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10308 return "add{q}\t{%0, %0|%0, %0}";
10311 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10312 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10313 operands[1] = gen_rtx_MULT (DImode, operands[1],
10314 GEN_INT (1 << INTVAL (operands[2])));
10315 return "lea{q}\t{%a1, %0|%0, %a1}";
10318 if (REG_P (operands[2]))
10319 return "sal{q}\t{%b2, %0|%0, %b2}";
10320 else if (operands[2] == const1_rtx
10321 && (TARGET_SHIFT1 || optimize_size))
10322 return "sal{q}\t%0";
10324 return "sal{q}\t{%2, %0|%0, %2}";
10327 [(set (attr "type")
10328 (cond [(eq_attr "alternative" "1")
10329 (const_string "lea")
10330 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10332 (match_operand 0 "register_operand" ""))
10333 (match_operand 2 "const1_operand" ""))
10334 (const_string "alu")
10336 (const_string "ishift")))
10337 (set_attr "mode" "DI")])
10339 ;; Convert lea to the lea pattern to avoid flags dependency.
10341 [(set (match_operand:DI 0 "register_operand" "")
10342 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10343 (match_operand:QI 2 "immediate_operand" "")))
10344 (clobber (reg:CC FLAGS_REG))]
10345 "TARGET_64BIT && reload_completed
10346 && true_regnum (operands[0]) != true_regnum (operands[1])"
10347 [(set (match_dup 0)
10348 (mult:DI (match_dup 1)
10350 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10352 ;; This pattern can't accept a variable shift count, since shifts by
10353 ;; zero don't affect the flags. We assume that shifts by constant
10354 ;; zero are optimized away.
10355 (define_insn "*ashldi3_cmp_rex64"
10356 [(set (reg FLAGS_REG)
10358 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10359 (match_operand:QI 2 "immediate_operand" "e"))
10361 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362 (ashift:DI (match_dup 1) (match_dup 2)))]
10363 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10364 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10366 switch (get_attr_type (insn))
10369 gcc_assert (operands[2] == const1_rtx);
10370 return "add{q}\t{%0, %0|%0, %0}";
10373 if (REG_P (operands[2]))
10374 return "sal{q}\t{%b2, %0|%0, %b2}";
10375 else if (operands[2] == const1_rtx
10376 && (TARGET_SHIFT1 || optimize_size))
10377 return "sal{q}\t%0";
10379 return "sal{q}\t{%2, %0|%0, %2}";
10382 [(set (attr "type")
10383 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10385 (match_operand 0 "register_operand" ""))
10386 (match_operand 2 "const1_operand" ""))
10387 (const_string "alu")
10389 (const_string "ishift")))
10390 (set_attr "mode" "DI")])
10392 (define_insn "*ashldi3_1"
10393 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10394 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10395 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10396 (clobber (reg:CC FLAGS_REG))]
10399 [(set_attr "type" "multi")])
10401 ;; By default we don't ask for a scratch register, because when DImode
10402 ;; values are manipulated, registers are already at a premium. But if
10403 ;; we have one handy, we won't turn it away.
10405 [(match_scratch:SI 3 "r")
10406 (parallel [(set (match_operand:DI 0 "register_operand" "")
10407 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10408 (match_operand:QI 2 "nonmemory_operand" "")))
10409 (clobber (reg:CC FLAGS_REG))])
10411 "!TARGET_64BIT && TARGET_CMOVE"
10413 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10416 [(set (match_operand:DI 0 "register_operand" "")
10417 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10418 (match_operand:QI 2 "nonmemory_operand" "")))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10421 ? flow2_completed : reload_completed)"
10423 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10425 (define_insn "x86_shld_1"
10426 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10427 (ior:SI (ashift:SI (match_dup 0)
10428 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10429 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10430 (minus:QI (const_int 32) (match_dup 2)))))
10431 (clobber (reg:CC FLAGS_REG))]
10434 shld{l}\t{%2, %1, %0|%0, %1, %2}
10435 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10436 [(set_attr "type" "ishift")
10437 (set_attr "prefix_0f" "1")
10438 (set_attr "mode" "SI")
10439 (set_attr "pent_pair" "np")
10440 (set_attr "athlon_decode" "vector")])
10442 (define_expand "x86_shift_adj_1"
10443 [(set (reg:CCZ FLAGS_REG)
10444 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10447 (set (match_operand:SI 0 "register_operand" "")
10448 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10449 (match_operand:SI 1 "register_operand" "")
10452 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10453 (match_operand:SI 3 "register_operand" "r")
10458 (define_expand "x86_shift_adj_2"
10459 [(use (match_operand:SI 0 "register_operand" ""))
10460 (use (match_operand:SI 1 "register_operand" ""))
10461 (use (match_operand:QI 2 "register_operand" ""))]
10464 rtx label = gen_label_rtx ();
10467 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10469 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10470 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10471 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10472 gen_rtx_LABEL_REF (VOIDmode, label),
10474 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10475 JUMP_LABEL (tmp) = label;
10477 emit_move_insn (operands[0], operands[1]);
10478 ix86_expand_clear (operands[1]);
10480 emit_label (label);
10481 LABEL_NUSES (label) = 1;
10486 (define_expand "ashlsi3"
10487 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10488 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10489 (match_operand:QI 2 "nonmemory_operand" "")))
10490 (clobber (reg:CC FLAGS_REG))]
10492 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10494 (define_insn "*ashlsi3_1"
10495 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10496 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10497 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10498 (clobber (reg:CC FLAGS_REG))]
10499 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10501 switch (get_attr_type (insn))
10504 gcc_assert (operands[2] == const1_rtx);
10505 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10506 return "add{l}\t{%0, %0|%0, %0}";
10512 if (REG_P (operands[2]))
10513 return "sal{l}\t{%b2, %0|%0, %b2}";
10514 else if (operands[2] == const1_rtx
10515 && (TARGET_SHIFT1 || optimize_size))
10516 return "sal{l}\t%0";
10518 return "sal{l}\t{%2, %0|%0, %2}";
10521 [(set (attr "type")
10522 (cond [(eq_attr "alternative" "1")
10523 (const_string "lea")
10524 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10526 (match_operand 0 "register_operand" ""))
10527 (match_operand 2 "const1_operand" ""))
10528 (const_string "alu")
10530 (const_string "ishift")))
10531 (set_attr "mode" "SI")])
10533 ;; Convert lea to the lea pattern to avoid flags dependency.
10535 [(set (match_operand 0 "register_operand" "")
10536 (ashift (match_operand 1 "index_register_operand" "")
10537 (match_operand:QI 2 "const_int_operand" "")))
10538 (clobber (reg:CC FLAGS_REG))]
10540 && true_regnum (operands[0]) != true_regnum (operands[1])
10541 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10545 enum machine_mode mode = GET_MODE (operands[0]);
10547 if (GET_MODE_SIZE (mode) < 4)
10548 operands[0] = gen_lowpart (SImode, operands[0]);
10550 operands[1] = gen_lowpart (Pmode, operands[1]);
10551 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10553 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10554 if (Pmode != SImode)
10555 pat = gen_rtx_SUBREG (SImode, pat, 0);
10556 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10560 ;; Rare case of shifting RSP is handled by generating move and shift
10562 [(set (match_operand 0 "register_operand" "")
10563 (ashift (match_operand 1 "register_operand" "")
10564 (match_operand:QI 2 "const_int_operand" "")))
10565 (clobber (reg:CC FLAGS_REG))]
10567 && true_regnum (operands[0]) != true_regnum (operands[1])"
10571 emit_move_insn (operands[1], operands[0]);
10572 pat = gen_rtx_SET (VOIDmode, operands[0],
10573 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10574 operands[0], operands[2]));
10575 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10576 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10580 (define_insn "*ashlsi3_1_zext"
10581 [(set (match_operand:DI 0 "register_operand" "=r,r")
10582 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10583 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10584 (clobber (reg:CC FLAGS_REG))]
10585 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10587 switch (get_attr_type (insn))
10590 gcc_assert (operands[2] == const1_rtx);
10591 return "add{l}\t{%k0, %k0|%k0, %k0}";
10597 if (REG_P (operands[2]))
10598 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10599 else if (operands[2] == const1_rtx
10600 && (TARGET_SHIFT1 || optimize_size))
10601 return "sal{l}\t%k0";
10603 return "sal{l}\t{%2, %k0|%k0, %2}";
10606 [(set (attr "type")
10607 (cond [(eq_attr "alternative" "1")
10608 (const_string "lea")
10609 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10611 (match_operand 2 "const1_operand" ""))
10612 (const_string "alu")
10614 (const_string "ishift")))
10615 (set_attr "mode" "SI")])
10617 ;; Convert lea to the lea pattern to avoid flags dependency.
10619 [(set (match_operand:DI 0 "register_operand" "")
10620 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10621 (match_operand:QI 2 "const_int_operand" ""))))
10622 (clobber (reg:CC FLAGS_REG))]
10623 "TARGET_64BIT && reload_completed
10624 && true_regnum (operands[0]) != true_regnum (operands[1])"
10625 [(set (match_dup 0) (zero_extend:DI
10626 (subreg:SI (mult:SI (match_dup 1)
10627 (match_dup 2)) 0)))]
10629 operands[1] = gen_lowpart (Pmode, operands[1]);
10630 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10633 ;; This pattern can't accept a variable shift count, since shifts by
10634 ;; zero don't affect the flags. We assume that shifts by constant
10635 ;; zero are optimized away.
10636 (define_insn "*ashlsi3_cmp"
10637 [(set (reg FLAGS_REG)
10639 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10640 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10642 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10643 (ashift:SI (match_dup 1) (match_dup 2)))]
10644 "ix86_match_ccmode (insn, CCGOCmode)
10645 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10647 switch (get_attr_type (insn))
10650 gcc_assert (operands[2] == const1_rtx);
10651 return "add{l}\t{%0, %0|%0, %0}";
10654 if (REG_P (operands[2]))
10655 return "sal{l}\t{%b2, %0|%0, %b2}";
10656 else if (operands[2] == const1_rtx
10657 && (TARGET_SHIFT1 || optimize_size))
10658 return "sal{l}\t%0";
10660 return "sal{l}\t{%2, %0|%0, %2}";
10663 [(set (attr "type")
10664 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10666 (match_operand 0 "register_operand" ""))
10667 (match_operand 2 "const1_operand" ""))
10668 (const_string "alu")
10670 (const_string "ishift")))
10671 (set_attr "mode" "SI")])
10673 (define_insn "*ashlsi3_cmp_zext"
10674 [(set (reg FLAGS_REG)
10676 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10677 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10679 (set (match_operand:DI 0 "register_operand" "=r")
10680 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10681 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10682 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10684 switch (get_attr_type (insn))
10687 gcc_assert (operands[2] == const1_rtx);
10688 return "add{l}\t{%k0, %k0|%k0, %k0}";
10691 if (REG_P (operands[2]))
10692 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10693 else if (operands[2] == const1_rtx
10694 && (TARGET_SHIFT1 || optimize_size))
10695 return "sal{l}\t%k0";
10697 return "sal{l}\t{%2, %k0|%k0, %2}";
10700 [(set (attr "type")
10701 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10703 (match_operand 2 "const1_operand" ""))
10704 (const_string "alu")
10706 (const_string "ishift")))
10707 (set_attr "mode" "SI")])
10709 (define_expand "ashlhi3"
10710 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10711 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10712 (match_operand:QI 2 "nonmemory_operand" "")))
10713 (clobber (reg:CC FLAGS_REG))]
10714 "TARGET_HIMODE_MATH"
10715 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10717 (define_insn "*ashlhi3_1_lea"
10718 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10719 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10720 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10721 (clobber (reg:CC FLAGS_REG))]
10722 "!TARGET_PARTIAL_REG_STALL
10723 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10725 switch (get_attr_type (insn))
10730 gcc_assert (operands[2] == const1_rtx);
10731 return "add{w}\t{%0, %0|%0, %0}";
10734 if (REG_P (operands[2]))
10735 return "sal{w}\t{%b2, %0|%0, %b2}";
10736 else if (operands[2] == const1_rtx
10737 && (TARGET_SHIFT1 || optimize_size))
10738 return "sal{w}\t%0";
10740 return "sal{w}\t{%2, %0|%0, %2}";
10743 [(set (attr "type")
10744 (cond [(eq_attr "alternative" "1")
10745 (const_string "lea")
10746 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10748 (match_operand 0 "register_operand" ""))
10749 (match_operand 2 "const1_operand" ""))
10750 (const_string "alu")
10752 (const_string "ishift")))
10753 (set_attr "mode" "HI,SI")])
10755 (define_insn "*ashlhi3_1"
10756 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10757 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10758 (match_operand:QI 2 "nonmemory_operand" "cI")))
10759 (clobber (reg:CC FLAGS_REG))]
10760 "TARGET_PARTIAL_REG_STALL
10761 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10763 switch (get_attr_type (insn))
10766 gcc_assert (operands[2] == const1_rtx);
10767 return "add{w}\t{%0, %0|%0, %0}";
10770 if (REG_P (operands[2]))
10771 return "sal{w}\t{%b2, %0|%0, %b2}";
10772 else if (operands[2] == const1_rtx
10773 && (TARGET_SHIFT1 || optimize_size))
10774 return "sal{w}\t%0";
10776 return "sal{w}\t{%2, %0|%0, %2}";
10779 [(set (attr "type")
10780 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10782 (match_operand 0 "register_operand" ""))
10783 (match_operand 2 "const1_operand" ""))
10784 (const_string "alu")
10786 (const_string "ishift")))
10787 (set_attr "mode" "HI")])
10789 ;; This pattern can't accept a variable shift count, since shifts by
10790 ;; zero don't affect the flags. We assume that shifts by constant
10791 ;; zero are optimized away.
10792 (define_insn "*ashlhi3_cmp"
10793 [(set (reg FLAGS_REG)
10795 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10796 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10798 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10799 (ashift:HI (match_dup 1) (match_dup 2)))]
10800 "ix86_match_ccmode (insn, CCGOCmode)
10801 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10803 switch (get_attr_type (insn))
10806 gcc_assert (operands[2] == const1_rtx);
10807 return "add{w}\t{%0, %0|%0, %0}";
10810 if (REG_P (operands[2]))
10811 return "sal{w}\t{%b2, %0|%0, %b2}";
10812 else if (operands[2] == const1_rtx
10813 && (TARGET_SHIFT1 || optimize_size))
10814 return "sal{w}\t%0";
10816 return "sal{w}\t{%2, %0|%0, %2}";
10819 [(set (attr "type")
10820 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10822 (match_operand 0 "register_operand" ""))
10823 (match_operand 2 "const1_operand" ""))
10824 (const_string "alu")
10826 (const_string "ishift")))
10827 (set_attr "mode" "HI")])
10829 (define_expand "ashlqi3"
10830 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10831 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10832 (match_operand:QI 2 "nonmemory_operand" "")))
10833 (clobber (reg:CC FLAGS_REG))]
10834 "TARGET_QIMODE_MATH"
10835 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10837 ;; %%% Potential partial reg stall on alternative 2. What to do?
10839 (define_insn "*ashlqi3_1_lea"
10840 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10841 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10842 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10843 (clobber (reg:CC FLAGS_REG))]
10844 "!TARGET_PARTIAL_REG_STALL
10845 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10847 switch (get_attr_type (insn))
10852 gcc_assert (operands[2] == const1_rtx);
10853 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10854 return "add{l}\t{%k0, %k0|%k0, %k0}";
10856 return "add{b}\t{%0, %0|%0, %0}";
10859 if (REG_P (operands[2]))
10861 if (get_attr_mode (insn) == MODE_SI)
10862 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10864 return "sal{b}\t{%b2, %0|%0, %b2}";
10866 else if (operands[2] == const1_rtx
10867 && (TARGET_SHIFT1 || optimize_size))
10869 if (get_attr_mode (insn) == MODE_SI)
10870 return "sal{l}\t%0";
10872 return "sal{b}\t%0";
10876 if (get_attr_mode (insn) == MODE_SI)
10877 return "sal{l}\t{%2, %k0|%k0, %2}";
10879 return "sal{b}\t{%2, %0|%0, %2}";
10883 [(set (attr "type")
10884 (cond [(eq_attr "alternative" "2")
10885 (const_string "lea")
10886 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10888 (match_operand 0 "register_operand" ""))
10889 (match_operand 2 "const1_operand" ""))
10890 (const_string "alu")
10892 (const_string "ishift")))
10893 (set_attr "mode" "QI,SI,SI")])
10895 (define_insn "*ashlqi3_1"
10896 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10897 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10898 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10899 (clobber (reg:CC FLAGS_REG))]
10900 "TARGET_PARTIAL_REG_STALL
10901 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10903 switch (get_attr_type (insn))
10906 gcc_assert (operands[2] == const1_rtx);
10907 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10908 return "add{l}\t{%k0, %k0|%k0, %k0}";
10910 return "add{b}\t{%0, %0|%0, %0}";
10913 if (REG_P (operands[2]))
10915 if (get_attr_mode (insn) == MODE_SI)
10916 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10918 return "sal{b}\t{%b2, %0|%0, %b2}";
10920 else if (operands[2] == const1_rtx
10921 && (TARGET_SHIFT1 || optimize_size))
10923 if (get_attr_mode (insn) == MODE_SI)
10924 return "sal{l}\t%0";
10926 return "sal{b}\t%0";
10930 if (get_attr_mode (insn) == MODE_SI)
10931 return "sal{l}\t{%2, %k0|%k0, %2}";
10933 return "sal{b}\t{%2, %0|%0, %2}";
10937 [(set (attr "type")
10938 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10940 (match_operand 0 "register_operand" ""))
10941 (match_operand 2 "const1_operand" ""))
10942 (const_string "alu")
10944 (const_string "ishift")))
10945 (set_attr "mode" "QI,SI")])
10947 ;; This pattern can't accept a variable shift count, since shifts by
10948 ;; zero don't affect the flags. We assume that shifts by constant
10949 ;; zero are optimized away.
10950 (define_insn "*ashlqi3_cmp"
10951 [(set (reg FLAGS_REG)
10953 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10954 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10956 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10957 (ashift:QI (match_dup 1) (match_dup 2)))]
10958 "ix86_match_ccmode (insn, CCGOCmode)
10959 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10961 switch (get_attr_type (insn))
10964 gcc_assert (operands[2] == const1_rtx);
10965 return "add{b}\t{%0, %0|%0, %0}";
10968 if (REG_P (operands[2]))
10969 return "sal{b}\t{%b2, %0|%0, %b2}";
10970 else if (operands[2] == const1_rtx
10971 && (TARGET_SHIFT1 || optimize_size))
10972 return "sal{b}\t%0";
10974 return "sal{b}\t{%2, %0|%0, %2}";
10977 [(set (attr "type")
10978 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980 (match_operand 0 "register_operand" ""))
10981 (match_operand 2 "const1_operand" ""))
10982 (const_string "alu")
10984 (const_string "ishift")))
10985 (set_attr "mode" "QI")])
10987 ;; See comment above `ashldi3' about how this works.
10989 (define_expand "ashrti3"
10990 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10991 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10992 (match_operand:QI 2 "nonmemory_operand" "")))
10993 (clobber (reg:CC FLAGS_REG))])]
10996 if (! immediate_operand (operands[2], QImode))
10998 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11001 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11005 (define_insn "ashrti3_1"
11006 [(set (match_operand:TI 0 "register_operand" "=r")
11007 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11008 (match_operand:QI 2 "register_operand" "c")))
11009 (clobber (match_scratch:DI 3 "=&r"))
11010 (clobber (reg:CC FLAGS_REG))]
11013 [(set_attr "type" "multi")])
11015 (define_insn "*ashrti3_2"
11016 [(set (match_operand:TI 0 "register_operand" "=r")
11017 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11018 (match_operand:QI 2 "immediate_operand" "O")))
11019 (clobber (reg:CC FLAGS_REG))]
11022 [(set_attr "type" "multi")])
11025 [(set (match_operand:TI 0 "register_operand" "")
11026 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11027 (match_operand:QI 2 "register_operand" "")))
11028 (clobber (match_scratch:DI 3 ""))
11029 (clobber (reg:CC FLAGS_REG))]
11030 "TARGET_64BIT && reload_completed"
11032 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11035 [(set (match_operand:TI 0 "register_operand" "")
11036 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11037 (match_operand:QI 2 "immediate_operand" "")))
11038 (clobber (reg:CC FLAGS_REG))]
11039 "TARGET_64BIT && reload_completed"
11041 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11043 (define_insn "x86_64_shrd"
11044 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11045 (ior:DI (ashiftrt:DI (match_dup 0)
11046 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11047 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11048 (minus:QI (const_int 64) (match_dup 2)))))
11049 (clobber (reg:CC FLAGS_REG))]
11052 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11053 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11054 [(set_attr "type" "ishift")
11055 (set_attr "prefix_0f" "1")
11056 (set_attr "mode" "DI")
11057 (set_attr "athlon_decode" "vector")])
11059 (define_expand "ashrdi3"
11060 [(set (match_operand:DI 0 "shiftdi_operand" "")
11061 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11062 (match_operand:QI 2 "nonmemory_operand" "")))]
11064 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11066 (define_insn "*ashrdi3_63_rex64"
11067 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11068 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11069 (match_operand:DI 2 "const_int_operand" "i,i")))
11070 (clobber (reg:CC FLAGS_REG))]
11071 "TARGET_64BIT && INTVAL (operands[2]) == 63
11072 && (TARGET_USE_CLTD || optimize_size)
11073 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11076 sar{q}\t{%2, %0|%0, %2}"
11077 [(set_attr "type" "imovx,ishift")
11078 (set_attr "prefix_0f" "0,*")
11079 (set_attr "length_immediate" "0,*")
11080 (set_attr "modrm" "0,1")
11081 (set_attr "mode" "DI")])
11083 (define_insn "*ashrdi3_1_one_bit_rex64"
11084 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11085 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11086 (match_operand:QI 2 "const1_operand" "")))
11087 (clobber (reg:CC FLAGS_REG))]
11088 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11089 && (TARGET_SHIFT1 || optimize_size)"
11091 [(set_attr "type" "ishift")
11092 (set (attr "length")
11093 (if_then_else (match_operand:DI 0 "register_operand" "")
11095 (const_string "*")))])
11097 (define_insn "*ashrdi3_1_rex64"
11098 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11099 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11100 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11101 (clobber (reg:CC FLAGS_REG))]
11102 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11104 sar{q}\t{%2, %0|%0, %2}
11105 sar{q}\t{%b2, %0|%0, %b2}"
11106 [(set_attr "type" "ishift")
11107 (set_attr "mode" "DI")])
11109 ;; This pattern can't accept a variable shift count, since shifts by
11110 ;; zero don't affect the flags. We assume that shifts by constant
11111 ;; zero are optimized away.
11112 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11113 [(set (reg FLAGS_REG)
11115 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11116 (match_operand:QI 2 "const1_operand" ""))
11118 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11119 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11120 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11121 && (TARGET_SHIFT1 || optimize_size)
11122 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11124 [(set_attr "type" "ishift")
11125 (set (attr "length")
11126 (if_then_else (match_operand:DI 0 "register_operand" "")
11128 (const_string "*")))])
11130 ;; This pattern can't accept a variable shift count, since shifts by
11131 ;; zero don't affect the flags. We assume that shifts by constant
11132 ;; zero are optimized away.
11133 (define_insn "*ashrdi3_cmp_rex64"
11134 [(set (reg FLAGS_REG)
11136 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11137 (match_operand:QI 2 "const_int_operand" "n"))
11139 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11140 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11141 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11142 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11143 "sar{q}\t{%2, %0|%0, %2}"
11144 [(set_attr "type" "ishift")
11145 (set_attr "mode" "DI")])
11147 (define_insn "*ashrdi3_1"
11148 [(set (match_operand:DI 0 "register_operand" "=r")
11149 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11150 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11151 (clobber (reg:CC FLAGS_REG))]
11154 [(set_attr "type" "multi")])
11156 ;; By default we don't ask for a scratch register, because when DImode
11157 ;; values are manipulated, registers are already at a premium. But if
11158 ;; we have one handy, we won't turn it away.
11160 [(match_scratch:SI 3 "r")
11161 (parallel [(set (match_operand:DI 0 "register_operand" "")
11162 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11163 (match_operand:QI 2 "nonmemory_operand" "")))
11164 (clobber (reg:CC FLAGS_REG))])
11166 "!TARGET_64BIT && TARGET_CMOVE"
11168 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11171 [(set (match_operand:DI 0 "register_operand" "")
11172 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11173 (match_operand:QI 2 "nonmemory_operand" "")))
11174 (clobber (reg:CC FLAGS_REG))]
11175 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11176 ? flow2_completed : reload_completed)"
11178 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11180 (define_insn "x86_shrd_1"
11181 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11182 (ior:SI (ashiftrt:SI (match_dup 0)
11183 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11184 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11185 (minus:QI (const_int 32) (match_dup 2)))))
11186 (clobber (reg:CC FLAGS_REG))]
11189 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11190 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11191 [(set_attr "type" "ishift")
11192 (set_attr "prefix_0f" "1")
11193 (set_attr "pent_pair" "np")
11194 (set_attr "mode" "SI")])
11196 (define_expand "x86_shift_adj_3"
11197 [(use (match_operand:SI 0 "register_operand" ""))
11198 (use (match_operand:SI 1 "register_operand" ""))
11199 (use (match_operand:QI 2 "register_operand" ""))]
11202 rtx label = gen_label_rtx ();
11205 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11207 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11208 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11209 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11210 gen_rtx_LABEL_REF (VOIDmode, label),
11212 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11213 JUMP_LABEL (tmp) = label;
11215 emit_move_insn (operands[0], operands[1]);
11216 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11218 emit_label (label);
11219 LABEL_NUSES (label) = 1;
11224 (define_insn "ashrsi3_31"
11225 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11226 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11227 (match_operand:SI 2 "const_int_operand" "i,i")))
11228 (clobber (reg:CC FLAGS_REG))]
11229 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11230 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11233 sar{l}\t{%2, %0|%0, %2}"
11234 [(set_attr "type" "imovx,ishift")
11235 (set_attr "prefix_0f" "0,*")
11236 (set_attr "length_immediate" "0,*")
11237 (set_attr "modrm" "0,1")
11238 (set_attr "mode" "SI")])
11240 (define_insn "*ashrsi3_31_zext"
11241 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11242 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11243 (match_operand:SI 2 "const_int_operand" "i,i"))))
11244 (clobber (reg:CC FLAGS_REG))]
11245 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11246 && INTVAL (operands[2]) == 31
11247 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11250 sar{l}\t{%2, %k0|%k0, %2}"
11251 [(set_attr "type" "imovx,ishift")
11252 (set_attr "prefix_0f" "0,*")
11253 (set_attr "length_immediate" "0,*")
11254 (set_attr "modrm" "0,1")
11255 (set_attr "mode" "SI")])
11257 (define_expand "ashrsi3"
11258 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11259 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11260 (match_operand:QI 2 "nonmemory_operand" "")))
11261 (clobber (reg:CC FLAGS_REG))]
11263 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11265 (define_insn "*ashrsi3_1_one_bit"
11266 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11267 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11268 (match_operand:QI 2 "const1_operand" "")))
11269 (clobber (reg:CC FLAGS_REG))]
11270 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11271 && (TARGET_SHIFT1 || optimize_size)"
11273 [(set_attr "type" "ishift")
11274 (set (attr "length")
11275 (if_then_else (match_operand:SI 0 "register_operand" "")
11277 (const_string "*")))])
11279 (define_insn "*ashrsi3_1_one_bit_zext"
11280 [(set (match_operand:DI 0 "register_operand" "=r")
11281 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11282 (match_operand:QI 2 "const1_operand" ""))))
11283 (clobber (reg:CC FLAGS_REG))]
11284 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11285 && (TARGET_SHIFT1 || optimize_size)"
11287 [(set_attr "type" "ishift")
11288 (set_attr "length" "2")])
11290 (define_insn "*ashrsi3_1"
11291 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11292 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11293 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11294 (clobber (reg:CC FLAGS_REG))]
11295 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11297 sar{l}\t{%2, %0|%0, %2}
11298 sar{l}\t{%b2, %0|%0, %b2}"
11299 [(set_attr "type" "ishift")
11300 (set_attr "mode" "SI")])
11302 (define_insn "*ashrsi3_1_zext"
11303 [(set (match_operand:DI 0 "register_operand" "=r,r")
11304 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11305 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11306 (clobber (reg:CC FLAGS_REG))]
11307 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11309 sar{l}\t{%2, %k0|%k0, %2}
11310 sar{l}\t{%b2, %k0|%k0, %b2}"
11311 [(set_attr "type" "ishift")
11312 (set_attr "mode" "SI")])
11314 ;; This pattern can't accept a variable shift count, since shifts by
11315 ;; zero don't affect the flags. We assume that shifts by constant
11316 ;; zero are optimized away.
11317 (define_insn "*ashrsi3_one_bit_cmp"
11318 [(set (reg FLAGS_REG)
11320 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11321 (match_operand:QI 2 "const1_operand" ""))
11323 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11324 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11325 "ix86_match_ccmode (insn, CCGOCmode)
11326 && (TARGET_SHIFT1 || optimize_size)
11327 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11329 [(set_attr "type" "ishift")
11330 (set (attr "length")
11331 (if_then_else (match_operand:SI 0 "register_operand" "")
11333 (const_string "*")))])
11335 (define_insn "*ashrsi3_one_bit_cmp_zext"
11336 [(set (reg FLAGS_REG)
11338 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11339 (match_operand:QI 2 "const1_operand" ""))
11341 (set (match_operand:DI 0 "register_operand" "=r")
11342 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11343 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11344 && (TARGET_SHIFT1 || optimize_size)
11345 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11347 [(set_attr "type" "ishift")
11348 (set_attr "length" "2")])
11350 ;; This pattern can't accept a variable shift count, since shifts by
11351 ;; zero don't affect the flags. We assume that shifts by constant
11352 ;; zero are optimized away.
11353 (define_insn "*ashrsi3_cmp"
11354 [(set (reg FLAGS_REG)
11356 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11357 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11359 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11360 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11361 "ix86_match_ccmode (insn, CCGOCmode)
11362 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11363 "sar{l}\t{%2, %0|%0, %2}"
11364 [(set_attr "type" "ishift")
11365 (set_attr "mode" "SI")])
11367 (define_insn "*ashrsi3_cmp_zext"
11368 [(set (reg FLAGS_REG)
11370 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11371 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11373 (set (match_operand:DI 0 "register_operand" "=r")
11374 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11375 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11376 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11377 "sar{l}\t{%2, %k0|%k0, %2}"
11378 [(set_attr "type" "ishift")
11379 (set_attr "mode" "SI")])
11381 (define_expand "ashrhi3"
11382 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11383 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11384 (match_operand:QI 2 "nonmemory_operand" "")))
11385 (clobber (reg:CC FLAGS_REG))]
11386 "TARGET_HIMODE_MATH"
11387 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11389 (define_insn "*ashrhi3_1_one_bit"
11390 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11391 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11392 (match_operand:QI 2 "const1_operand" "")))
11393 (clobber (reg:CC FLAGS_REG))]
11394 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11395 && (TARGET_SHIFT1 || optimize_size)"
11397 [(set_attr "type" "ishift")
11398 (set (attr "length")
11399 (if_then_else (match_operand 0 "register_operand" "")
11401 (const_string "*")))])
11403 (define_insn "*ashrhi3_1"
11404 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11405 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11406 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11407 (clobber (reg:CC FLAGS_REG))]
11408 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11410 sar{w}\t{%2, %0|%0, %2}
11411 sar{w}\t{%b2, %0|%0, %b2}"
11412 [(set_attr "type" "ishift")
11413 (set_attr "mode" "HI")])
11415 ;; This pattern can't accept a variable shift count, since shifts by
11416 ;; zero don't affect the flags. We assume that shifts by constant
11417 ;; zero are optimized away.
11418 (define_insn "*ashrhi3_one_bit_cmp"
11419 [(set (reg FLAGS_REG)
11421 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11422 (match_operand:QI 2 "const1_operand" ""))
11424 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11425 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11426 "ix86_match_ccmode (insn, CCGOCmode)
11427 && (TARGET_SHIFT1 || optimize_size)
11428 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11430 [(set_attr "type" "ishift")
11431 (set (attr "length")
11432 (if_then_else (match_operand 0 "register_operand" "")
11434 (const_string "*")))])
11436 ;; This pattern can't accept a variable shift count, since shifts by
11437 ;; zero don't affect the flags. We assume that shifts by constant
11438 ;; zero are optimized away.
11439 (define_insn "*ashrhi3_cmp"
11440 [(set (reg FLAGS_REG)
11442 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11443 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11445 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11446 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11447 "ix86_match_ccmode (insn, CCGOCmode)
11448 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11449 "sar{w}\t{%2, %0|%0, %2}"
11450 [(set_attr "type" "ishift")
11451 (set_attr "mode" "HI")])
11453 (define_expand "ashrqi3"
11454 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11455 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11456 (match_operand:QI 2 "nonmemory_operand" "")))
11457 (clobber (reg:CC FLAGS_REG))]
11458 "TARGET_QIMODE_MATH"
11459 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11461 (define_insn "*ashrqi3_1_one_bit"
11462 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11463 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11464 (match_operand:QI 2 "const1_operand" "")))
11465 (clobber (reg:CC FLAGS_REG))]
11466 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11467 && (TARGET_SHIFT1 || optimize_size)"
11469 [(set_attr "type" "ishift")
11470 (set (attr "length")
11471 (if_then_else (match_operand 0 "register_operand" "")
11473 (const_string "*")))])
11475 (define_insn "*ashrqi3_1_one_bit_slp"
11476 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11477 (ashiftrt:QI (match_dup 0)
11478 (match_operand:QI 1 "const1_operand" "")))
11479 (clobber (reg:CC FLAGS_REG))]
11480 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11481 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11482 && (TARGET_SHIFT1 || optimize_size)"
11484 [(set_attr "type" "ishift1")
11485 (set (attr "length")
11486 (if_then_else (match_operand 0 "register_operand" "")
11488 (const_string "*")))])
11490 (define_insn "*ashrqi3_1"
11491 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11492 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11493 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11494 (clobber (reg:CC FLAGS_REG))]
11495 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11497 sar{b}\t{%2, %0|%0, %2}
11498 sar{b}\t{%b2, %0|%0, %b2}"
11499 [(set_attr "type" "ishift")
11500 (set_attr "mode" "QI")])
11502 (define_insn "*ashrqi3_1_slp"
11503 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11504 (ashiftrt:QI (match_dup 0)
11505 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11506 (clobber (reg:CC FLAGS_REG))]
11507 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11508 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11510 sar{b}\t{%1, %0|%0, %1}
11511 sar{b}\t{%b1, %0|%0, %b1}"
11512 [(set_attr "type" "ishift1")
11513 (set_attr "mode" "QI")])
11515 ;; This pattern can't accept a variable shift count, since shifts by
11516 ;; zero don't affect the flags. We assume that shifts by constant
11517 ;; zero are optimized away.
11518 (define_insn "*ashrqi3_one_bit_cmp"
11519 [(set (reg FLAGS_REG)
11521 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11522 (match_operand:QI 2 "const1_operand" "I"))
11524 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11525 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11526 "ix86_match_ccmode (insn, CCGOCmode)
11527 && (TARGET_SHIFT1 || optimize_size)
11528 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11530 [(set_attr "type" "ishift")
11531 (set (attr "length")
11532 (if_then_else (match_operand 0 "register_operand" "")
11534 (const_string "*")))])
11536 ;; This pattern can't accept a variable shift count, since shifts by
11537 ;; zero don't affect the flags. We assume that shifts by constant
11538 ;; zero are optimized away.
11539 (define_insn "*ashrqi3_cmp"
11540 [(set (reg FLAGS_REG)
11542 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11543 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11545 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11546 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11547 "ix86_match_ccmode (insn, CCGOCmode)
11548 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11549 "sar{b}\t{%2, %0|%0, %2}"
11550 [(set_attr "type" "ishift")
11551 (set_attr "mode" "QI")])
11553 ;; Logical shift instructions
11555 ;; See comment above `ashldi3' about how this works.
11557 (define_expand "lshrti3"
11558 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11559 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11560 (match_operand:QI 2 "nonmemory_operand" "")))
11561 (clobber (reg:CC FLAGS_REG))])]
11564 if (! immediate_operand (operands[2], QImode))
11566 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11569 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11573 (define_insn "lshrti3_1"
11574 [(set (match_operand:TI 0 "register_operand" "=r")
11575 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11576 (match_operand:QI 2 "register_operand" "c")))
11577 (clobber (match_scratch:DI 3 "=&r"))
11578 (clobber (reg:CC FLAGS_REG))]
11581 [(set_attr "type" "multi")])
11583 (define_insn "*lshrti3_2"
11584 [(set (match_operand:TI 0 "register_operand" "=r")
11585 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11586 (match_operand:QI 2 "immediate_operand" "O")))
11587 (clobber (reg:CC FLAGS_REG))]
11590 [(set_attr "type" "multi")])
11593 [(set (match_operand:TI 0 "register_operand" "")
11594 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11595 (match_operand:QI 2 "register_operand" "")))
11596 (clobber (match_scratch:DI 3 ""))
11597 (clobber (reg:CC FLAGS_REG))]
11598 "TARGET_64BIT && reload_completed"
11600 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11603 [(set (match_operand:TI 0 "register_operand" "")
11604 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11605 (match_operand:QI 2 "immediate_operand" "")))
11606 (clobber (reg:CC FLAGS_REG))]
11607 "TARGET_64BIT && reload_completed"
11609 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11611 (define_expand "lshrdi3"
11612 [(set (match_operand:DI 0 "shiftdi_operand" "")
11613 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11614 (match_operand:QI 2 "nonmemory_operand" "")))]
11616 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11618 (define_insn "*lshrdi3_1_one_bit_rex64"
11619 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11620 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11621 (match_operand:QI 2 "const1_operand" "")))
11622 (clobber (reg:CC FLAGS_REG))]
11623 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11624 && (TARGET_SHIFT1 || optimize_size)"
11626 [(set_attr "type" "ishift")
11627 (set (attr "length")
11628 (if_then_else (match_operand:DI 0 "register_operand" "")
11630 (const_string "*")))])
11632 (define_insn "*lshrdi3_1_rex64"
11633 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11634 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11635 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11636 (clobber (reg:CC FLAGS_REG))]
11637 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11639 shr{q}\t{%2, %0|%0, %2}
11640 shr{q}\t{%b2, %0|%0, %b2}"
11641 [(set_attr "type" "ishift")
11642 (set_attr "mode" "DI")])
11644 ;; This pattern can't accept a variable shift count, since shifts by
11645 ;; zero don't affect the flags. We assume that shifts by constant
11646 ;; zero are optimized away.
11647 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11648 [(set (reg FLAGS_REG)
11650 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11651 (match_operand:QI 2 "const1_operand" ""))
11653 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11654 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11655 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11656 && (TARGET_SHIFT1 || optimize_size)
11657 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11659 [(set_attr "type" "ishift")
11660 (set (attr "length")
11661 (if_then_else (match_operand:DI 0 "register_operand" "")
11663 (const_string "*")))])
11665 ;; This pattern can't accept a variable shift count, since shifts by
11666 ;; zero don't affect the flags. We assume that shifts by constant
11667 ;; zero are optimized away.
11668 (define_insn "*lshrdi3_cmp_rex64"
11669 [(set (reg FLAGS_REG)
11671 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11672 (match_operand:QI 2 "const_int_operand" "e"))
11674 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11675 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11676 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11677 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11678 "shr{q}\t{%2, %0|%0, %2}"
11679 [(set_attr "type" "ishift")
11680 (set_attr "mode" "DI")])
11682 (define_insn "*lshrdi3_1"
11683 [(set (match_operand:DI 0 "register_operand" "=r")
11684 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11685 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11686 (clobber (reg:CC FLAGS_REG))]
11689 [(set_attr "type" "multi")])
11691 ;; By default we don't ask for a scratch register, because when DImode
11692 ;; values are manipulated, registers are already at a premium. But if
11693 ;; we have one handy, we won't turn it away.
11695 [(match_scratch:SI 3 "r")
11696 (parallel [(set (match_operand:DI 0 "register_operand" "")
11697 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11698 (match_operand:QI 2 "nonmemory_operand" "")))
11699 (clobber (reg:CC FLAGS_REG))])
11701 "!TARGET_64BIT && TARGET_CMOVE"
11703 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11706 [(set (match_operand:DI 0 "register_operand" "")
11707 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11708 (match_operand:QI 2 "nonmemory_operand" "")))
11709 (clobber (reg:CC FLAGS_REG))]
11710 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11711 ? flow2_completed : reload_completed)"
11713 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11715 (define_expand "lshrsi3"
11716 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11717 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11718 (match_operand:QI 2 "nonmemory_operand" "")))
11719 (clobber (reg:CC FLAGS_REG))]
11721 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11723 (define_insn "*lshrsi3_1_one_bit"
11724 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11725 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11726 (match_operand:QI 2 "const1_operand" "")))
11727 (clobber (reg:CC FLAGS_REG))]
11728 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11729 && (TARGET_SHIFT1 || optimize_size)"
11731 [(set_attr "type" "ishift")
11732 (set (attr "length")
11733 (if_then_else (match_operand:SI 0 "register_operand" "")
11735 (const_string "*")))])
11737 (define_insn "*lshrsi3_1_one_bit_zext"
11738 [(set (match_operand:DI 0 "register_operand" "=r")
11739 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11740 (match_operand:QI 2 "const1_operand" "")))
11741 (clobber (reg:CC FLAGS_REG))]
11742 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11743 && (TARGET_SHIFT1 || optimize_size)"
11745 [(set_attr "type" "ishift")
11746 (set_attr "length" "2")])
11748 (define_insn "*lshrsi3_1"
11749 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11750 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11751 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11752 (clobber (reg:CC FLAGS_REG))]
11753 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11755 shr{l}\t{%2, %0|%0, %2}
11756 shr{l}\t{%b2, %0|%0, %b2}"
11757 [(set_attr "type" "ishift")
11758 (set_attr "mode" "SI")])
11760 (define_insn "*lshrsi3_1_zext"
11761 [(set (match_operand:DI 0 "register_operand" "=r,r")
11763 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11764 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11765 (clobber (reg:CC FLAGS_REG))]
11766 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11768 shr{l}\t{%2, %k0|%k0, %2}
11769 shr{l}\t{%b2, %k0|%k0, %b2}"
11770 [(set_attr "type" "ishift")
11771 (set_attr "mode" "SI")])
11773 ;; This pattern can't accept a variable shift count, since shifts by
11774 ;; zero don't affect the flags. We assume that shifts by constant
11775 ;; zero are optimized away.
11776 (define_insn "*lshrsi3_one_bit_cmp"
11777 [(set (reg FLAGS_REG)
11779 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11780 (match_operand:QI 2 "const1_operand" ""))
11782 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11783 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11784 "ix86_match_ccmode (insn, CCGOCmode)
11785 && (TARGET_SHIFT1 || optimize_size)
11786 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11788 [(set_attr "type" "ishift")
11789 (set (attr "length")
11790 (if_then_else (match_operand:SI 0 "register_operand" "")
11792 (const_string "*")))])
11794 (define_insn "*lshrsi3_cmp_one_bit_zext"
11795 [(set (reg FLAGS_REG)
11797 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11798 (match_operand:QI 2 "const1_operand" ""))
11800 (set (match_operand:DI 0 "register_operand" "=r")
11801 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11802 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11803 && (TARGET_SHIFT1 || optimize_size)
11804 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11806 [(set_attr "type" "ishift")
11807 (set_attr "length" "2")])
11809 ;; This pattern can't accept a variable shift count, since shifts by
11810 ;; zero don't affect the flags. We assume that shifts by constant
11811 ;; zero are optimized away.
11812 (define_insn "*lshrsi3_cmp"
11813 [(set (reg FLAGS_REG)
11815 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11816 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11818 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11819 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11820 "ix86_match_ccmode (insn, CCGOCmode)
11821 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822 "shr{l}\t{%2, %0|%0, %2}"
11823 [(set_attr "type" "ishift")
11824 (set_attr "mode" "SI")])
11826 (define_insn "*lshrsi3_cmp_zext"
11827 [(set (reg FLAGS_REG)
11829 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11830 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11832 (set (match_operand:DI 0 "register_operand" "=r")
11833 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11834 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11835 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11836 "shr{l}\t{%2, %k0|%k0, %2}"
11837 [(set_attr "type" "ishift")
11838 (set_attr "mode" "SI")])
11840 (define_expand "lshrhi3"
11841 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11842 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11843 (match_operand:QI 2 "nonmemory_operand" "")))
11844 (clobber (reg:CC FLAGS_REG))]
11845 "TARGET_HIMODE_MATH"
11846 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11848 (define_insn "*lshrhi3_1_one_bit"
11849 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11850 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11851 (match_operand:QI 2 "const1_operand" "")))
11852 (clobber (reg:CC FLAGS_REG))]
11853 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11854 && (TARGET_SHIFT1 || optimize_size)"
11856 [(set_attr "type" "ishift")
11857 (set (attr "length")
11858 (if_then_else (match_operand 0 "register_operand" "")
11860 (const_string "*")))])
11862 (define_insn "*lshrhi3_1"
11863 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11864 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11865 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11866 (clobber (reg:CC FLAGS_REG))]
11867 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11869 shr{w}\t{%2, %0|%0, %2}
11870 shr{w}\t{%b2, %0|%0, %b2}"
11871 [(set_attr "type" "ishift")
11872 (set_attr "mode" "HI")])
11874 ;; This pattern can't accept a variable shift count, since shifts by
11875 ;; zero don't affect the flags. We assume that shifts by constant
11876 ;; zero are optimized away.
11877 (define_insn "*lshrhi3_one_bit_cmp"
11878 [(set (reg FLAGS_REG)
11880 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11881 (match_operand:QI 2 "const1_operand" ""))
11883 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11884 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11885 "ix86_match_ccmode (insn, CCGOCmode)
11886 && (TARGET_SHIFT1 || optimize_size)
11887 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11889 [(set_attr "type" "ishift")
11890 (set (attr "length")
11891 (if_then_else (match_operand:SI 0 "register_operand" "")
11893 (const_string "*")))])
11895 ;; This pattern can't accept a variable shift count, since shifts by
11896 ;; zero don't affect the flags. We assume that shifts by constant
11897 ;; zero are optimized away.
11898 (define_insn "*lshrhi3_cmp"
11899 [(set (reg FLAGS_REG)
11901 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11902 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11904 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11905 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11906 "ix86_match_ccmode (insn, CCGOCmode)
11907 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11908 "shr{w}\t{%2, %0|%0, %2}"
11909 [(set_attr "type" "ishift")
11910 (set_attr "mode" "HI")])
11912 (define_expand "lshrqi3"
11913 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11914 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11915 (match_operand:QI 2 "nonmemory_operand" "")))
11916 (clobber (reg:CC FLAGS_REG))]
11917 "TARGET_QIMODE_MATH"
11918 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11920 (define_insn "*lshrqi3_1_one_bit"
11921 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11922 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11923 (match_operand:QI 2 "const1_operand" "")))
11924 (clobber (reg:CC FLAGS_REG))]
11925 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11926 && (TARGET_SHIFT1 || optimize_size)"
11928 [(set_attr "type" "ishift")
11929 (set (attr "length")
11930 (if_then_else (match_operand 0 "register_operand" "")
11932 (const_string "*")))])
11934 (define_insn "*lshrqi3_1_one_bit_slp"
11935 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11936 (lshiftrt:QI (match_dup 0)
11937 (match_operand:QI 1 "const1_operand" "")))
11938 (clobber (reg:CC FLAGS_REG))]
11939 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11940 && (TARGET_SHIFT1 || optimize_size)"
11942 [(set_attr "type" "ishift1")
11943 (set (attr "length")
11944 (if_then_else (match_operand 0 "register_operand" "")
11946 (const_string "*")))])
11948 (define_insn "*lshrqi3_1"
11949 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11950 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11951 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11952 (clobber (reg:CC FLAGS_REG))]
11953 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11955 shr{b}\t{%2, %0|%0, %2}
11956 shr{b}\t{%b2, %0|%0, %b2}"
11957 [(set_attr "type" "ishift")
11958 (set_attr "mode" "QI")])
11960 (define_insn "*lshrqi3_1_slp"
11961 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11962 (lshiftrt:QI (match_dup 0)
11963 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11964 (clobber (reg:CC FLAGS_REG))]
11965 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11966 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11968 shr{b}\t{%1, %0|%0, %1}
11969 shr{b}\t{%b1, %0|%0, %b1}"
11970 [(set_attr "type" "ishift1")
11971 (set_attr "mode" "QI")])
11973 ;; This pattern can't accept a variable shift count, since shifts by
11974 ;; zero don't affect the flags. We assume that shifts by constant
11975 ;; zero are optimized away.
11976 (define_insn "*lshrqi2_one_bit_cmp"
11977 [(set (reg FLAGS_REG)
11979 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11980 (match_operand:QI 2 "const1_operand" ""))
11982 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11983 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11984 "ix86_match_ccmode (insn, CCGOCmode)
11985 && (TARGET_SHIFT1 || optimize_size)
11986 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11988 [(set_attr "type" "ishift")
11989 (set (attr "length")
11990 (if_then_else (match_operand:SI 0 "register_operand" "")
11992 (const_string "*")))])
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags. We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*lshrqi2_cmp"
11998 [(set (reg FLAGS_REG)
12000 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12001 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12003 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12004 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12005 "ix86_match_ccmode (insn, CCGOCmode)
12006 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12007 "shr{b}\t{%2, %0|%0, %2}"
12008 [(set_attr "type" "ishift")
12009 (set_attr "mode" "QI")])
12011 ;; Rotate instructions
12013 (define_expand "rotldi3"
12014 [(set (match_operand:DI 0 "shiftdi_operand" "")
12015 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12016 (match_operand:QI 2 "nonmemory_operand" "")))
12017 (clobber (reg:CC FLAGS_REG))]
12022 ix86_expand_binary_operator (ROTATE, DImode, operands);
12025 if (!const_1_to_31_operand (operands[2], VOIDmode))
12027 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12031 ;; Implement rotation using two double-precision shift instructions
12032 ;; and a scratch register.
12033 (define_insn_and_split "ix86_rotldi3"
12034 [(set (match_operand:DI 0 "register_operand" "=r")
12035 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12036 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12037 (clobber (reg:CC FLAGS_REG))
12038 (clobber (match_scratch:SI 3 "=&r"))]
12041 "&& reload_completed"
12042 [(set (match_dup 3) (match_dup 4))
12044 [(set (match_dup 4)
12045 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12046 (lshiftrt:SI (match_dup 5)
12047 (minus:QI (const_int 32) (match_dup 2)))))
12048 (clobber (reg:CC FLAGS_REG))])
12050 [(set (match_dup 5)
12051 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12052 (lshiftrt:SI (match_dup 3)
12053 (minus:QI (const_int 32) (match_dup 2)))))
12054 (clobber (reg:CC FLAGS_REG))])]
12055 "split_di (operands, 1, operands + 4, operands + 5);")
12057 (define_insn "*rotlsi3_1_one_bit_rex64"
12058 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12059 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12060 (match_operand:QI 2 "const1_operand" "")))
12061 (clobber (reg:CC FLAGS_REG))]
12062 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12063 && (TARGET_SHIFT1 || optimize_size)"
12065 [(set_attr "type" "rotate")
12066 (set (attr "length")
12067 (if_then_else (match_operand:DI 0 "register_operand" "")
12069 (const_string "*")))])
12071 (define_insn "*rotldi3_1_rex64"
12072 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12073 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12074 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12075 (clobber (reg:CC FLAGS_REG))]
12076 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12078 rol{q}\t{%2, %0|%0, %2}
12079 rol{q}\t{%b2, %0|%0, %b2}"
12080 [(set_attr "type" "rotate")
12081 (set_attr "mode" "DI")])
12083 (define_expand "rotlsi3"
12084 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12085 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12086 (match_operand:QI 2 "nonmemory_operand" "")))
12087 (clobber (reg:CC FLAGS_REG))]
12089 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12091 (define_insn "*rotlsi3_1_one_bit"
12092 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12093 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12094 (match_operand:QI 2 "const1_operand" "")))
12095 (clobber (reg:CC FLAGS_REG))]
12096 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12097 && (TARGET_SHIFT1 || optimize_size)"
12099 [(set_attr "type" "rotate")
12100 (set (attr "length")
12101 (if_then_else (match_operand:SI 0 "register_operand" "")
12103 (const_string "*")))])
12105 (define_insn "*rotlsi3_1_one_bit_zext"
12106 [(set (match_operand:DI 0 "register_operand" "=r")
12108 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12109 (match_operand:QI 2 "const1_operand" ""))))
12110 (clobber (reg:CC FLAGS_REG))]
12111 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12112 && (TARGET_SHIFT1 || optimize_size)"
12114 [(set_attr "type" "rotate")
12115 (set_attr "length" "2")])
12117 (define_insn "*rotlsi3_1"
12118 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12119 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12120 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12121 (clobber (reg:CC FLAGS_REG))]
12122 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12124 rol{l}\t{%2, %0|%0, %2}
12125 rol{l}\t{%b2, %0|%0, %b2}"
12126 [(set_attr "type" "rotate")
12127 (set_attr "mode" "SI")])
12129 (define_insn "*rotlsi3_1_zext"
12130 [(set (match_operand:DI 0 "register_operand" "=r,r")
12132 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12133 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12134 (clobber (reg:CC FLAGS_REG))]
12135 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12137 rol{l}\t{%2, %k0|%k0, %2}
12138 rol{l}\t{%b2, %k0|%k0, %b2}"
12139 [(set_attr "type" "rotate")
12140 (set_attr "mode" "SI")])
12142 (define_expand "rotlhi3"
12143 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12144 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12145 (match_operand:QI 2 "nonmemory_operand" "")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "TARGET_HIMODE_MATH"
12148 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12150 (define_insn "*rotlhi3_1_one_bit"
12151 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12152 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12153 (match_operand:QI 2 "const1_operand" "")))
12154 (clobber (reg:CC FLAGS_REG))]
12155 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12156 && (TARGET_SHIFT1 || optimize_size)"
12158 [(set_attr "type" "rotate")
12159 (set (attr "length")
12160 (if_then_else (match_operand 0 "register_operand" "")
12162 (const_string "*")))])
12164 (define_insn "*rotlhi3_1"
12165 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12166 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12167 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12168 (clobber (reg:CC FLAGS_REG))]
12169 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12171 rol{w}\t{%2, %0|%0, %2}
12172 rol{w}\t{%b2, %0|%0, %b2}"
12173 [(set_attr "type" "rotate")
12174 (set_attr "mode" "HI")])
12176 (define_expand "rotlqi3"
12177 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12178 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12179 (match_operand:QI 2 "nonmemory_operand" "")))
12180 (clobber (reg:CC FLAGS_REG))]
12181 "TARGET_QIMODE_MATH"
12182 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12184 (define_insn "*rotlqi3_1_one_bit_slp"
12185 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12186 (rotate:QI (match_dup 0)
12187 (match_operand:QI 1 "const1_operand" "")))
12188 (clobber (reg:CC FLAGS_REG))]
12189 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12190 && (TARGET_SHIFT1 || optimize_size)"
12192 [(set_attr "type" "rotate1")
12193 (set (attr "length")
12194 (if_then_else (match_operand 0 "register_operand" "")
12196 (const_string "*")))])
12198 (define_insn "*rotlqi3_1_one_bit"
12199 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12200 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12201 (match_operand:QI 2 "const1_operand" "")))
12202 (clobber (reg:CC FLAGS_REG))]
12203 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12204 && (TARGET_SHIFT1 || optimize_size)"
12206 [(set_attr "type" "rotate")
12207 (set (attr "length")
12208 (if_then_else (match_operand 0 "register_operand" "")
12210 (const_string "*")))])
12212 (define_insn "*rotlqi3_1_slp"
12213 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12214 (rotate:QI (match_dup 0)
12215 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12216 (clobber (reg:CC FLAGS_REG))]
12217 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12218 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12220 rol{b}\t{%1, %0|%0, %1}
12221 rol{b}\t{%b1, %0|%0, %b1}"
12222 [(set_attr "type" "rotate1")
12223 (set_attr "mode" "QI")])
12225 (define_insn "*rotlqi3_1"
12226 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12227 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12228 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12229 (clobber (reg:CC FLAGS_REG))]
12230 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12232 rol{b}\t{%2, %0|%0, %2}
12233 rol{b}\t{%b2, %0|%0, %b2}"
12234 [(set_attr "type" "rotate")
12235 (set_attr "mode" "QI")])
12237 (define_expand "rotrdi3"
12238 [(set (match_operand:DI 0 "shiftdi_operand" "")
12239 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12240 (match_operand:QI 2 "nonmemory_operand" "")))
12241 (clobber (reg:CC FLAGS_REG))]
12246 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12249 if (!const_1_to_31_operand (operands[2], VOIDmode))
12251 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12255 ;; Implement rotation using two double-precision shift instructions
12256 ;; and a scratch register.
12257 (define_insn_and_split "ix86_rotrdi3"
12258 [(set (match_operand:DI 0 "register_operand" "=r")
12259 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12260 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12261 (clobber (reg:CC FLAGS_REG))
12262 (clobber (match_scratch:SI 3 "=&r"))]
12265 "&& reload_completed"
12266 [(set (match_dup 3) (match_dup 4))
12268 [(set (match_dup 4)
12269 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12270 (ashift:SI (match_dup 5)
12271 (minus:QI (const_int 32) (match_dup 2)))))
12272 (clobber (reg:CC FLAGS_REG))])
12274 [(set (match_dup 5)
12275 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12276 (ashift:SI (match_dup 3)
12277 (minus:QI (const_int 32) (match_dup 2)))))
12278 (clobber (reg:CC FLAGS_REG))])]
12279 "split_di (operands, 1, operands + 4, operands + 5);")
12281 (define_insn "*rotrdi3_1_one_bit_rex64"
12282 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12283 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12284 (match_operand:QI 2 "const1_operand" "")))
12285 (clobber (reg:CC FLAGS_REG))]
12286 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12287 && (TARGET_SHIFT1 || optimize_size)"
12289 [(set_attr "type" "rotate")
12290 (set (attr "length")
12291 (if_then_else (match_operand:DI 0 "register_operand" "")
12293 (const_string "*")))])
12295 (define_insn "*rotrdi3_1_rex64"
12296 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12297 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12298 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12299 (clobber (reg:CC FLAGS_REG))]
12300 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12302 ror{q}\t{%2, %0|%0, %2}
12303 ror{q}\t{%b2, %0|%0, %b2}"
12304 [(set_attr "type" "rotate")
12305 (set_attr "mode" "DI")])
12307 (define_expand "rotrsi3"
12308 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12309 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12310 (match_operand:QI 2 "nonmemory_operand" "")))
12311 (clobber (reg:CC FLAGS_REG))]
12313 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12315 (define_insn "*rotrsi3_1_one_bit"
12316 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12318 (match_operand:QI 2 "const1_operand" "")))
12319 (clobber (reg:CC FLAGS_REG))]
12320 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12321 && (TARGET_SHIFT1 || optimize_size)"
12323 [(set_attr "type" "rotate")
12324 (set (attr "length")
12325 (if_then_else (match_operand:SI 0 "register_operand" "")
12327 (const_string "*")))])
12329 (define_insn "*rotrsi3_1_one_bit_zext"
12330 [(set (match_operand:DI 0 "register_operand" "=r")
12332 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12333 (match_operand:QI 2 "const1_operand" ""))))
12334 (clobber (reg:CC FLAGS_REG))]
12335 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12336 && (TARGET_SHIFT1 || optimize_size)"
12338 [(set_attr "type" "rotate")
12339 (set (attr "length")
12340 (if_then_else (match_operand:SI 0 "register_operand" "")
12342 (const_string "*")))])
12344 (define_insn "*rotrsi3_1"
12345 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12346 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12347 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12348 (clobber (reg:CC FLAGS_REG))]
12349 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12351 ror{l}\t{%2, %0|%0, %2}
12352 ror{l}\t{%b2, %0|%0, %b2}"
12353 [(set_attr "type" "rotate")
12354 (set_attr "mode" "SI")])
12356 (define_insn "*rotrsi3_1_zext"
12357 [(set (match_operand:DI 0 "register_operand" "=r,r")
12359 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12360 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12361 (clobber (reg:CC FLAGS_REG))]
12362 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12364 ror{l}\t{%2, %k0|%k0, %2}
12365 ror{l}\t{%b2, %k0|%k0, %b2}"
12366 [(set_attr "type" "rotate")
12367 (set_attr "mode" "SI")])
12369 (define_expand "rotrhi3"
12370 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12371 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12372 (match_operand:QI 2 "nonmemory_operand" "")))
12373 (clobber (reg:CC FLAGS_REG))]
12374 "TARGET_HIMODE_MATH"
12375 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12377 (define_insn "*rotrhi3_one_bit"
12378 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12379 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12380 (match_operand:QI 2 "const1_operand" "")))
12381 (clobber (reg:CC FLAGS_REG))]
12382 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12383 && (TARGET_SHIFT1 || optimize_size)"
12385 [(set_attr "type" "rotate")
12386 (set (attr "length")
12387 (if_then_else (match_operand 0 "register_operand" "")
12389 (const_string "*")))])
12391 (define_insn "*rotrhi3"
12392 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12393 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12394 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12395 (clobber (reg:CC FLAGS_REG))]
12396 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12398 ror{w}\t{%2, %0|%0, %2}
12399 ror{w}\t{%b2, %0|%0, %b2}"
12400 [(set_attr "type" "rotate")
12401 (set_attr "mode" "HI")])
12403 (define_expand "rotrqi3"
12404 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12405 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12406 (match_operand:QI 2 "nonmemory_operand" "")))
12407 (clobber (reg:CC FLAGS_REG))]
12408 "TARGET_QIMODE_MATH"
12409 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12411 (define_insn "*rotrqi3_1_one_bit"
12412 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12413 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12414 (match_operand:QI 2 "const1_operand" "")))
12415 (clobber (reg:CC FLAGS_REG))]
12416 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12417 && (TARGET_SHIFT1 || optimize_size)"
12419 [(set_attr "type" "rotate")
12420 (set (attr "length")
12421 (if_then_else (match_operand 0 "register_operand" "")
12423 (const_string "*")))])
12425 (define_insn "*rotrqi3_1_one_bit_slp"
12426 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12427 (rotatert:QI (match_dup 0)
12428 (match_operand:QI 1 "const1_operand" "")))
12429 (clobber (reg:CC FLAGS_REG))]
12430 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12431 && (TARGET_SHIFT1 || optimize_size)"
12433 [(set_attr "type" "rotate1")
12434 (set (attr "length")
12435 (if_then_else (match_operand 0 "register_operand" "")
12437 (const_string "*")))])
12439 (define_insn "*rotrqi3_1"
12440 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12441 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12442 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12443 (clobber (reg:CC FLAGS_REG))]
12444 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12446 ror{b}\t{%2, %0|%0, %2}
12447 ror{b}\t{%b2, %0|%0, %b2}"
12448 [(set_attr "type" "rotate")
12449 (set_attr "mode" "QI")])
12451 (define_insn "*rotrqi3_1_slp"
12452 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12453 (rotatert:QI (match_dup 0)
12454 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12455 (clobber (reg:CC FLAGS_REG))]
12456 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12457 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12459 ror{b}\t{%1, %0|%0, %1}
12460 ror{b}\t{%b1, %0|%0, %b1}"
12461 [(set_attr "type" "rotate1")
12462 (set_attr "mode" "QI")])
12464 ;; Bit set / bit test instructions
12466 (define_expand "extv"
12467 [(set (match_operand:SI 0 "register_operand" "")
12468 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12469 (match_operand:SI 2 "immediate_operand" "")
12470 (match_operand:SI 3 "immediate_operand" "")))]
12473 /* Handle extractions from %ah et al. */
12474 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12477 /* From mips.md: extract_bit_field doesn't verify that our source
12478 matches the predicate, so check it again here. */
12479 if (! ext_register_operand (operands[1], VOIDmode))
12483 (define_expand "extzv"
12484 [(set (match_operand:SI 0 "register_operand" "")
12485 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12486 (match_operand:SI 2 "immediate_operand" "")
12487 (match_operand:SI 3 "immediate_operand" "")))]
12490 /* Handle extractions from %ah et al. */
12491 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12494 /* From mips.md: extract_bit_field doesn't verify that our source
12495 matches the predicate, so check it again here. */
12496 if (! ext_register_operand (operands[1], VOIDmode))
12500 (define_expand "insv"
12501 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12502 (match_operand 1 "immediate_operand" "")
12503 (match_operand 2 "immediate_operand" ""))
12504 (match_operand 3 "register_operand" ""))]
12507 /* Handle extractions from %ah et al. */
12508 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12511 /* From mips.md: insert_bit_field doesn't verify that our source
12512 matches the predicate, so check it again here. */
12513 if (! ext_register_operand (operands[0], VOIDmode))
12517 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12519 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12524 ;; %%% bts, btr, btc, bt.
12525 ;; In general these instructions are *slow* when applied to memory,
12526 ;; since they enforce atomic operation. When applied to registers,
12527 ;; it depends on the cpu implementation. They're never faster than
12528 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12529 ;; no point. But in 64-bit, we can't hold the relevant immediates
12530 ;; within the instruction itself, so operating on bits in the high
12531 ;; 32-bits of a register becomes easier.
12533 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12534 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12535 ;; negdf respectively, so they can never be disabled entirely.
12537 (define_insn "*btsq"
12538 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12540 (match_operand:DI 1 "const_0_to_63_operand" ""))
12542 (clobber (reg:CC FLAGS_REG))]
12543 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12545 [(set_attr "type" "alu1")])
12547 (define_insn "*btrq"
12548 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12550 (match_operand:DI 1 "const_0_to_63_operand" ""))
12552 (clobber (reg:CC FLAGS_REG))]
12553 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12555 [(set_attr "type" "alu1")])
12557 (define_insn "*btcq"
12558 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12560 (match_operand:DI 1 "const_0_to_63_operand" ""))
12561 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12562 (clobber (reg:CC FLAGS_REG))]
12563 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12565 [(set_attr "type" "alu1")])
12567 ;; Allow Nocona to avoid these instructions if a register is available.
12570 [(match_scratch:DI 2 "r")
12571 (parallel [(set (zero_extract:DI
12572 (match_operand:DI 0 "register_operand" "")
12574 (match_operand:DI 1 "const_0_to_63_operand" ""))
12576 (clobber (reg:CC FLAGS_REG))])]
12577 "TARGET_64BIT && !TARGET_USE_BT"
12580 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12583 if (HOST_BITS_PER_WIDE_INT >= 64)
12584 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12585 else if (i < HOST_BITS_PER_WIDE_INT)
12586 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12588 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12590 op1 = immed_double_const (lo, hi, DImode);
12593 emit_move_insn (operands[2], op1);
12597 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12602 [(match_scratch:DI 2 "r")
12603 (parallel [(set (zero_extract:DI
12604 (match_operand:DI 0 "register_operand" "")
12606 (match_operand:DI 1 "const_0_to_63_operand" ""))
12608 (clobber (reg:CC FLAGS_REG))])]
12609 "TARGET_64BIT && !TARGET_USE_BT"
12612 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12615 if (HOST_BITS_PER_WIDE_INT >= 64)
12616 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12617 else if (i < HOST_BITS_PER_WIDE_INT)
12618 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12622 op1 = immed_double_const (~lo, ~hi, DImode);
12625 emit_move_insn (operands[2], op1);
12629 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12634 [(match_scratch:DI 2 "r")
12635 (parallel [(set (zero_extract:DI
12636 (match_operand:DI 0 "register_operand" "")
12638 (match_operand:DI 1 "const_0_to_63_operand" ""))
12639 (not:DI (zero_extract:DI
12640 (match_dup 0) (const_int 1) (match_dup 1))))
12641 (clobber (reg:CC FLAGS_REG))])]
12642 "TARGET_64BIT && !TARGET_USE_BT"
12645 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12648 if (HOST_BITS_PER_WIDE_INT >= 64)
12649 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12650 else if (i < HOST_BITS_PER_WIDE_INT)
12651 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12653 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12655 op1 = immed_double_const (lo, hi, DImode);
12658 emit_move_insn (operands[2], op1);
12662 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12666 ;; Store-flag instructions.
12668 ;; For all sCOND expanders, also expand the compare or test insn that
12669 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12671 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12672 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12673 ;; way, which can later delete the movzx if only QImode is needed.
12675 (define_expand "seq"
12676 [(set (match_operand:QI 0 "register_operand" "")
12677 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12679 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12681 (define_expand "sne"
12682 [(set (match_operand:QI 0 "register_operand" "")
12683 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12685 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12687 (define_expand "sgt"
12688 [(set (match_operand:QI 0 "register_operand" "")
12689 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12691 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12693 (define_expand "sgtu"
12694 [(set (match_operand:QI 0 "register_operand" "")
12695 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12697 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12699 (define_expand "slt"
12700 [(set (match_operand:QI 0 "register_operand" "")
12701 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12703 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12705 (define_expand "sltu"
12706 [(set (match_operand:QI 0 "register_operand" "")
12707 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12709 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12711 (define_expand "sge"
12712 [(set (match_operand:QI 0 "register_operand" "")
12713 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12715 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12717 (define_expand "sgeu"
12718 [(set (match_operand:QI 0 "register_operand" "")
12719 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12721 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12723 (define_expand "sle"
12724 [(set (match_operand:QI 0 "register_operand" "")
12725 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12727 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12729 (define_expand "sleu"
12730 [(set (match_operand:QI 0 "register_operand" "")
12731 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12733 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12735 (define_expand "sunordered"
12736 [(set (match_operand:QI 0 "register_operand" "")
12737 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12738 "TARGET_80387 || TARGET_SSE"
12739 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12741 (define_expand "sordered"
12742 [(set (match_operand:QI 0 "register_operand" "")
12743 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12745 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12747 (define_expand "suneq"
12748 [(set (match_operand:QI 0 "register_operand" "")
12749 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12750 "TARGET_80387 || TARGET_SSE"
12751 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12753 (define_expand "sunge"
12754 [(set (match_operand:QI 0 "register_operand" "")
12755 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12756 "TARGET_80387 || TARGET_SSE"
12757 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12759 (define_expand "sungt"
12760 [(set (match_operand:QI 0 "register_operand" "")
12761 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12762 "TARGET_80387 || TARGET_SSE"
12763 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12765 (define_expand "sunle"
12766 [(set (match_operand:QI 0 "register_operand" "")
12767 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12768 "TARGET_80387 || TARGET_SSE"
12769 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12771 (define_expand "sunlt"
12772 [(set (match_operand:QI 0 "register_operand" "")
12773 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12774 "TARGET_80387 || TARGET_SSE"
12775 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12777 (define_expand "sltgt"
12778 [(set (match_operand:QI 0 "register_operand" "")
12779 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12780 "TARGET_80387 || TARGET_SSE"
12781 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12783 (define_insn "*setcc_1"
12784 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12785 (match_operator:QI 1 "ix86_comparison_operator"
12786 [(reg FLAGS_REG) (const_int 0)]))]
12789 [(set_attr "type" "setcc")
12790 (set_attr "mode" "QI")])
12792 (define_insn "*setcc_2"
12793 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12794 (match_operator:QI 1 "ix86_comparison_operator"
12795 [(reg FLAGS_REG) (const_int 0)]))]
12798 [(set_attr "type" "setcc")
12799 (set_attr "mode" "QI")])
12801 ;; In general it is not safe to assume too much about CCmode registers,
12802 ;; so simplify-rtx stops when it sees a second one. Under certain
12803 ;; conditions this is safe on x86, so help combine not create
12810 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12811 (ne:QI (match_operator 1 "ix86_comparison_operator"
12812 [(reg FLAGS_REG) (const_int 0)])
12815 [(set (match_dup 0) (match_dup 1))]
12817 PUT_MODE (operands[1], QImode);
12821 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12822 (ne:QI (match_operator 1 "ix86_comparison_operator"
12823 [(reg FLAGS_REG) (const_int 0)])
12826 [(set (match_dup 0) (match_dup 1))]
12828 PUT_MODE (operands[1], QImode);
12832 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12833 (eq:QI (match_operator 1 "ix86_comparison_operator"
12834 [(reg FLAGS_REG) (const_int 0)])
12837 [(set (match_dup 0) (match_dup 1))]
12839 rtx new_op1 = copy_rtx (operands[1]);
12840 operands[1] = new_op1;
12841 PUT_MODE (new_op1, QImode);
12842 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12843 GET_MODE (XEXP (new_op1, 0))));
12845 /* Make sure that (a) the CCmode we have for the flags is strong
12846 enough for the reversed compare or (b) we have a valid FP compare. */
12847 if (! ix86_comparison_operator (new_op1, VOIDmode))
12852 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12853 (eq:QI (match_operator 1 "ix86_comparison_operator"
12854 [(reg FLAGS_REG) (const_int 0)])
12857 [(set (match_dup 0) (match_dup 1))]
12859 rtx new_op1 = copy_rtx (operands[1]);
12860 operands[1] = new_op1;
12861 PUT_MODE (new_op1, QImode);
12862 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12863 GET_MODE (XEXP (new_op1, 0))));
12865 /* Make sure that (a) the CCmode we have for the flags is strong
12866 enough for the reversed compare or (b) we have a valid FP compare. */
12867 if (! ix86_comparison_operator (new_op1, VOIDmode))
12871 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12872 ;; subsequent logical operations are used to imitate conditional moves.
12873 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12876 (define_insn "*sse_setccsf"
12877 [(set (match_operand:SF 0 "register_operand" "=x")
12878 (match_operator:SF 1 "sse_comparison_operator"
12879 [(match_operand:SF 2 "register_operand" "0")
12880 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12882 "cmp%D1ss\t{%3, %0|%0, %3}"
12883 [(set_attr "type" "ssecmp")
12884 (set_attr "mode" "SF")])
12886 (define_insn "*sse_setccdf"
12887 [(set (match_operand:DF 0 "register_operand" "=Y")
12888 (match_operator:DF 1 "sse_comparison_operator"
12889 [(match_operand:DF 2 "register_operand" "0")
12890 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12892 "cmp%D1sd\t{%3, %0|%0, %3}"
12893 [(set_attr "type" "ssecmp")
12894 (set_attr "mode" "DF")])
12896 ;; Basic conditional jump instructions.
12897 ;; We ignore the overflow flag for signed branch instructions.
12899 ;; For all bCOND expanders, also expand the compare or test insn that
12900 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12902 (define_expand "beq"
12904 (if_then_else (match_dup 1)
12905 (label_ref (match_operand 0 "" ""))
12908 "ix86_expand_branch (EQ, operands[0]); DONE;")
12910 (define_expand "bne"
12912 (if_then_else (match_dup 1)
12913 (label_ref (match_operand 0 "" ""))
12916 "ix86_expand_branch (NE, operands[0]); DONE;")
12918 (define_expand "bgt"
12920 (if_then_else (match_dup 1)
12921 (label_ref (match_operand 0 "" ""))
12924 "ix86_expand_branch (GT, operands[0]); DONE;")
12926 (define_expand "bgtu"
12928 (if_then_else (match_dup 1)
12929 (label_ref (match_operand 0 "" ""))
12932 "ix86_expand_branch (GTU, operands[0]); DONE;")
12934 (define_expand "blt"
12936 (if_then_else (match_dup 1)
12937 (label_ref (match_operand 0 "" ""))
12940 "ix86_expand_branch (LT, operands[0]); DONE;")
12942 (define_expand "bltu"
12944 (if_then_else (match_dup 1)
12945 (label_ref (match_operand 0 "" ""))
12948 "ix86_expand_branch (LTU, operands[0]); DONE;")
12950 (define_expand "bge"
12952 (if_then_else (match_dup 1)
12953 (label_ref (match_operand 0 "" ""))
12956 "ix86_expand_branch (GE, operands[0]); DONE;")
12958 (define_expand "bgeu"
12960 (if_then_else (match_dup 1)
12961 (label_ref (match_operand 0 "" ""))
12964 "ix86_expand_branch (GEU, operands[0]); DONE;")
12966 (define_expand "ble"
12968 (if_then_else (match_dup 1)
12969 (label_ref (match_operand 0 "" ""))
12972 "ix86_expand_branch (LE, operands[0]); DONE;")
12974 (define_expand "bleu"
12976 (if_then_else (match_dup 1)
12977 (label_ref (match_operand 0 "" ""))
12980 "ix86_expand_branch (LEU, operands[0]); DONE;")
12982 (define_expand "bunordered"
12984 (if_then_else (match_dup 1)
12985 (label_ref (match_operand 0 "" ""))
12987 "TARGET_80387 || TARGET_SSE_MATH"
12988 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12990 (define_expand "bordered"
12992 (if_then_else (match_dup 1)
12993 (label_ref (match_operand 0 "" ""))
12995 "TARGET_80387 || TARGET_SSE_MATH"
12996 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12998 (define_expand "buneq"
13000 (if_then_else (match_dup 1)
13001 (label_ref (match_operand 0 "" ""))
13003 "TARGET_80387 || TARGET_SSE_MATH"
13004 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13006 (define_expand "bunge"
13008 (if_then_else (match_dup 1)
13009 (label_ref (match_operand 0 "" ""))
13011 "TARGET_80387 || TARGET_SSE_MATH"
13012 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13014 (define_expand "bungt"
13016 (if_then_else (match_dup 1)
13017 (label_ref (match_operand 0 "" ""))
13019 "TARGET_80387 || TARGET_SSE_MATH"
13020 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13022 (define_expand "bunle"
13024 (if_then_else (match_dup 1)
13025 (label_ref (match_operand 0 "" ""))
13027 "TARGET_80387 || TARGET_SSE_MATH"
13028 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13030 (define_expand "bunlt"
13032 (if_then_else (match_dup 1)
13033 (label_ref (match_operand 0 "" ""))
13035 "TARGET_80387 || TARGET_SSE_MATH"
13036 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13038 (define_expand "bltgt"
13040 (if_then_else (match_dup 1)
13041 (label_ref (match_operand 0 "" ""))
13043 "TARGET_80387 || TARGET_SSE_MATH"
13044 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13046 (define_insn "*jcc_1"
13048 (if_then_else (match_operator 1 "ix86_comparison_operator"
13049 [(reg FLAGS_REG) (const_int 0)])
13050 (label_ref (match_operand 0 "" ""))
13054 [(set_attr "type" "ibr")
13055 (set_attr "modrm" "0")
13056 (set (attr "length")
13057 (if_then_else (and (ge (minus (match_dup 0) (pc))
13059 (lt (minus (match_dup 0) (pc))
13064 (define_insn "*jcc_2"
13066 (if_then_else (match_operator 1 "ix86_comparison_operator"
13067 [(reg FLAGS_REG) (const_int 0)])
13069 (label_ref (match_operand 0 "" ""))))]
13072 [(set_attr "type" "ibr")
13073 (set_attr "modrm" "0")
13074 (set (attr "length")
13075 (if_then_else (and (ge (minus (match_dup 0) (pc))
13077 (lt (minus (match_dup 0) (pc))
13082 ;; In general it is not safe to assume too much about CCmode registers,
13083 ;; so simplify-rtx stops when it sees a second one. Under certain
13084 ;; conditions this is safe on x86, so help combine not create
13092 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13093 [(reg FLAGS_REG) (const_int 0)])
13095 (label_ref (match_operand 1 "" ""))
13099 (if_then_else (match_dup 0)
13100 (label_ref (match_dup 1))
13103 PUT_MODE (operands[0], VOIDmode);
13108 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13109 [(reg FLAGS_REG) (const_int 0)])
13111 (label_ref (match_operand 1 "" ""))
13115 (if_then_else (match_dup 0)
13116 (label_ref (match_dup 1))
13119 rtx new_op0 = copy_rtx (operands[0]);
13120 operands[0] = new_op0;
13121 PUT_MODE (new_op0, VOIDmode);
13122 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13123 GET_MODE (XEXP (new_op0, 0))));
13125 /* Make sure that (a) the CCmode we have for the flags is strong
13126 enough for the reversed compare or (b) we have a valid FP compare. */
13127 if (! ix86_comparison_operator (new_op0, VOIDmode))
13131 ;; Define combination compare-and-branch fp compare instructions to use
13132 ;; during early optimization. Splitting the operation apart early makes
13133 ;; for bad code when we want to reverse the operation.
13135 (define_insn "*fp_jcc_1_mixed"
13137 (if_then_else (match_operator 0 "comparison_operator"
13138 [(match_operand 1 "register_operand" "f#x,x#f")
13139 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13140 (label_ref (match_operand 3 "" ""))
13142 (clobber (reg:CCFP FPSR_REG))
13143 (clobber (reg:CCFP FLAGS_REG))]
13144 "TARGET_MIX_SSE_I387
13145 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13146 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13147 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13150 (define_insn "*fp_jcc_1_sse"
13152 (if_then_else (match_operator 0 "comparison_operator"
13153 [(match_operand 1 "register_operand" "x")
13154 (match_operand 2 "nonimmediate_operand" "xm")])
13155 (label_ref (match_operand 3 "" ""))
13157 (clobber (reg:CCFP FPSR_REG))
13158 (clobber (reg:CCFP FLAGS_REG))]
13160 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13161 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13162 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13165 (define_insn "*fp_jcc_1_387"
13167 (if_then_else (match_operator 0 "comparison_operator"
13168 [(match_operand 1 "register_operand" "f")
13169 (match_operand 2 "register_operand" "f")])
13170 (label_ref (match_operand 3 "" ""))
13172 (clobber (reg:CCFP FPSR_REG))
13173 (clobber (reg:CCFP FLAGS_REG))]
13174 "TARGET_CMOVE && TARGET_80387
13175 && FLOAT_MODE_P (GET_MODE (operands[1]))
13176 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13177 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13180 (define_insn "*fp_jcc_2_mixed"
13182 (if_then_else (match_operator 0 "comparison_operator"
13183 [(match_operand 1 "register_operand" "f#x,x#f")
13184 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13186 (label_ref (match_operand 3 "" ""))))
13187 (clobber (reg:CCFP FPSR_REG))
13188 (clobber (reg:CCFP FLAGS_REG))]
13189 "TARGET_MIX_SSE_I387
13190 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13191 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13192 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13195 (define_insn "*fp_jcc_2_sse"
13197 (if_then_else (match_operator 0 "comparison_operator"
13198 [(match_operand 1 "register_operand" "x")
13199 (match_operand 2 "nonimmediate_operand" "xm")])
13201 (label_ref (match_operand 3 "" ""))))
13202 (clobber (reg:CCFP FPSR_REG))
13203 (clobber (reg:CCFP FLAGS_REG))]
13205 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13206 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13207 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13210 (define_insn "*fp_jcc_2_387"
13212 (if_then_else (match_operator 0 "comparison_operator"
13213 [(match_operand 1 "register_operand" "f")
13214 (match_operand 2 "register_operand" "f")])
13216 (label_ref (match_operand 3 "" ""))))
13217 (clobber (reg:CCFP FPSR_REG))
13218 (clobber (reg:CCFP FLAGS_REG))]
13219 "TARGET_CMOVE && TARGET_80387
13220 && FLOAT_MODE_P (GET_MODE (operands[1]))
13221 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13222 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13225 (define_insn "*fp_jcc_3_387"
13227 (if_then_else (match_operator 0 "comparison_operator"
13228 [(match_operand 1 "register_operand" "f")
13229 (match_operand 2 "nonimmediate_operand" "fm")])
13230 (label_ref (match_operand 3 "" ""))
13232 (clobber (reg:CCFP FPSR_REG))
13233 (clobber (reg:CCFP FLAGS_REG))
13234 (clobber (match_scratch:HI 4 "=a"))]
13236 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13237 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13238 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13239 && SELECT_CC_MODE (GET_CODE (operands[0]),
13240 operands[1], operands[2]) == CCFPmode
13241 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13244 (define_insn "*fp_jcc_4_387"
13246 (if_then_else (match_operator 0 "comparison_operator"
13247 [(match_operand 1 "register_operand" "f")
13248 (match_operand 2 "nonimmediate_operand" "fm")])
13250 (label_ref (match_operand 3 "" ""))))
13251 (clobber (reg:CCFP FPSR_REG))
13252 (clobber (reg:CCFP FLAGS_REG))
13253 (clobber (match_scratch:HI 4 "=a"))]
13255 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13256 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13257 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13258 && SELECT_CC_MODE (GET_CODE (operands[0]),
13259 operands[1], operands[2]) == CCFPmode
13260 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13263 (define_insn "*fp_jcc_5_387"
13265 (if_then_else (match_operator 0 "comparison_operator"
13266 [(match_operand 1 "register_operand" "f")
13267 (match_operand 2 "register_operand" "f")])
13268 (label_ref (match_operand 3 "" ""))
13270 (clobber (reg:CCFP FPSR_REG))
13271 (clobber (reg:CCFP FLAGS_REG))
13272 (clobber (match_scratch:HI 4 "=a"))]
13274 && FLOAT_MODE_P (GET_MODE (operands[1]))
13275 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13276 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13279 (define_insn "*fp_jcc_6_387"
13281 (if_then_else (match_operator 0 "comparison_operator"
13282 [(match_operand 1 "register_operand" "f")
13283 (match_operand 2 "register_operand" "f")])
13285 (label_ref (match_operand 3 "" ""))))
13286 (clobber (reg:CCFP FPSR_REG))
13287 (clobber (reg:CCFP FLAGS_REG))
13288 (clobber (match_scratch:HI 4 "=a"))]
13290 && FLOAT_MODE_P (GET_MODE (operands[1]))
13291 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13292 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13295 (define_insn "*fp_jcc_7_387"
13297 (if_then_else (match_operator 0 "comparison_operator"
13298 [(match_operand 1 "register_operand" "f")
13299 (match_operand 2 "const0_operand" "X")])
13300 (label_ref (match_operand 3 "" ""))
13302 (clobber (reg:CCFP FPSR_REG))
13303 (clobber (reg:CCFP FLAGS_REG))
13304 (clobber (match_scratch:HI 4 "=a"))]
13306 && FLOAT_MODE_P (GET_MODE (operands[1]))
13307 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13308 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13309 && SELECT_CC_MODE (GET_CODE (operands[0]),
13310 operands[1], operands[2]) == CCFPmode
13311 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13314 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13315 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13316 ;; with a precedence over other operators and is always put in the first
13317 ;; place. Swap condition and operands to match ficom instruction.
13319 (define_insn "*fp_jcc_8<mode>_387"
13321 (if_then_else (match_operator 0 "comparison_operator"
13322 [(match_operator 1 "float_operator"
13323 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13324 (match_operand 3 "register_operand" "f,f")])
13325 (label_ref (match_operand 4 "" ""))
13327 (clobber (reg:CCFP FPSR_REG))
13328 (clobber (reg:CCFP FLAGS_REG))
13329 (clobber (match_scratch:HI 5 "=a,a"))]
13330 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13331 && FLOAT_MODE_P (GET_MODE (operands[3]))
13332 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13333 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13334 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13335 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13340 (if_then_else (match_operator 0 "comparison_operator"
13341 [(match_operand 1 "register_operand" "")
13342 (match_operand 2 "nonimmediate_operand" "")])
13343 (match_operand 3 "" "")
13344 (match_operand 4 "" "")))
13345 (clobber (reg:CCFP FPSR_REG))
13346 (clobber (reg:CCFP FLAGS_REG))]
13350 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13351 operands[3], operands[4], NULL_RTX, NULL_RTX);
13357 (if_then_else (match_operator 0 "comparison_operator"
13358 [(match_operand 1 "register_operand" "")
13359 (match_operand 2 "general_operand" "")])
13360 (match_operand 3 "" "")
13361 (match_operand 4 "" "")))
13362 (clobber (reg:CCFP FPSR_REG))
13363 (clobber (reg:CCFP FLAGS_REG))
13364 (clobber (match_scratch:HI 5 "=a"))]
13368 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13369 operands[3], operands[4], operands[5], NULL_RTX);
13375 (if_then_else (match_operator 0 "comparison_operator"
13376 [(match_operator 1 "float_operator"
13377 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13378 (match_operand 3 "register_operand" "")])
13379 (match_operand 4 "" "")
13380 (match_operand 5 "" "")))
13381 (clobber (reg:CCFP FPSR_REG))
13382 (clobber (reg:CCFP FLAGS_REG))
13383 (clobber (match_scratch:HI 6 "=a"))]
13387 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13388 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13389 operands[3], operands[7],
13390 operands[4], operands[5], operands[6], NULL_RTX);
13394 ;; %%% Kill this when reload knows how to do it.
13397 (if_then_else (match_operator 0 "comparison_operator"
13398 [(match_operator 1 "float_operator"
13399 [(match_operand:X87MODEI12 2 "register_operand" "")])
13400 (match_operand 3 "register_operand" "")])
13401 (match_operand 4 "" "")
13402 (match_operand 5 "" "")))
13403 (clobber (reg:CCFP FPSR_REG))
13404 (clobber (reg:CCFP FLAGS_REG))
13405 (clobber (match_scratch:HI 6 "=a"))]
13409 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13410 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13411 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13412 operands[3], operands[7],
13413 operands[4], operands[5], operands[6], operands[2]);
13417 ;; Unconditional and other jump instructions
13419 (define_insn "jump"
13421 (label_ref (match_operand 0 "" "")))]
13424 [(set_attr "type" "ibr")
13425 (set (attr "length")
13426 (if_then_else (and (ge (minus (match_dup 0) (pc))
13428 (lt (minus (match_dup 0) (pc))
13432 (set_attr "modrm" "0")])
13434 (define_expand "indirect_jump"
13435 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13439 (define_insn "*indirect_jump"
13440 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13443 [(set_attr "type" "ibr")
13444 (set_attr "length_immediate" "0")])
13446 (define_insn "*indirect_jump_rtx64"
13447 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13450 [(set_attr "type" "ibr")
13451 (set_attr "length_immediate" "0")])
13453 (define_expand "tablejump"
13454 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13455 (use (label_ref (match_operand 1 "" "")))])]
13458 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13459 relative. Convert the relative address to an absolute address. */
13463 enum rtx_code code;
13469 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13471 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13475 op1 = pic_offset_table_rtx;
13480 op0 = pic_offset_table_rtx;
13484 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13489 (define_insn "*tablejump_1"
13490 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13491 (use (label_ref (match_operand 1 "" "")))]
13494 [(set_attr "type" "ibr")
13495 (set_attr "length_immediate" "0")])
13497 (define_insn "*tablejump_1_rtx64"
13498 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13499 (use (label_ref (match_operand 1 "" "")))]
13502 [(set_attr "type" "ibr")
13503 (set_attr "length_immediate" "0")])
13505 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13508 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13509 (set (match_operand:QI 1 "register_operand" "")
13510 (match_operator:QI 2 "ix86_comparison_operator"
13511 [(reg FLAGS_REG) (const_int 0)]))
13512 (set (match_operand 3 "q_regs_operand" "")
13513 (zero_extend (match_dup 1)))]
13514 "(peep2_reg_dead_p (3, operands[1])
13515 || operands_match_p (operands[1], operands[3]))
13516 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13517 [(set (match_dup 4) (match_dup 0))
13518 (set (strict_low_part (match_dup 5))
13521 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13522 operands[5] = gen_lowpart (QImode, operands[3]);
13523 ix86_expand_clear (operands[3]);
13526 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13529 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13530 (set (match_operand:QI 1 "register_operand" "")
13531 (match_operator:QI 2 "ix86_comparison_operator"
13532 [(reg FLAGS_REG) (const_int 0)]))
13533 (parallel [(set (match_operand 3 "q_regs_operand" "")
13534 (zero_extend (match_dup 1)))
13535 (clobber (reg:CC FLAGS_REG))])]
13536 "(peep2_reg_dead_p (3, operands[1])
13537 || operands_match_p (operands[1], operands[3]))
13538 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13539 [(set (match_dup 4) (match_dup 0))
13540 (set (strict_low_part (match_dup 5))
13543 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13544 operands[5] = gen_lowpart (QImode, operands[3]);
13545 ix86_expand_clear (operands[3]);
13548 ;; Call instructions.
13550 ;; The predicates normally associated with named expanders are not properly
13551 ;; checked for calls. This is a bug in the generic code, but it isn't that
13552 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13554 ;; Call subroutine returning no value.
13556 (define_expand "call_pop"
13557 [(parallel [(call (match_operand:QI 0 "" "")
13558 (match_operand:SI 1 "" ""))
13559 (set (reg:SI SP_REG)
13560 (plus:SI (reg:SI SP_REG)
13561 (match_operand:SI 3 "" "")))])]
13564 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13568 (define_insn "*call_pop_0"
13569 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13570 (match_operand:SI 1 "" ""))
13571 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13572 (match_operand:SI 2 "immediate_operand" "")))]
13575 if (SIBLING_CALL_P (insn))
13578 return "call\t%P0";
13580 [(set_attr "type" "call")])
13582 (define_insn "*call_pop_1"
13583 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13584 (match_operand:SI 1 "" ""))
13585 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13586 (match_operand:SI 2 "immediate_operand" "i")))]
13589 if (constant_call_address_operand (operands[0], Pmode))
13591 if (SIBLING_CALL_P (insn))
13594 return "call\t%P0";
13596 if (SIBLING_CALL_P (insn))
13599 return "call\t%A0";
13601 [(set_attr "type" "call")])
13603 (define_expand "call"
13604 [(call (match_operand:QI 0 "" "")
13605 (match_operand 1 "" ""))
13606 (use (match_operand 2 "" ""))]
13609 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13613 (define_expand "sibcall"
13614 [(call (match_operand:QI 0 "" "")
13615 (match_operand 1 "" ""))
13616 (use (match_operand 2 "" ""))]
13619 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13623 (define_insn "*call_0"
13624 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13625 (match_operand 1 "" ""))]
13628 if (SIBLING_CALL_P (insn))
13631 return "call\t%P0";
13633 [(set_attr "type" "call")])
13635 (define_insn "*call_1"
13636 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13637 (match_operand 1 "" ""))]
13638 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13640 if (constant_call_address_operand (operands[0], Pmode))
13641 return "call\t%P0";
13642 return "call\t%A0";
13644 [(set_attr "type" "call")])
13646 (define_insn "*sibcall_1"
13647 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13648 (match_operand 1 "" ""))]
13649 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13651 if (constant_call_address_operand (operands[0], Pmode))
13655 [(set_attr "type" "call")])
13657 (define_insn "*call_1_rex64"
13658 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13659 (match_operand 1 "" ""))]
13660 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13662 if (constant_call_address_operand (operands[0], Pmode))
13663 return "call\t%P0";
13664 return "call\t%A0";
13666 [(set_attr "type" "call")])
13668 (define_insn "*sibcall_1_rex64"
13669 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13670 (match_operand 1 "" ""))]
13671 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13673 [(set_attr "type" "call")])
13675 (define_insn "*sibcall_1_rex64_v"
13676 [(call (mem:QI (reg:DI 40))
13677 (match_operand 0 "" ""))]
13678 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13680 [(set_attr "type" "call")])
13683 ;; Call subroutine, returning value in operand 0
13685 (define_expand "call_value_pop"
13686 [(parallel [(set (match_operand 0 "" "")
13687 (call (match_operand:QI 1 "" "")
13688 (match_operand:SI 2 "" "")))
13689 (set (reg:SI SP_REG)
13690 (plus:SI (reg:SI SP_REG)
13691 (match_operand:SI 4 "" "")))])]
13694 ix86_expand_call (operands[0], operands[1], operands[2],
13695 operands[3], operands[4], 0);
13699 (define_expand "call_value"
13700 [(set (match_operand 0 "" "")
13701 (call (match_operand:QI 1 "" "")
13702 (match_operand:SI 2 "" "")))
13703 (use (match_operand:SI 3 "" ""))]
13704 ;; Operand 2 not used on the i386.
13707 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13711 (define_expand "sibcall_value"
13712 [(set (match_operand 0 "" "")
13713 (call (match_operand:QI 1 "" "")
13714 (match_operand:SI 2 "" "")))
13715 (use (match_operand:SI 3 "" ""))]
13716 ;; Operand 2 not used on the i386.
13719 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13723 ;; Call subroutine returning any type.
13725 (define_expand "untyped_call"
13726 [(parallel [(call (match_operand 0 "" "")
13728 (match_operand 1 "" "")
13729 (match_operand 2 "" "")])]
13734 /* In order to give reg-stack an easier job in validating two
13735 coprocessor registers as containing a possible return value,
13736 simply pretend the untyped call returns a complex long double
13739 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13740 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13741 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13744 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13746 rtx set = XVECEXP (operands[2], 0, i);
13747 emit_move_insn (SET_DEST (set), SET_SRC (set));
13750 /* The optimizer does not know that the call sets the function value
13751 registers we stored in the result block. We avoid problems by
13752 claiming that all hard registers are used and clobbered at this
13754 emit_insn (gen_blockage (const0_rtx));
13759 ;; Prologue and epilogue instructions
13761 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13762 ;; all of memory. This blocks insns from being moved across this point.
13764 (define_insn "blockage"
13765 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13768 [(set_attr "length" "0")])
13770 ;; Insn emitted into the body of a function to return from a function.
13771 ;; This is only done if the function's epilogue is known to be simple.
13772 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13774 (define_expand "return"
13776 "ix86_can_use_return_insn_p ()"
13778 if (current_function_pops_args)
13780 rtx popc = GEN_INT (current_function_pops_args);
13781 emit_jump_insn (gen_return_pop_internal (popc));
13786 (define_insn "return_internal"
13790 [(set_attr "length" "1")
13791 (set_attr "length_immediate" "0")
13792 (set_attr "modrm" "0")])
13794 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13795 ;; instruction Athlon and K8 have.
13797 (define_insn "return_internal_long"
13799 (unspec [(const_int 0)] UNSPEC_REP)]
13802 [(set_attr "length" "1")
13803 (set_attr "length_immediate" "0")
13804 (set_attr "prefix_rep" "1")
13805 (set_attr "modrm" "0")])
13807 (define_insn "return_pop_internal"
13809 (use (match_operand:SI 0 "const_int_operand" ""))]
13812 [(set_attr "length" "3")
13813 (set_attr "length_immediate" "2")
13814 (set_attr "modrm" "0")])
13816 (define_insn "return_indirect_internal"
13818 (use (match_operand:SI 0 "register_operand" "r"))]
13821 [(set_attr "type" "ibr")
13822 (set_attr "length_immediate" "0")])
13828 [(set_attr "length" "1")
13829 (set_attr "length_immediate" "0")
13830 (set_attr "modrm" "0")])
13832 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13833 ;; branch prediction penalty for the third jump in a 16-byte
13836 (define_insn "align"
13837 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13840 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13841 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13843 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13844 The align insn is used to avoid 3 jump instructions in the row to improve
13845 branch prediction and the benefits hardly outweight the cost of extra 8
13846 nops on the average inserted by full alignment pseudo operation. */
13850 [(set_attr "length" "16")])
13852 (define_expand "prologue"
13855 "ix86_expand_prologue (); DONE;")
13857 (define_insn "set_got"
13858 [(set (match_operand:SI 0 "register_operand" "=r")
13859 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13860 (clobber (reg:CC FLAGS_REG))]
13862 { return output_set_got (operands[0]); }
13863 [(set_attr "type" "multi")
13864 (set_attr "length" "12")])
13866 (define_insn "set_got_rex64"
13867 [(set (match_operand:DI 0 "register_operand" "=r")
13868 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13870 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13871 [(set_attr "type" "lea")
13872 (set_attr "length" "6")])
13874 (define_expand "epilogue"
13877 "ix86_expand_epilogue (1); DONE;")
13879 (define_expand "sibcall_epilogue"
13882 "ix86_expand_epilogue (0); DONE;")
13884 (define_expand "eh_return"
13885 [(use (match_operand 0 "register_operand" ""))]
13888 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13890 /* Tricky bit: we write the address of the handler to which we will
13891 be returning into someone else's stack frame, one word below the
13892 stack address we wish to restore. */
13893 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13894 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13895 tmp = gen_rtx_MEM (Pmode, tmp);
13896 emit_move_insn (tmp, ra);
13898 if (Pmode == SImode)
13899 emit_jump_insn (gen_eh_return_si (sa));
13901 emit_jump_insn (gen_eh_return_di (sa));
13906 (define_insn_and_split "eh_return_si"
13908 (unspec [(match_operand:SI 0 "register_operand" "c")]
13909 UNSPEC_EH_RETURN))]
13914 "ix86_expand_epilogue (2); DONE;")
13916 (define_insn_and_split "eh_return_di"
13918 (unspec [(match_operand:DI 0 "register_operand" "c")]
13919 UNSPEC_EH_RETURN))]
13924 "ix86_expand_epilogue (2); DONE;")
13926 (define_insn "leave"
13927 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13928 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13929 (clobber (mem:BLK (scratch)))]
13932 [(set_attr "type" "leave")])
13934 (define_insn "leave_rex64"
13935 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13936 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13937 (clobber (mem:BLK (scratch)))]
13940 [(set_attr "type" "leave")])
13942 (define_expand "ffssi2"
13944 [(set (match_operand:SI 0 "register_operand" "")
13945 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13946 (clobber (match_scratch:SI 2 ""))
13947 (clobber (reg:CC FLAGS_REG))])]
13951 (define_insn_and_split "*ffs_cmove"
13952 [(set (match_operand:SI 0 "register_operand" "=r")
13953 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13954 (clobber (match_scratch:SI 2 "=&r"))
13955 (clobber (reg:CC FLAGS_REG))]
13958 "&& reload_completed"
13959 [(set (match_dup 2) (const_int -1))
13960 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13961 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13962 (set (match_dup 0) (if_then_else:SI
13963 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13966 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13967 (clobber (reg:CC FLAGS_REG))])]
13970 (define_insn_and_split "*ffs_no_cmove"
13971 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13972 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13973 (clobber (match_scratch:SI 2 "=&q"))
13974 (clobber (reg:CC FLAGS_REG))]
13978 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13979 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13980 (set (strict_low_part (match_dup 3))
13981 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13982 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13983 (clobber (reg:CC FLAGS_REG))])
13984 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13985 (clobber (reg:CC FLAGS_REG))])
13986 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13987 (clobber (reg:CC FLAGS_REG))])]
13989 operands[3] = gen_lowpart (QImode, operands[2]);
13990 ix86_expand_clear (operands[2]);
13993 (define_insn "*ffssi_1"
13994 [(set (reg:CCZ FLAGS_REG)
13995 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13997 (set (match_operand:SI 0 "register_operand" "=r")
13998 (ctz:SI (match_dup 1)))]
14000 "bsf{l}\t{%1, %0|%0, %1}"
14001 [(set_attr "prefix_0f" "1")])
14003 (define_expand "ffsdi2"
14005 [(set (match_operand:DI 0 "register_operand" "")
14006 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14007 (clobber (match_scratch:DI 2 ""))
14008 (clobber (reg:CC FLAGS_REG))])]
14009 "TARGET_64BIT && TARGET_CMOVE"
14012 (define_insn_and_split "*ffs_rex64"
14013 [(set (match_operand:DI 0 "register_operand" "=r")
14014 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14015 (clobber (match_scratch:DI 2 "=&r"))
14016 (clobber (reg:CC FLAGS_REG))]
14017 "TARGET_64BIT && TARGET_CMOVE"
14019 "&& reload_completed"
14020 [(set (match_dup 2) (const_int -1))
14021 (parallel [(set (reg:CCZ FLAGS_REG)
14022 (compare:CCZ (match_dup 1) (const_int 0)))
14023 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14024 (set (match_dup 0) (if_then_else:DI
14025 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14028 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14029 (clobber (reg:CC FLAGS_REG))])]
14032 (define_insn "*ffsdi_1"
14033 [(set (reg:CCZ FLAGS_REG)
14034 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14036 (set (match_operand:DI 0 "register_operand" "=r")
14037 (ctz:DI (match_dup 1)))]
14039 "bsf{q}\t{%1, %0|%0, %1}"
14040 [(set_attr "prefix_0f" "1")])
14042 (define_insn "ctzsi2"
14043 [(set (match_operand:SI 0 "register_operand" "=r")
14044 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14045 (clobber (reg:CC FLAGS_REG))]
14047 "bsf{l}\t{%1, %0|%0, %1}"
14048 [(set_attr "prefix_0f" "1")])
14050 (define_insn "ctzdi2"
14051 [(set (match_operand:DI 0 "register_operand" "=r")
14052 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14053 (clobber (reg:CC FLAGS_REG))]
14055 "bsf{q}\t{%1, %0|%0, %1}"
14056 [(set_attr "prefix_0f" "1")])
14058 (define_expand "clzsi2"
14060 [(set (match_operand:SI 0 "register_operand" "")
14061 (minus:SI (const_int 31)
14062 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14063 (clobber (reg:CC FLAGS_REG))])
14065 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14066 (clobber (reg:CC FLAGS_REG))])]
14070 (define_insn "*bsr"
14071 [(set (match_operand:SI 0 "register_operand" "=r")
14072 (minus:SI (const_int 31)
14073 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14074 (clobber (reg:CC FLAGS_REG))]
14076 "bsr{l}\t{%1, %0|%0, %1}"
14077 [(set_attr "prefix_0f" "1")])
14079 (define_expand "clzdi2"
14081 [(set (match_operand:DI 0 "register_operand" "")
14082 (minus:DI (const_int 63)
14083 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14084 (clobber (reg:CC FLAGS_REG))])
14086 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14087 (clobber (reg:CC FLAGS_REG))])]
14091 (define_insn "*bsr_rex64"
14092 [(set (match_operand:DI 0 "register_operand" "=r")
14093 (minus:DI (const_int 63)
14094 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14095 (clobber (reg:CC FLAGS_REG))]
14097 "bsr{q}\t{%1, %0|%0, %1}"
14098 [(set_attr "prefix_0f" "1")])
14100 ;; Thread-local storage patterns for ELF.
14102 ;; Note that these code sequences must appear exactly as shown
14103 ;; in order to allow linker relaxation.
14105 (define_insn "*tls_global_dynamic_32_gnu"
14106 [(set (match_operand:SI 0 "register_operand" "=a")
14107 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14108 (match_operand:SI 2 "tls_symbolic_operand" "")
14109 (match_operand:SI 3 "call_insn_operand" "")]
14111 (clobber (match_scratch:SI 4 "=d"))
14112 (clobber (match_scratch:SI 5 "=c"))
14113 (clobber (reg:CC FLAGS_REG))]
14114 "!TARGET_64BIT && TARGET_GNU_TLS"
14115 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14116 [(set_attr "type" "multi")
14117 (set_attr "length" "12")])
14119 (define_insn "*tls_global_dynamic_32_sun"
14120 [(set (match_operand:SI 0 "register_operand" "=a")
14121 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14122 (match_operand:SI 2 "tls_symbolic_operand" "")
14123 (match_operand:SI 3 "call_insn_operand" "")]
14125 (clobber (match_scratch:SI 4 "=d"))
14126 (clobber (match_scratch:SI 5 "=c"))
14127 (clobber (reg:CC FLAGS_REG))]
14128 "!TARGET_64BIT && TARGET_SUN_TLS"
14129 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14130 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14131 [(set_attr "type" "multi")
14132 (set_attr "length" "14")])
14134 (define_expand "tls_global_dynamic_32"
14135 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14138 (match_operand:SI 1 "tls_symbolic_operand" "")
14141 (clobber (match_scratch:SI 4 ""))
14142 (clobber (match_scratch:SI 5 ""))
14143 (clobber (reg:CC FLAGS_REG))])]
14147 operands[2] = pic_offset_table_rtx;
14150 operands[2] = gen_reg_rtx (Pmode);
14151 emit_insn (gen_set_got (operands[2]));
14153 operands[3] = ix86_tls_get_addr ();
14156 (define_insn "*tls_global_dynamic_64"
14157 [(set (match_operand:DI 0 "register_operand" "=a")
14158 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14159 (match_operand:DI 3 "" "")))
14160 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14163 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14164 [(set_attr "type" "multi")
14165 (set_attr "length" "16")])
14167 (define_expand "tls_global_dynamic_64"
14168 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14169 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14170 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14174 operands[2] = ix86_tls_get_addr ();
14177 (define_insn "*tls_local_dynamic_base_32_gnu"
14178 [(set (match_operand:SI 0 "register_operand" "=a")
14179 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14180 (match_operand:SI 2 "call_insn_operand" "")]
14181 UNSPEC_TLS_LD_BASE))
14182 (clobber (match_scratch:SI 3 "=d"))
14183 (clobber (match_scratch:SI 4 "=c"))
14184 (clobber (reg:CC FLAGS_REG))]
14185 "!TARGET_64BIT && TARGET_GNU_TLS"
14186 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14187 [(set_attr "type" "multi")
14188 (set_attr "length" "11")])
14190 (define_insn "*tls_local_dynamic_base_32_sun"
14191 [(set (match_operand:SI 0 "register_operand" "=a")
14192 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14193 (match_operand:SI 2 "call_insn_operand" "")]
14194 UNSPEC_TLS_LD_BASE))
14195 (clobber (match_scratch:SI 3 "=d"))
14196 (clobber (match_scratch:SI 4 "=c"))
14197 (clobber (reg:CC FLAGS_REG))]
14198 "!TARGET_64BIT && TARGET_SUN_TLS"
14199 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14200 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14201 [(set_attr "type" "multi")
14202 (set_attr "length" "13")])
14204 (define_expand "tls_local_dynamic_base_32"
14205 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14206 (unspec:SI [(match_dup 1) (match_dup 2)]
14207 UNSPEC_TLS_LD_BASE))
14208 (clobber (match_scratch:SI 3 ""))
14209 (clobber (match_scratch:SI 4 ""))
14210 (clobber (reg:CC FLAGS_REG))])]
14214 operands[1] = pic_offset_table_rtx;
14217 operands[1] = gen_reg_rtx (Pmode);
14218 emit_insn (gen_set_got (operands[1]));
14220 operands[2] = ix86_tls_get_addr ();
14223 (define_insn "*tls_local_dynamic_base_64"
14224 [(set (match_operand:DI 0 "register_operand" "=a")
14225 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14226 (match_operand:DI 2 "" "")))
14227 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14229 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14230 [(set_attr "type" "multi")
14231 (set_attr "length" "12")])
14233 (define_expand "tls_local_dynamic_base_64"
14234 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14235 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14236 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14239 operands[1] = ix86_tls_get_addr ();
14242 ;; Local dynamic of a single variable is a lose. Show combine how
14243 ;; to convert that back to global dynamic.
14245 (define_insn_and_split "*tls_local_dynamic_32_once"
14246 [(set (match_operand:SI 0 "register_operand" "=a")
14247 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14248 (match_operand:SI 2 "call_insn_operand" "")]
14249 UNSPEC_TLS_LD_BASE)
14250 (const:SI (unspec:SI
14251 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14253 (clobber (match_scratch:SI 4 "=d"))
14254 (clobber (match_scratch:SI 5 "=c"))
14255 (clobber (reg:CC FLAGS_REG))]
14259 [(parallel [(set (match_dup 0)
14260 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14262 (clobber (match_dup 4))
14263 (clobber (match_dup 5))
14264 (clobber (reg:CC FLAGS_REG))])]
14267 ;; Load and add the thread base pointer from %gs:0.
14269 (define_insn "*load_tp_si"
14270 [(set (match_operand:SI 0 "register_operand" "=r")
14271 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14273 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14274 [(set_attr "type" "imov")
14275 (set_attr "modrm" "0")
14276 (set_attr "length" "7")
14277 (set_attr "memory" "load")
14278 (set_attr "imm_disp" "false")])
14280 (define_insn "*add_tp_si"
14281 [(set (match_operand:SI 0 "register_operand" "=r")
14282 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14283 (match_operand:SI 1 "register_operand" "0")))
14284 (clobber (reg:CC FLAGS_REG))]
14286 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14287 [(set_attr "type" "alu")
14288 (set_attr "modrm" "0")
14289 (set_attr "length" "7")
14290 (set_attr "memory" "load")
14291 (set_attr "imm_disp" "false")])
14293 (define_insn "*load_tp_di"
14294 [(set (match_operand:DI 0 "register_operand" "=r")
14295 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14297 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14298 [(set_attr "type" "imov")
14299 (set_attr "modrm" "0")
14300 (set_attr "length" "7")
14301 (set_attr "memory" "load")
14302 (set_attr "imm_disp" "false")])
14304 (define_insn "*add_tp_di"
14305 [(set (match_operand:DI 0 "register_operand" "=r")
14306 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14307 (match_operand:DI 1 "register_operand" "0")))
14308 (clobber (reg:CC FLAGS_REG))]
14310 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14311 [(set_attr "type" "alu")
14312 (set_attr "modrm" "0")
14313 (set_attr "length" "7")
14314 (set_attr "memory" "load")
14315 (set_attr "imm_disp" "false")])
14317 ;; These patterns match the binary 387 instructions for addM3, subM3,
14318 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14319 ;; SFmode. The first is the normal insn, the second the same insn but
14320 ;; with one operand a conversion, and the third the same insn but with
14321 ;; the other operand a conversion. The conversion may be SFmode or
14322 ;; SImode if the target mode DFmode, but only SImode if the target mode
14325 ;; Gcc is slightly more smart about handling normal two address instructions
14326 ;; so use special patterns for add and mull.
14328 (define_insn "*fop_sf_comm_mixed"
14329 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14330 (match_operator:SF 3 "binary_fp_operator"
14331 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14332 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14333 "TARGET_MIX_SSE_I387
14334 && COMMUTATIVE_ARITH_P (operands[3])
14335 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14336 "* return output_387_binary_op (insn, operands);"
14337 [(set (attr "type")
14338 (if_then_else (eq_attr "alternative" "1")
14339 (if_then_else (match_operand:SF 3 "mult_operator" "")
14340 (const_string "ssemul")
14341 (const_string "sseadd"))
14342 (if_then_else (match_operand:SF 3 "mult_operator" "")
14343 (const_string "fmul")
14344 (const_string "fop"))))
14345 (set_attr "mode" "SF")])
14347 (define_insn "*fop_sf_comm_sse"
14348 [(set (match_operand:SF 0 "register_operand" "=x")
14349 (match_operator:SF 3 "binary_fp_operator"
14350 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14351 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14353 && COMMUTATIVE_ARITH_P (operands[3])
14354 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14355 "* return output_387_binary_op (insn, operands);"
14356 [(set (attr "type")
14357 (if_then_else (match_operand:SF 3 "mult_operator" "")
14358 (const_string "ssemul")
14359 (const_string "sseadd")))
14360 (set_attr "mode" "SF")])
14362 (define_insn "*fop_sf_comm_i387"
14363 [(set (match_operand:SF 0 "register_operand" "=f")
14364 (match_operator:SF 3 "binary_fp_operator"
14365 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14366 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14368 && COMMUTATIVE_ARITH_P (operands[3])
14369 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14370 "* return output_387_binary_op (insn, operands);"
14371 [(set (attr "type")
14372 (if_then_else (match_operand:SF 3 "mult_operator" "")
14373 (const_string "fmul")
14374 (const_string "fop")))
14375 (set_attr "mode" "SF")])
14377 (define_insn "*fop_sf_1_mixed"
14378 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14379 (match_operator:SF 3 "binary_fp_operator"
14380 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14381 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14382 "TARGET_MIX_SSE_I387
14383 && !COMMUTATIVE_ARITH_P (operands[3])
14384 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14385 "* return output_387_binary_op (insn, operands);"
14386 [(set (attr "type")
14387 (cond [(and (eq_attr "alternative" "2")
14388 (match_operand:SF 3 "mult_operator" ""))
14389 (const_string "ssemul")
14390 (and (eq_attr "alternative" "2")
14391 (match_operand:SF 3 "div_operator" ""))
14392 (const_string "ssediv")
14393 (eq_attr "alternative" "2")
14394 (const_string "sseadd")
14395 (match_operand:SF 3 "mult_operator" "")
14396 (const_string "fmul")
14397 (match_operand:SF 3 "div_operator" "")
14398 (const_string "fdiv")
14400 (const_string "fop")))
14401 (set_attr "mode" "SF")])
14403 (define_insn "*fop_sf_1_sse"
14404 [(set (match_operand:SF 0 "register_operand" "=x")
14405 (match_operator:SF 3 "binary_fp_operator"
14406 [(match_operand:SF 1 "register_operand" "0")
14407 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14409 && !COMMUTATIVE_ARITH_P (operands[3])"
14410 "* return output_387_binary_op (insn, operands);"
14411 [(set (attr "type")
14412 (cond [(match_operand:SF 3 "mult_operator" "")
14413 (const_string "ssemul")
14414 (match_operand:SF 3 "div_operator" "")
14415 (const_string "ssediv")
14417 (const_string "sseadd")))
14418 (set_attr "mode" "SF")])
14420 ;; This pattern is not fully shadowed by the pattern above.
14421 (define_insn "*fop_sf_1_i387"
14422 [(set (match_operand:SF 0 "register_operand" "=f,f")
14423 (match_operator:SF 3 "binary_fp_operator"
14424 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14425 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14426 "TARGET_80387 && !TARGET_SSE_MATH
14427 && !COMMUTATIVE_ARITH_P (operands[3])
14428 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14429 "* return output_387_binary_op (insn, operands);"
14430 [(set (attr "type")
14431 (cond [(match_operand:SF 3 "mult_operator" "")
14432 (const_string "fmul")
14433 (match_operand:SF 3 "div_operator" "")
14434 (const_string "fdiv")
14436 (const_string "fop")))
14437 (set_attr "mode" "SF")])
14439 ;; ??? Add SSE splitters for these!
14440 (define_insn "*fop_sf_2<mode>_i387"
14441 [(set (match_operand:SF 0 "register_operand" "=f,f")
14442 (match_operator:SF 3 "binary_fp_operator"
14443 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14444 (match_operand:SF 2 "register_operand" "0,0")]))]
14445 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14446 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14447 [(set (attr "type")
14448 (cond [(match_operand:SF 3 "mult_operator" "")
14449 (const_string "fmul")
14450 (match_operand:SF 3 "div_operator" "")
14451 (const_string "fdiv")
14453 (const_string "fop")))
14454 (set_attr "fp_int_src" "true")
14455 (set_attr "mode" "<MODE>")])
14457 (define_insn "*fop_sf_3<mode>_i387"
14458 [(set (match_operand:SF 0 "register_operand" "=f,f")
14459 (match_operator:SF 3 "binary_fp_operator"
14460 [(match_operand:SF 1 "register_operand" "0,0")
14461 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14462 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14463 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14464 [(set (attr "type")
14465 (cond [(match_operand:SF 3 "mult_operator" "")
14466 (const_string "fmul")
14467 (match_operand:SF 3 "div_operator" "")
14468 (const_string "fdiv")
14470 (const_string "fop")))
14471 (set_attr "fp_int_src" "true")
14472 (set_attr "mode" "<MODE>")])
14474 (define_insn "*fop_df_comm_mixed"
14475 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14476 (match_operator:DF 3 "binary_fp_operator"
14477 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14478 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14479 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14480 && COMMUTATIVE_ARITH_P (operands[3])
14481 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14482 "* return output_387_binary_op (insn, operands);"
14483 [(set (attr "type")
14484 (if_then_else (eq_attr "alternative" "1")
14485 (if_then_else (match_operand:SF 3 "mult_operator" "")
14486 (const_string "ssemul")
14487 (const_string "sseadd"))
14488 (if_then_else (match_operand:SF 3 "mult_operator" "")
14489 (const_string "fmul")
14490 (const_string "fop"))))
14491 (set_attr "mode" "DF")])
14493 (define_insn "*fop_df_comm_sse"
14494 [(set (match_operand:DF 0 "register_operand" "=Y")
14495 (match_operator:DF 3 "binary_fp_operator"
14496 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14497 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14498 "TARGET_SSE2 && TARGET_SSE_MATH
14499 && COMMUTATIVE_ARITH_P (operands[3])
14500 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14501 "* return output_387_binary_op (insn, operands);"
14502 [(set (attr "type")
14503 (if_then_else (match_operand:SF 3 "mult_operator" "")
14504 (const_string "ssemul")
14505 (const_string "sseadd")))
14506 (set_attr "mode" "DF")])
14508 (define_insn "*fop_df_comm_i387"
14509 [(set (match_operand:DF 0 "register_operand" "=f")
14510 (match_operator:DF 3 "binary_fp_operator"
14511 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14512 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14514 && COMMUTATIVE_ARITH_P (operands[3])
14515 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14516 "* return output_387_binary_op (insn, operands);"
14517 [(set (attr "type")
14518 (if_then_else (match_operand:SF 3 "mult_operator" "")
14519 (const_string "fmul")
14520 (const_string "fop")))
14521 (set_attr "mode" "DF")])
14523 (define_insn "*fop_df_1_mixed"
14524 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14525 (match_operator:DF 3 "binary_fp_operator"
14526 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14527 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14528 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14529 && !COMMUTATIVE_ARITH_P (operands[3])
14530 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14531 "* return output_387_binary_op (insn, operands);"
14532 [(set (attr "type")
14533 (cond [(and (eq_attr "alternative" "2")
14534 (match_operand:SF 3 "mult_operator" ""))
14535 (const_string "ssemul")
14536 (and (eq_attr "alternative" "2")
14537 (match_operand:SF 3 "div_operator" ""))
14538 (const_string "ssediv")
14539 (eq_attr "alternative" "2")
14540 (const_string "sseadd")
14541 (match_operand:DF 3 "mult_operator" "")
14542 (const_string "fmul")
14543 (match_operand:DF 3 "div_operator" "")
14544 (const_string "fdiv")
14546 (const_string "fop")))
14547 (set_attr "mode" "DF")])
14549 (define_insn "*fop_df_1_sse"
14550 [(set (match_operand:DF 0 "register_operand" "=Y")
14551 (match_operator:DF 3 "binary_fp_operator"
14552 [(match_operand:DF 1 "register_operand" "0")
14553 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14554 "TARGET_SSE2 && TARGET_SSE_MATH
14555 && !COMMUTATIVE_ARITH_P (operands[3])"
14556 "* return output_387_binary_op (insn, operands);"
14557 [(set_attr "mode" "DF")
14559 (cond [(match_operand:SF 3 "mult_operator" "")
14560 (const_string "ssemul")
14561 (match_operand:SF 3 "div_operator" "")
14562 (const_string "ssediv")
14564 (const_string "sseadd")))])
14566 ;; This pattern is not fully shadowed by the pattern above.
14567 (define_insn "*fop_df_1_i387"
14568 [(set (match_operand:DF 0 "register_operand" "=f,f")
14569 (match_operator:DF 3 "binary_fp_operator"
14570 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14571 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14572 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14573 && !COMMUTATIVE_ARITH_P (operands[3])
14574 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14575 "* return output_387_binary_op (insn, operands);"
14576 [(set (attr "type")
14577 (cond [(match_operand:DF 3 "mult_operator" "")
14578 (const_string "fmul")
14579 (match_operand:DF 3 "div_operator" "")
14580 (const_string "fdiv")
14582 (const_string "fop")))
14583 (set_attr "mode" "DF")])
14585 ;; ??? Add SSE splitters for these!
14586 (define_insn "*fop_df_2<mode>_i387"
14587 [(set (match_operand:DF 0 "register_operand" "=f,f")
14588 (match_operator:DF 3 "binary_fp_operator"
14589 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14590 (match_operand:DF 2 "register_operand" "0,0")]))]
14591 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14592 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14593 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14594 [(set (attr "type")
14595 (cond [(match_operand:DF 3 "mult_operator" "")
14596 (const_string "fmul")
14597 (match_operand:DF 3 "div_operator" "")
14598 (const_string "fdiv")
14600 (const_string "fop")))
14601 (set_attr "fp_int_src" "true")
14602 (set_attr "mode" "<MODE>")])
14604 (define_insn "*fop_df_3<mode>_i387"
14605 [(set (match_operand:DF 0 "register_operand" "=f,f")
14606 (match_operator:DF 3 "binary_fp_operator"
14607 [(match_operand:DF 1 "register_operand" "0,0")
14608 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14609 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14610 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14611 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14612 [(set (attr "type")
14613 (cond [(match_operand:DF 3 "mult_operator" "")
14614 (const_string "fmul")
14615 (match_operand:DF 3 "div_operator" "")
14616 (const_string "fdiv")
14618 (const_string "fop")))
14619 (set_attr "fp_int_src" "true")
14620 (set_attr "mode" "<MODE>")])
14622 (define_insn "*fop_df_4_i387"
14623 [(set (match_operand:DF 0 "register_operand" "=f,f")
14624 (match_operator:DF 3 "binary_fp_operator"
14625 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14626 (match_operand:DF 2 "register_operand" "0,f")]))]
14627 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14628 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14629 "* return output_387_binary_op (insn, operands);"
14630 [(set (attr "type")
14631 (cond [(match_operand:DF 3 "mult_operator" "")
14632 (const_string "fmul")
14633 (match_operand:DF 3 "div_operator" "")
14634 (const_string "fdiv")
14636 (const_string "fop")))
14637 (set_attr "mode" "SF")])
14639 (define_insn "*fop_df_5_i387"
14640 [(set (match_operand:DF 0 "register_operand" "=f,f")
14641 (match_operator:DF 3 "binary_fp_operator"
14642 [(match_operand:DF 1 "register_operand" "0,f")
14644 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14645 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14646 "* return output_387_binary_op (insn, operands);"
14647 [(set (attr "type")
14648 (cond [(match_operand:DF 3 "mult_operator" "")
14649 (const_string "fmul")
14650 (match_operand:DF 3 "div_operator" "")
14651 (const_string "fdiv")
14653 (const_string "fop")))
14654 (set_attr "mode" "SF")])
14656 (define_insn "*fop_df_6_i387"
14657 [(set (match_operand:DF 0 "register_operand" "=f,f")
14658 (match_operator:DF 3 "binary_fp_operator"
14660 (match_operand:SF 1 "register_operand" "0,f"))
14662 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14663 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14664 "* return output_387_binary_op (insn, operands);"
14665 [(set (attr "type")
14666 (cond [(match_operand:DF 3 "mult_operator" "")
14667 (const_string "fmul")
14668 (match_operand:DF 3 "div_operator" "")
14669 (const_string "fdiv")
14671 (const_string "fop")))
14672 (set_attr "mode" "SF")])
14674 (define_insn "*fop_xf_comm_i387"
14675 [(set (match_operand:XF 0 "register_operand" "=f")
14676 (match_operator:XF 3 "binary_fp_operator"
14677 [(match_operand:XF 1 "register_operand" "%0")
14678 (match_operand:XF 2 "register_operand" "f")]))]
14680 && COMMUTATIVE_ARITH_P (operands[3])"
14681 "* return output_387_binary_op (insn, operands);"
14682 [(set (attr "type")
14683 (if_then_else (match_operand:XF 3 "mult_operator" "")
14684 (const_string "fmul")
14685 (const_string "fop")))
14686 (set_attr "mode" "XF")])
14688 (define_insn "*fop_xf_1_i387"
14689 [(set (match_operand:XF 0 "register_operand" "=f,f")
14690 (match_operator:XF 3 "binary_fp_operator"
14691 [(match_operand:XF 1 "register_operand" "0,f")
14692 (match_operand:XF 2 "register_operand" "f,0")]))]
14694 && !COMMUTATIVE_ARITH_P (operands[3])"
14695 "* return output_387_binary_op (insn, operands);"
14696 [(set (attr "type")
14697 (cond [(match_operand:XF 3 "mult_operator" "")
14698 (const_string "fmul")
14699 (match_operand:XF 3 "div_operator" "")
14700 (const_string "fdiv")
14702 (const_string "fop")))
14703 (set_attr "mode" "XF")])
14705 (define_insn "*fop_xf_2<mode>_i387"
14706 [(set (match_operand:XF 0 "register_operand" "=f,f")
14707 (match_operator:XF 3 "binary_fp_operator"
14708 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14709 (match_operand:XF 2 "register_operand" "0,0")]))]
14710 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14711 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14712 [(set (attr "type")
14713 (cond [(match_operand:XF 3 "mult_operator" "")
14714 (const_string "fmul")
14715 (match_operand:XF 3 "div_operator" "")
14716 (const_string "fdiv")
14718 (const_string "fop")))
14719 (set_attr "fp_int_src" "true")
14720 (set_attr "mode" "<MODE>")])
14722 (define_insn "*fop_xf_3<mode>_i387"
14723 [(set (match_operand:XF 0 "register_operand" "=f,f")
14724 (match_operator:XF 3 "binary_fp_operator"
14725 [(match_operand:XF 1 "register_operand" "0,0")
14726 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14727 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14728 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14729 [(set (attr "type")
14730 (cond [(match_operand:XF 3 "mult_operator" "")
14731 (const_string "fmul")
14732 (match_operand:XF 3 "div_operator" "")
14733 (const_string "fdiv")
14735 (const_string "fop")))
14736 (set_attr "fp_int_src" "true")
14737 (set_attr "mode" "<MODE>")])
14739 (define_insn "*fop_xf_4_i387"
14740 [(set (match_operand:XF 0 "register_operand" "=f,f")
14741 (match_operator:XF 3 "binary_fp_operator"
14742 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14743 (match_operand:XF 2 "register_operand" "0,f")]))]
14745 "* return output_387_binary_op (insn, operands);"
14746 [(set (attr "type")
14747 (cond [(match_operand:XF 3 "mult_operator" "")
14748 (const_string "fmul")
14749 (match_operand:XF 3 "div_operator" "")
14750 (const_string "fdiv")
14752 (const_string "fop")))
14753 (set_attr "mode" "SF")])
14755 (define_insn "*fop_xf_5_i387"
14756 [(set (match_operand:XF 0 "register_operand" "=f,f")
14757 (match_operator:XF 3 "binary_fp_operator"
14758 [(match_operand:XF 1 "register_operand" "0,f")
14760 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14762 "* return output_387_binary_op (insn, operands);"
14763 [(set (attr "type")
14764 (cond [(match_operand:XF 3 "mult_operator" "")
14765 (const_string "fmul")
14766 (match_operand:XF 3 "div_operator" "")
14767 (const_string "fdiv")
14769 (const_string "fop")))
14770 (set_attr "mode" "SF")])
14772 (define_insn "*fop_xf_6_i387"
14773 [(set (match_operand:XF 0 "register_operand" "=f,f")
14774 (match_operator:XF 3 "binary_fp_operator"
14776 (match_operand 1 "register_operand" "0,f"))
14778 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14780 "* return output_387_binary_op (insn, operands);"
14781 [(set (attr "type")
14782 (cond [(match_operand:XF 3 "mult_operator" "")
14783 (const_string "fmul")
14784 (match_operand:XF 3 "div_operator" "")
14785 (const_string "fdiv")
14787 (const_string "fop")))
14788 (set_attr "mode" "SF")])
14791 [(set (match_operand 0 "register_operand" "")
14792 (match_operator 3 "binary_fp_operator"
14793 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14794 (match_operand 2 "register_operand" "")]))]
14795 "TARGET_80387 && reload_completed
14796 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14799 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14800 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14801 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14802 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14803 GET_MODE (operands[3]),
14806 ix86_free_from_memory (GET_MODE (operands[1]));
14811 [(set (match_operand 0 "register_operand" "")
14812 (match_operator 3 "binary_fp_operator"
14813 [(match_operand 1 "register_operand" "")
14814 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14815 "TARGET_80387 && reload_completed
14816 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14819 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14820 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14821 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14822 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14823 GET_MODE (operands[3]),
14826 ix86_free_from_memory (GET_MODE (operands[2]));
14830 ;; FPU special functions.
14832 (define_expand "sqrtsf2"
14833 [(set (match_operand:SF 0 "register_operand" "")
14834 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14835 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14837 if (!TARGET_SSE_MATH)
14838 operands[1] = force_reg (SFmode, operands[1]);
14841 (define_insn "*sqrtsf2_mixed"
14842 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14843 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14844 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14847 sqrtss\t{%1, %0|%0, %1}"
14848 [(set_attr "type" "fpspc,sse")
14849 (set_attr "mode" "SF,SF")
14850 (set_attr "athlon_decode" "direct,*")])
14852 (define_insn "*sqrtsf2_sse"
14853 [(set (match_operand:SF 0 "register_operand" "=x")
14854 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14856 "sqrtss\t{%1, %0|%0, %1}"
14857 [(set_attr "type" "sse")
14858 (set_attr "mode" "SF")
14859 (set_attr "athlon_decode" "*")])
14861 (define_insn "*sqrtsf2_i387"
14862 [(set (match_operand:SF 0 "register_operand" "=f")
14863 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14864 "TARGET_USE_FANCY_MATH_387"
14866 [(set_attr "type" "fpspc")
14867 (set_attr "mode" "SF")
14868 (set_attr "athlon_decode" "direct")])
14870 (define_expand "sqrtdf2"
14871 [(set (match_operand:DF 0 "register_operand" "")
14872 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14873 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14875 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14876 operands[1] = force_reg (DFmode, operands[1]);
14879 (define_insn "*sqrtdf2_mixed"
14880 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14881 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14882 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14885 sqrtsd\t{%1, %0|%0, %1}"
14886 [(set_attr "type" "fpspc,sse")
14887 (set_attr "mode" "DF,DF")
14888 (set_attr "athlon_decode" "direct,*")])
14890 (define_insn "*sqrtdf2_sse"
14891 [(set (match_operand:DF 0 "register_operand" "=Y")
14892 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14893 "TARGET_SSE2 && TARGET_SSE_MATH"
14894 "sqrtsd\t{%1, %0|%0, %1}"
14895 [(set_attr "type" "sse")
14896 (set_attr "mode" "DF")
14897 (set_attr "athlon_decode" "*")])
14899 (define_insn "*sqrtdf2_i387"
14900 [(set (match_operand:DF 0 "register_operand" "=f")
14901 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14902 "TARGET_USE_FANCY_MATH_387"
14904 [(set_attr "type" "fpspc")
14905 (set_attr "mode" "DF")
14906 (set_attr "athlon_decode" "direct")])
14908 (define_insn "*sqrtextendsfdf2_i387"
14909 [(set (match_operand:DF 0 "register_operand" "=f")
14910 (sqrt:DF (float_extend:DF
14911 (match_operand:SF 1 "register_operand" "0"))))]
14912 "TARGET_USE_FANCY_MATH_387
14913 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14915 [(set_attr "type" "fpspc")
14916 (set_attr "mode" "DF")
14917 (set_attr "athlon_decode" "direct")])
14919 (define_insn "sqrtxf2"
14920 [(set (match_operand:XF 0 "register_operand" "=f")
14921 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14922 "TARGET_USE_FANCY_MATH_387
14923 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14925 [(set_attr "type" "fpspc")
14926 (set_attr "mode" "XF")
14927 (set_attr "athlon_decode" "direct")])
14929 (define_insn "*sqrtextendsfxf2_i387"
14930 [(set (match_operand:XF 0 "register_operand" "=f")
14931 (sqrt:XF (float_extend:XF
14932 (match_operand:SF 1 "register_operand" "0"))))]
14933 "TARGET_USE_FANCY_MATH_387"
14935 [(set_attr "type" "fpspc")
14936 (set_attr "mode" "XF")
14937 (set_attr "athlon_decode" "direct")])
14939 (define_insn "*sqrtextenddfxf2_i387"
14940 [(set (match_operand:XF 0 "register_operand" "=f")
14941 (sqrt:XF (float_extend:XF
14942 (match_operand:DF 1 "register_operand" "0"))))]
14943 "TARGET_USE_FANCY_MATH_387"
14945 [(set_attr "type" "fpspc")
14946 (set_attr "mode" "XF")
14947 (set_attr "athlon_decode" "direct")])
14949 (define_insn "fpremxf4"
14950 [(set (match_operand:XF 0 "register_operand" "=f")
14951 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14952 (match_operand:XF 3 "register_operand" "1")]
14954 (set (match_operand:XF 1 "register_operand" "=u")
14955 (unspec:XF [(match_dup 2) (match_dup 3)]
14957 (set (reg:CCFP FPSR_REG)
14958 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14959 "TARGET_USE_FANCY_MATH_387
14960 && flag_unsafe_math_optimizations"
14962 [(set_attr "type" "fpspc")
14963 (set_attr "mode" "XF")])
14965 (define_expand "fmodsf3"
14966 [(use (match_operand:SF 0 "register_operand" ""))
14967 (use (match_operand:SF 1 "register_operand" ""))
14968 (use (match_operand:SF 2 "register_operand" ""))]
14969 "TARGET_USE_FANCY_MATH_387
14970 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14971 && flag_unsafe_math_optimizations"
14973 rtx label = gen_label_rtx ();
14975 rtx op1 = gen_reg_rtx (XFmode);
14976 rtx op2 = gen_reg_rtx (XFmode);
14978 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14979 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14981 emit_label (label);
14983 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14984 ix86_emit_fp_unordered_jump (label);
14986 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14990 (define_expand "fmoddf3"
14991 [(use (match_operand:DF 0 "register_operand" ""))
14992 (use (match_operand:DF 1 "register_operand" ""))
14993 (use (match_operand:DF 2 "register_operand" ""))]
14994 "TARGET_USE_FANCY_MATH_387
14995 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14996 && flag_unsafe_math_optimizations"
14998 rtx label = gen_label_rtx ();
15000 rtx op1 = gen_reg_rtx (XFmode);
15001 rtx op2 = gen_reg_rtx (XFmode);
15003 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15004 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15006 emit_label (label);
15008 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15009 ix86_emit_fp_unordered_jump (label);
15011 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15015 (define_expand "fmodxf3"
15016 [(use (match_operand:XF 0 "register_operand" ""))
15017 (use (match_operand:XF 1 "register_operand" ""))
15018 (use (match_operand:XF 2 "register_operand" ""))]
15019 "TARGET_USE_FANCY_MATH_387
15020 && flag_unsafe_math_optimizations"
15022 rtx label = gen_label_rtx ();
15024 emit_label (label);
15026 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15027 operands[1], operands[2]));
15028 ix86_emit_fp_unordered_jump (label);
15030 emit_move_insn (operands[0], operands[1]);
15034 (define_insn "fprem1xf4"
15035 [(set (match_operand:XF 0 "register_operand" "=f")
15036 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15037 (match_operand:XF 3 "register_operand" "1")]
15039 (set (match_operand:XF 1 "register_operand" "=u")
15040 (unspec:XF [(match_dup 2) (match_dup 3)]
15042 (set (reg:CCFP FPSR_REG)
15043 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15044 "TARGET_USE_FANCY_MATH_387
15045 && flag_unsafe_math_optimizations"
15047 [(set_attr "type" "fpspc")
15048 (set_attr "mode" "XF")])
15050 (define_expand "dremsf3"
15051 [(use (match_operand:SF 0 "register_operand" ""))
15052 (use (match_operand:SF 1 "register_operand" ""))
15053 (use (match_operand:SF 2 "register_operand" ""))]
15054 "TARGET_USE_FANCY_MATH_387
15055 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15056 && flag_unsafe_math_optimizations"
15058 rtx label = gen_label_rtx ();
15060 rtx op1 = gen_reg_rtx (XFmode);
15061 rtx op2 = gen_reg_rtx (XFmode);
15063 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15064 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15066 emit_label (label);
15068 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15069 ix86_emit_fp_unordered_jump (label);
15071 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15075 (define_expand "dremdf3"
15076 [(use (match_operand:DF 0 "register_operand" ""))
15077 (use (match_operand:DF 1 "register_operand" ""))
15078 (use (match_operand:DF 2 "register_operand" ""))]
15079 "TARGET_USE_FANCY_MATH_387
15080 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15081 && flag_unsafe_math_optimizations"
15083 rtx label = gen_label_rtx ();
15085 rtx op1 = gen_reg_rtx (XFmode);
15086 rtx op2 = gen_reg_rtx (XFmode);
15088 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15089 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15091 emit_label (label);
15093 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15094 ix86_emit_fp_unordered_jump (label);
15096 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15100 (define_expand "dremxf3"
15101 [(use (match_operand:XF 0 "register_operand" ""))
15102 (use (match_operand:XF 1 "register_operand" ""))
15103 (use (match_operand:XF 2 "register_operand" ""))]
15104 "TARGET_USE_FANCY_MATH_387
15105 && flag_unsafe_math_optimizations"
15107 rtx label = gen_label_rtx ();
15109 emit_label (label);
15111 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15112 operands[1], operands[2]));
15113 ix86_emit_fp_unordered_jump (label);
15115 emit_move_insn (operands[0], operands[1]);
15119 (define_insn "*sindf2"
15120 [(set (match_operand:DF 0 "register_operand" "=f")
15121 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15122 "TARGET_USE_FANCY_MATH_387
15123 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15124 && flag_unsafe_math_optimizations"
15126 [(set_attr "type" "fpspc")
15127 (set_attr "mode" "DF")])
15129 (define_insn "*sinsf2"
15130 [(set (match_operand:SF 0 "register_operand" "=f")
15131 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15132 "TARGET_USE_FANCY_MATH_387
15133 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15134 && flag_unsafe_math_optimizations"
15136 [(set_attr "type" "fpspc")
15137 (set_attr "mode" "SF")])
15139 (define_insn "*sinextendsfdf2"
15140 [(set (match_operand:DF 0 "register_operand" "=f")
15141 (unspec:DF [(float_extend:DF
15142 (match_operand:SF 1 "register_operand" "0"))]
15144 "TARGET_USE_FANCY_MATH_387
15145 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15146 && flag_unsafe_math_optimizations"
15148 [(set_attr "type" "fpspc")
15149 (set_attr "mode" "DF")])
15151 (define_insn "*sinxf2"
15152 [(set (match_operand:XF 0 "register_operand" "=f")
15153 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15154 "TARGET_USE_FANCY_MATH_387
15155 && flag_unsafe_math_optimizations"
15157 [(set_attr "type" "fpspc")
15158 (set_attr "mode" "XF")])
15160 (define_insn "*cosdf2"
15161 [(set (match_operand:DF 0 "register_operand" "=f")
15162 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15163 "TARGET_USE_FANCY_MATH_387
15164 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15165 && flag_unsafe_math_optimizations"
15167 [(set_attr "type" "fpspc")
15168 (set_attr "mode" "DF")])
15170 (define_insn "*cossf2"
15171 [(set (match_operand:SF 0 "register_operand" "=f")
15172 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15173 "TARGET_USE_FANCY_MATH_387
15174 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15175 && flag_unsafe_math_optimizations"
15177 [(set_attr "type" "fpspc")
15178 (set_attr "mode" "SF")])
15180 (define_insn "*cosextendsfdf2"
15181 [(set (match_operand:DF 0 "register_operand" "=f")
15182 (unspec:DF [(float_extend:DF
15183 (match_operand:SF 1 "register_operand" "0"))]
15185 "TARGET_USE_FANCY_MATH_387
15186 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15187 && flag_unsafe_math_optimizations"
15189 [(set_attr "type" "fpspc")
15190 (set_attr "mode" "DF")])
15192 (define_insn "*cosxf2"
15193 [(set (match_operand:XF 0 "register_operand" "=f")
15194 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15195 "TARGET_USE_FANCY_MATH_387
15196 && flag_unsafe_math_optimizations"
15198 [(set_attr "type" "fpspc")
15199 (set_attr "mode" "XF")])
15201 ;; With sincos pattern defined, sin and cos builtin function will be
15202 ;; expanded to sincos pattern with one of its outputs left unused.
15203 ;; Cse pass will detected, if two sincos patterns can be combined,
15204 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15205 ;; depending on the unused output.
15207 (define_insn "sincosdf3"
15208 [(set (match_operand:DF 0 "register_operand" "=f")
15209 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15210 UNSPEC_SINCOS_COS))
15211 (set (match_operand:DF 1 "register_operand" "=u")
15212 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15213 "TARGET_USE_FANCY_MATH_387
15214 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15215 && flag_unsafe_math_optimizations"
15217 [(set_attr "type" "fpspc")
15218 (set_attr "mode" "DF")])
15221 [(set (match_operand:DF 0 "register_operand" "")
15222 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15223 UNSPEC_SINCOS_COS))
15224 (set (match_operand:DF 1 "register_operand" "")
15225 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15226 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15227 && !reload_completed && !reload_in_progress"
15228 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15232 [(set (match_operand:DF 0 "register_operand" "")
15233 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15234 UNSPEC_SINCOS_COS))
15235 (set (match_operand:DF 1 "register_operand" "")
15236 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15237 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15238 && !reload_completed && !reload_in_progress"
15239 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15242 (define_insn "sincossf3"
15243 [(set (match_operand:SF 0 "register_operand" "=f")
15244 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15245 UNSPEC_SINCOS_COS))
15246 (set (match_operand:SF 1 "register_operand" "=u")
15247 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15248 "TARGET_USE_FANCY_MATH_387
15249 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15250 && flag_unsafe_math_optimizations"
15252 [(set_attr "type" "fpspc")
15253 (set_attr "mode" "SF")])
15256 [(set (match_operand:SF 0 "register_operand" "")
15257 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15258 UNSPEC_SINCOS_COS))
15259 (set (match_operand:SF 1 "register_operand" "")
15260 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15261 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15262 && !reload_completed && !reload_in_progress"
15263 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15267 [(set (match_operand:SF 0 "register_operand" "")
15268 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15269 UNSPEC_SINCOS_COS))
15270 (set (match_operand:SF 1 "register_operand" "")
15271 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15272 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15273 && !reload_completed && !reload_in_progress"
15274 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15277 (define_insn "*sincosextendsfdf3"
15278 [(set (match_operand:DF 0 "register_operand" "=f")
15279 (unspec:DF [(float_extend:DF
15280 (match_operand:SF 2 "register_operand" "0"))]
15281 UNSPEC_SINCOS_COS))
15282 (set (match_operand:DF 1 "register_operand" "=u")
15283 (unspec:DF [(float_extend:DF
15284 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15285 "TARGET_USE_FANCY_MATH_387
15286 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15287 && flag_unsafe_math_optimizations"
15289 [(set_attr "type" "fpspc")
15290 (set_attr "mode" "DF")])
15293 [(set (match_operand:DF 0 "register_operand" "")
15294 (unspec:DF [(float_extend:DF
15295 (match_operand:SF 2 "register_operand" ""))]
15296 UNSPEC_SINCOS_COS))
15297 (set (match_operand:DF 1 "register_operand" "")
15298 (unspec:DF [(float_extend:DF
15299 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15300 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15301 && !reload_completed && !reload_in_progress"
15302 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15303 (match_dup 2))] UNSPEC_SIN))]
15307 [(set (match_operand:DF 0 "register_operand" "")
15308 (unspec:DF [(float_extend:DF
15309 (match_operand:SF 2 "register_operand" ""))]
15310 UNSPEC_SINCOS_COS))
15311 (set (match_operand:DF 1 "register_operand" "")
15312 (unspec:DF [(float_extend:DF
15313 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15314 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15315 && !reload_completed && !reload_in_progress"
15316 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15317 (match_dup 2))] UNSPEC_COS))]
15320 (define_insn "sincosxf3"
15321 [(set (match_operand:XF 0 "register_operand" "=f")
15322 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15323 UNSPEC_SINCOS_COS))
15324 (set (match_operand:XF 1 "register_operand" "=u")
15325 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15326 "TARGET_USE_FANCY_MATH_387
15327 && flag_unsafe_math_optimizations"
15329 [(set_attr "type" "fpspc")
15330 (set_attr "mode" "XF")])
15333 [(set (match_operand:XF 0 "register_operand" "")
15334 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15335 UNSPEC_SINCOS_COS))
15336 (set (match_operand:XF 1 "register_operand" "")
15337 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15338 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15339 && !reload_completed && !reload_in_progress"
15340 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15344 [(set (match_operand:XF 0 "register_operand" "")
15345 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15346 UNSPEC_SINCOS_COS))
15347 (set (match_operand:XF 1 "register_operand" "")
15348 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15349 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15350 && !reload_completed && !reload_in_progress"
15351 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15354 (define_insn "*tandf3_1"
15355 [(set (match_operand:DF 0 "register_operand" "=f")
15356 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15358 (set (match_operand:DF 1 "register_operand" "=u")
15359 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15360 "TARGET_USE_FANCY_MATH_387
15361 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15362 && flag_unsafe_math_optimizations"
15364 [(set_attr "type" "fpspc")
15365 (set_attr "mode" "DF")])
15367 ;; optimize sequence: fptan
15370 ;; into fptan insn.
15373 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15374 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15376 (set (match_operand:DF 1 "register_operand" "")
15377 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15379 (match_operand:DF 3 "immediate_operand" ""))]
15380 "standard_80387_constant_p (operands[3]) == 2"
15381 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15382 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15385 (define_expand "tandf2"
15386 [(parallel [(set (match_dup 2)
15387 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15389 (set (match_operand:DF 0 "register_operand" "")
15390 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15391 "TARGET_USE_FANCY_MATH_387
15392 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15393 && flag_unsafe_math_optimizations"
15395 operands[2] = gen_reg_rtx (DFmode);
15398 (define_insn "*tansf3_1"
15399 [(set (match_operand:SF 0 "register_operand" "=f")
15400 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15402 (set (match_operand:SF 1 "register_operand" "=u")
15403 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15404 "TARGET_USE_FANCY_MATH_387
15405 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15406 && flag_unsafe_math_optimizations"
15408 [(set_attr "type" "fpspc")
15409 (set_attr "mode" "SF")])
15411 ;; optimize sequence: fptan
15414 ;; into fptan insn.
15417 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15418 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15420 (set (match_operand:SF 1 "register_operand" "")
15421 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15423 (match_operand:SF 3 "immediate_operand" ""))]
15424 "standard_80387_constant_p (operands[3]) == 2"
15425 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15426 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15429 (define_expand "tansf2"
15430 [(parallel [(set (match_dup 2)
15431 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15433 (set (match_operand:SF 0 "register_operand" "")
15434 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15435 "TARGET_USE_FANCY_MATH_387
15436 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15437 && flag_unsafe_math_optimizations"
15439 operands[2] = gen_reg_rtx (SFmode);
15442 (define_insn "*tanxf3_1"
15443 [(set (match_operand:XF 0 "register_operand" "=f")
15444 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15446 (set (match_operand:XF 1 "register_operand" "=u")
15447 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15448 "TARGET_USE_FANCY_MATH_387
15449 && flag_unsafe_math_optimizations"
15451 [(set_attr "type" "fpspc")
15452 (set_attr "mode" "XF")])
15454 ;; optimize sequence: fptan
15457 ;; into fptan insn.
15460 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15461 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15463 (set (match_operand:XF 1 "register_operand" "")
15464 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15466 (match_operand:XF 3 "immediate_operand" ""))]
15467 "standard_80387_constant_p (operands[3]) == 2"
15468 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15469 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15472 (define_expand "tanxf2"
15473 [(parallel [(set (match_dup 2)
15474 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15476 (set (match_operand:XF 0 "register_operand" "")
15477 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15478 "TARGET_USE_FANCY_MATH_387
15479 && flag_unsafe_math_optimizations"
15481 operands[2] = gen_reg_rtx (XFmode);
15484 (define_insn "atan2df3_1"
15485 [(set (match_operand:DF 0 "register_operand" "=f")
15486 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15487 (match_operand:DF 1 "register_operand" "u")]
15489 (clobber (match_scratch:DF 3 "=1"))]
15490 "TARGET_USE_FANCY_MATH_387
15491 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15492 && flag_unsafe_math_optimizations"
15494 [(set_attr "type" "fpspc")
15495 (set_attr "mode" "DF")])
15497 (define_expand "atan2df3"
15498 [(use (match_operand:DF 0 "register_operand" ""))
15499 (use (match_operand:DF 2 "register_operand" ""))
15500 (use (match_operand:DF 1 "register_operand" ""))]
15501 "TARGET_USE_FANCY_MATH_387
15502 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15503 && flag_unsafe_math_optimizations"
15505 rtx copy = gen_reg_rtx (DFmode);
15506 emit_move_insn (copy, operands[1]);
15507 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15511 (define_expand "atandf2"
15512 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15513 (unspec:DF [(match_dup 2)
15514 (match_operand:DF 1 "register_operand" "")]
15516 (clobber (match_scratch:DF 3 ""))])]
15517 "TARGET_USE_FANCY_MATH_387
15518 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15519 && flag_unsafe_math_optimizations"
15521 operands[2] = gen_reg_rtx (DFmode);
15522 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15525 (define_insn "atan2sf3_1"
15526 [(set (match_operand:SF 0 "register_operand" "=f")
15527 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15528 (match_operand:SF 1 "register_operand" "u")]
15530 (clobber (match_scratch:SF 3 "=1"))]
15531 "TARGET_USE_FANCY_MATH_387
15532 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15533 && flag_unsafe_math_optimizations"
15535 [(set_attr "type" "fpspc")
15536 (set_attr "mode" "SF")])
15538 (define_expand "atan2sf3"
15539 [(use (match_operand:SF 0 "register_operand" ""))
15540 (use (match_operand:SF 2 "register_operand" ""))
15541 (use (match_operand:SF 1 "register_operand" ""))]
15542 "TARGET_USE_FANCY_MATH_387
15543 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15544 && flag_unsafe_math_optimizations"
15546 rtx copy = gen_reg_rtx (SFmode);
15547 emit_move_insn (copy, operands[1]);
15548 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15552 (define_expand "atansf2"
15553 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15554 (unspec:SF [(match_dup 2)
15555 (match_operand:SF 1 "register_operand" "")]
15557 (clobber (match_scratch:SF 3 ""))])]
15558 "TARGET_USE_FANCY_MATH_387
15559 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15560 && flag_unsafe_math_optimizations"
15562 operands[2] = gen_reg_rtx (SFmode);
15563 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15566 (define_insn "atan2xf3_1"
15567 [(set (match_operand:XF 0 "register_operand" "=f")
15568 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15569 (match_operand:XF 1 "register_operand" "u")]
15571 (clobber (match_scratch:XF 3 "=1"))]
15572 "TARGET_USE_FANCY_MATH_387
15573 && flag_unsafe_math_optimizations"
15575 [(set_attr "type" "fpspc")
15576 (set_attr "mode" "XF")])
15578 (define_expand "atan2xf3"
15579 [(use (match_operand:XF 0 "register_operand" ""))
15580 (use (match_operand:XF 2 "register_operand" ""))
15581 (use (match_operand:XF 1 "register_operand" ""))]
15582 "TARGET_USE_FANCY_MATH_387
15583 && flag_unsafe_math_optimizations"
15585 rtx copy = gen_reg_rtx (XFmode);
15586 emit_move_insn (copy, operands[1]);
15587 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15591 (define_expand "atanxf2"
15592 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15593 (unspec:XF [(match_dup 2)
15594 (match_operand:XF 1 "register_operand" "")]
15596 (clobber (match_scratch:XF 3 ""))])]
15597 "TARGET_USE_FANCY_MATH_387
15598 && flag_unsafe_math_optimizations"
15600 operands[2] = gen_reg_rtx (XFmode);
15601 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15604 (define_expand "asindf2"
15605 [(set (match_dup 2)
15606 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15607 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15608 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15609 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15610 (parallel [(set (match_dup 7)
15611 (unspec:XF [(match_dup 6) (match_dup 2)]
15613 (clobber (match_scratch:XF 8 ""))])
15614 (set (match_operand:DF 0 "register_operand" "")
15615 (float_truncate:DF (match_dup 7)))]
15616 "TARGET_USE_FANCY_MATH_387
15617 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15618 && flag_unsafe_math_optimizations"
15622 for (i=2; i<8; i++)
15623 operands[i] = gen_reg_rtx (XFmode);
15625 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15628 (define_expand "asinsf2"
15629 [(set (match_dup 2)
15630 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15631 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15632 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15633 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15634 (parallel [(set (match_dup 7)
15635 (unspec:XF [(match_dup 6) (match_dup 2)]
15637 (clobber (match_scratch:XF 8 ""))])
15638 (set (match_operand:SF 0 "register_operand" "")
15639 (float_truncate:SF (match_dup 7)))]
15640 "TARGET_USE_FANCY_MATH_387
15641 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15642 && flag_unsafe_math_optimizations"
15646 for (i=2; i<8; i++)
15647 operands[i] = gen_reg_rtx (XFmode);
15649 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15652 (define_expand "asinxf2"
15653 [(set (match_dup 2)
15654 (mult:XF (match_operand:XF 1 "register_operand" "")
15656 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15657 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15658 (parallel [(set (match_operand:XF 0 "register_operand" "")
15659 (unspec:XF [(match_dup 5) (match_dup 1)]
15661 (clobber (match_scratch:XF 6 ""))])]
15662 "TARGET_USE_FANCY_MATH_387
15663 && flag_unsafe_math_optimizations"
15667 for (i=2; i<6; i++)
15668 operands[i] = gen_reg_rtx (XFmode);
15670 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15673 (define_expand "acosdf2"
15674 [(set (match_dup 2)
15675 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15676 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15677 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15678 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15679 (parallel [(set (match_dup 7)
15680 (unspec:XF [(match_dup 2) (match_dup 6)]
15682 (clobber (match_scratch:XF 8 ""))])
15683 (set (match_operand:DF 0 "register_operand" "")
15684 (float_truncate:DF (match_dup 7)))]
15685 "TARGET_USE_FANCY_MATH_387
15686 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15687 && flag_unsafe_math_optimizations"
15691 for (i=2; i<8; i++)
15692 operands[i] = gen_reg_rtx (XFmode);
15694 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15697 (define_expand "acossf2"
15698 [(set (match_dup 2)
15699 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15700 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15701 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15702 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15703 (parallel [(set (match_dup 7)
15704 (unspec:XF [(match_dup 2) (match_dup 6)]
15706 (clobber (match_scratch:XF 8 ""))])
15707 (set (match_operand:SF 0 "register_operand" "")
15708 (float_truncate:SF (match_dup 7)))]
15709 "TARGET_USE_FANCY_MATH_387
15710 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15711 && flag_unsafe_math_optimizations"
15715 for (i=2; i<8; i++)
15716 operands[i] = gen_reg_rtx (XFmode);
15718 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15721 (define_expand "acosxf2"
15722 [(set (match_dup 2)
15723 (mult:XF (match_operand:XF 1 "register_operand" "")
15725 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15726 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15727 (parallel [(set (match_operand:XF 0 "register_operand" "")
15728 (unspec:XF [(match_dup 1) (match_dup 5)]
15730 (clobber (match_scratch:XF 6 ""))])]
15731 "TARGET_USE_FANCY_MATH_387
15732 && flag_unsafe_math_optimizations"
15736 for (i=2; i<6; i++)
15737 operands[i] = gen_reg_rtx (XFmode);
15739 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15742 (define_insn "fyl2x_xf3"
15743 [(set (match_operand:XF 0 "register_operand" "=f")
15744 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15745 (match_operand:XF 1 "register_operand" "u")]
15747 (clobber (match_scratch:XF 3 "=1"))]
15748 "TARGET_USE_FANCY_MATH_387
15749 && flag_unsafe_math_optimizations"
15751 [(set_attr "type" "fpspc")
15752 (set_attr "mode" "XF")])
15754 (define_expand "logsf2"
15755 [(set (match_dup 2)
15756 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15757 (parallel [(set (match_dup 4)
15758 (unspec:XF [(match_dup 2)
15759 (match_dup 3)] UNSPEC_FYL2X))
15760 (clobber (match_scratch:XF 5 ""))])
15761 (set (match_operand:SF 0 "register_operand" "")
15762 (float_truncate:SF (match_dup 4)))]
15763 "TARGET_USE_FANCY_MATH_387
15764 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15765 && flag_unsafe_math_optimizations"
15769 operands[2] = gen_reg_rtx (XFmode);
15770 operands[3] = gen_reg_rtx (XFmode);
15771 operands[4] = gen_reg_rtx (XFmode);
15773 temp = standard_80387_constant_rtx (4); /* fldln2 */
15774 emit_move_insn (operands[3], temp);
15777 (define_expand "logdf2"
15778 [(set (match_dup 2)
15779 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15780 (parallel [(set (match_dup 4)
15781 (unspec:XF [(match_dup 2)
15782 (match_dup 3)] UNSPEC_FYL2X))
15783 (clobber (match_scratch:XF 5 ""))])
15784 (set (match_operand:DF 0 "register_operand" "")
15785 (float_truncate:DF (match_dup 4)))]
15786 "TARGET_USE_FANCY_MATH_387
15787 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15788 && flag_unsafe_math_optimizations"
15792 operands[2] = gen_reg_rtx (XFmode);
15793 operands[3] = gen_reg_rtx (XFmode);
15794 operands[4] = gen_reg_rtx (XFmode);
15796 temp = standard_80387_constant_rtx (4); /* fldln2 */
15797 emit_move_insn (operands[3], temp);
15800 (define_expand "logxf2"
15801 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15802 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15803 (match_dup 2)] UNSPEC_FYL2X))
15804 (clobber (match_scratch:XF 3 ""))])]
15805 "TARGET_USE_FANCY_MATH_387
15806 && flag_unsafe_math_optimizations"
15810 operands[2] = gen_reg_rtx (XFmode);
15811 temp = standard_80387_constant_rtx (4); /* fldln2 */
15812 emit_move_insn (operands[2], temp);
15815 (define_expand "log10sf2"
15816 [(set (match_dup 2)
15817 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15818 (parallel [(set (match_dup 4)
15819 (unspec:XF [(match_dup 2)
15820 (match_dup 3)] UNSPEC_FYL2X))
15821 (clobber (match_scratch:XF 5 ""))])
15822 (set (match_operand:SF 0 "register_operand" "")
15823 (float_truncate:SF (match_dup 4)))]
15824 "TARGET_USE_FANCY_MATH_387
15825 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15826 && flag_unsafe_math_optimizations"
15830 operands[2] = gen_reg_rtx (XFmode);
15831 operands[3] = gen_reg_rtx (XFmode);
15832 operands[4] = gen_reg_rtx (XFmode);
15834 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15835 emit_move_insn (operands[3], temp);
15838 (define_expand "log10df2"
15839 [(set (match_dup 2)
15840 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15841 (parallel [(set (match_dup 4)
15842 (unspec:XF [(match_dup 2)
15843 (match_dup 3)] UNSPEC_FYL2X))
15844 (clobber (match_scratch:XF 5 ""))])
15845 (set (match_operand:DF 0 "register_operand" "")
15846 (float_truncate:DF (match_dup 4)))]
15847 "TARGET_USE_FANCY_MATH_387
15848 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15849 && flag_unsafe_math_optimizations"
15853 operands[2] = gen_reg_rtx (XFmode);
15854 operands[3] = gen_reg_rtx (XFmode);
15855 operands[4] = gen_reg_rtx (XFmode);
15857 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15858 emit_move_insn (operands[3], temp);
15861 (define_expand "log10xf2"
15862 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15863 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15864 (match_dup 2)] UNSPEC_FYL2X))
15865 (clobber (match_scratch:XF 3 ""))])]
15866 "TARGET_USE_FANCY_MATH_387
15867 && flag_unsafe_math_optimizations"
15871 operands[2] = gen_reg_rtx (XFmode);
15872 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15873 emit_move_insn (operands[2], temp);
15876 (define_expand "log2sf2"
15877 [(set (match_dup 2)
15878 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15879 (parallel [(set (match_dup 4)
15880 (unspec:XF [(match_dup 2)
15881 (match_dup 3)] UNSPEC_FYL2X))
15882 (clobber (match_scratch:XF 5 ""))])
15883 (set (match_operand:SF 0 "register_operand" "")
15884 (float_truncate:SF (match_dup 4)))]
15885 "TARGET_USE_FANCY_MATH_387
15886 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15887 && flag_unsafe_math_optimizations"
15889 operands[2] = gen_reg_rtx (XFmode);
15890 operands[3] = gen_reg_rtx (XFmode);
15891 operands[4] = gen_reg_rtx (XFmode);
15893 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15896 (define_expand "log2df2"
15897 [(set (match_dup 2)
15898 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15899 (parallel [(set (match_dup 4)
15900 (unspec:XF [(match_dup 2)
15901 (match_dup 3)] UNSPEC_FYL2X))
15902 (clobber (match_scratch:XF 5 ""))])
15903 (set (match_operand:DF 0 "register_operand" "")
15904 (float_truncate:DF (match_dup 4)))]
15905 "TARGET_USE_FANCY_MATH_387
15906 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15907 && flag_unsafe_math_optimizations"
15909 operands[2] = gen_reg_rtx (XFmode);
15910 operands[3] = gen_reg_rtx (XFmode);
15911 operands[4] = gen_reg_rtx (XFmode);
15913 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15916 (define_expand "log2xf2"
15917 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15918 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15919 (match_dup 2)] UNSPEC_FYL2X))
15920 (clobber (match_scratch:XF 3 ""))])]
15921 "TARGET_USE_FANCY_MATH_387
15922 && flag_unsafe_math_optimizations"
15924 operands[2] = gen_reg_rtx (XFmode);
15925 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15928 (define_insn "fyl2xp1_xf3"
15929 [(set (match_operand:XF 0 "register_operand" "=f")
15930 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15931 (match_operand:XF 1 "register_operand" "u")]
15933 (clobber (match_scratch:XF 3 "=1"))]
15934 "TARGET_USE_FANCY_MATH_387
15935 && flag_unsafe_math_optimizations"
15937 [(set_attr "type" "fpspc")
15938 (set_attr "mode" "XF")])
15940 (define_expand "log1psf2"
15941 [(use (match_operand:SF 0 "register_operand" ""))
15942 (use (match_operand:SF 1 "register_operand" ""))]
15943 "TARGET_USE_FANCY_MATH_387
15944 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15945 && flag_unsafe_math_optimizations"
15947 rtx op0 = gen_reg_rtx (XFmode);
15948 rtx op1 = gen_reg_rtx (XFmode);
15950 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15951 ix86_emit_i387_log1p (op0, op1);
15952 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15956 (define_expand "log1pdf2"
15957 [(use (match_operand:DF 0 "register_operand" ""))
15958 (use (match_operand:DF 1 "register_operand" ""))]
15959 "TARGET_USE_FANCY_MATH_387
15960 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15961 && flag_unsafe_math_optimizations"
15963 rtx op0 = gen_reg_rtx (XFmode);
15964 rtx op1 = gen_reg_rtx (XFmode);
15966 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15967 ix86_emit_i387_log1p (op0, op1);
15968 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15972 (define_expand "log1pxf2"
15973 [(use (match_operand:XF 0 "register_operand" ""))
15974 (use (match_operand:XF 1 "register_operand" ""))]
15975 "TARGET_USE_FANCY_MATH_387
15976 && flag_unsafe_math_optimizations"
15978 ix86_emit_i387_log1p (operands[0], operands[1]);
15982 (define_insn "*fxtractxf3"
15983 [(set (match_operand:XF 0 "register_operand" "=f")
15984 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15985 UNSPEC_XTRACT_FRACT))
15986 (set (match_operand:XF 1 "register_operand" "=u")
15987 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15988 "TARGET_USE_FANCY_MATH_387
15989 && flag_unsafe_math_optimizations"
15991 [(set_attr "type" "fpspc")
15992 (set_attr "mode" "XF")])
15994 (define_expand "logbsf2"
15995 [(set (match_dup 2)
15996 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15997 (parallel [(set (match_dup 3)
15998 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16000 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16001 (set (match_operand:SF 0 "register_operand" "")
16002 (float_truncate:SF (match_dup 4)))]
16003 "TARGET_USE_FANCY_MATH_387
16004 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16005 && flag_unsafe_math_optimizations"
16007 operands[2] = gen_reg_rtx (XFmode);
16008 operands[3] = gen_reg_rtx (XFmode);
16009 operands[4] = gen_reg_rtx (XFmode);
16012 (define_expand "logbdf2"
16013 [(set (match_dup 2)
16014 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16015 (parallel [(set (match_dup 3)
16016 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16018 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16019 (set (match_operand:DF 0 "register_operand" "")
16020 (float_truncate:DF (match_dup 4)))]
16021 "TARGET_USE_FANCY_MATH_387
16022 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16023 && flag_unsafe_math_optimizations"
16025 operands[2] = gen_reg_rtx (XFmode);
16026 operands[3] = gen_reg_rtx (XFmode);
16027 operands[4] = gen_reg_rtx (XFmode);
16030 (define_expand "logbxf2"
16031 [(parallel [(set (match_dup 2)
16032 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16033 UNSPEC_XTRACT_FRACT))
16034 (set (match_operand:XF 0 "register_operand" "")
16035 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16036 "TARGET_USE_FANCY_MATH_387
16037 && flag_unsafe_math_optimizations"
16039 operands[2] = gen_reg_rtx (XFmode);
16042 (define_expand "ilogbsi2"
16043 [(parallel [(set (match_dup 2)
16044 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16045 UNSPEC_XTRACT_FRACT))
16046 (set (match_operand:XF 3 "register_operand" "")
16047 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16048 (parallel [(set (match_operand:SI 0 "register_operand" "")
16049 (fix:SI (match_dup 3)))
16050 (clobber (reg:CC FLAGS_REG))])]
16051 "TARGET_USE_FANCY_MATH_387
16052 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053 && flag_unsafe_math_optimizations"
16055 operands[2] = gen_reg_rtx (XFmode);
16056 operands[3] = gen_reg_rtx (XFmode);
16059 (define_insn "*f2xm1xf2"
16060 [(set (match_operand:XF 0 "register_operand" "=f")
16061 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16063 "TARGET_USE_FANCY_MATH_387
16064 && flag_unsafe_math_optimizations"
16066 [(set_attr "type" "fpspc")
16067 (set_attr "mode" "XF")])
16069 (define_insn "*fscalexf4"
16070 [(set (match_operand:XF 0 "register_operand" "=f")
16071 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16072 (match_operand:XF 3 "register_operand" "1")]
16073 UNSPEC_FSCALE_FRACT))
16074 (set (match_operand:XF 1 "register_operand" "=u")
16075 (unspec:XF [(match_dup 2) (match_dup 3)]
16076 UNSPEC_FSCALE_EXP))]
16077 "TARGET_USE_FANCY_MATH_387
16078 && flag_unsafe_math_optimizations"
16080 [(set_attr "type" "fpspc")
16081 (set_attr "mode" "XF")])
16083 (define_expand "expsf2"
16084 [(set (match_dup 2)
16085 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16086 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16087 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16088 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16089 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16090 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16091 (parallel [(set (match_dup 10)
16092 (unspec:XF [(match_dup 9) (match_dup 5)]
16093 UNSPEC_FSCALE_FRACT))
16094 (set (match_dup 11)
16095 (unspec:XF [(match_dup 9) (match_dup 5)]
16096 UNSPEC_FSCALE_EXP))])
16097 (set (match_operand:SF 0 "register_operand" "")
16098 (float_truncate:SF (match_dup 10)))]
16099 "TARGET_USE_FANCY_MATH_387
16100 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16101 && flag_unsafe_math_optimizations"
16106 for (i=2; i<12; i++)
16107 operands[i] = gen_reg_rtx (XFmode);
16108 temp = standard_80387_constant_rtx (5); /* fldl2e */
16109 emit_move_insn (operands[3], temp);
16110 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16113 (define_expand "expdf2"
16114 [(set (match_dup 2)
16115 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16116 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16117 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16118 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16119 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16120 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16121 (parallel [(set (match_dup 10)
16122 (unspec:XF [(match_dup 9) (match_dup 5)]
16123 UNSPEC_FSCALE_FRACT))
16124 (set (match_dup 11)
16125 (unspec:XF [(match_dup 9) (match_dup 5)]
16126 UNSPEC_FSCALE_EXP))])
16127 (set (match_operand:DF 0 "register_operand" "")
16128 (float_truncate:DF (match_dup 10)))]
16129 "TARGET_USE_FANCY_MATH_387
16130 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16131 && flag_unsafe_math_optimizations"
16136 for (i=2; i<12; i++)
16137 operands[i] = gen_reg_rtx (XFmode);
16138 temp = standard_80387_constant_rtx (5); /* fldl2e */
16139 emit_move_insn (operands[3], temp);
16140 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16143 (define_expand "expxf2"
16144 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16146 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16147 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16148 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16149 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16150 (parallel [(set (match_operand:XF 0 "register_operand" "")
16151 (unspec:XF [(match_dup 8) (match_dup 4)]
16152 UNSPEC_FSCALE_FRACT))
16154 (unspec:XF [(match_dup 8) (match_dup 4)]
16155 UNSPEC_FSCALE_EXP))])]
16156 "TARGET_USE_FANCY_MATH_387
16157 && flag_unsafe_math_optimizations"
16162 for (i=2; i<10; i++)
16163 operands[i] = gen_reg_rtx (XFmode);
16164 temp = standard_80387_constant_rtx (5); /* fldl2e */
16165 emit_move_insn (operands[2], temp);
16166 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16169 (define_expand "exp10sf2"
16170 [(set (match_dup 2)
16171 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16172 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16173 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16174 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16175 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16176 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16177 (parallel [(set (match_dup 10)
16178 (unspec:XF [(match_dup 9) (match_dup 5)]
16179 UNSPEC_FSCALE_FRACT))
16180 (set (match_dup 11)
16181 (unspec:XF [(match_dup 9) (match_dup 5)]
16182 UNSPEC_FSCALE_EXP))])
16183 (set (match_operand:SF 0 "register_operand" "")
16184 (float_truncate:SF (match_dup 10)))]
16185 "TARGET_USE_FANCY_MATH_387
16186 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16187 && flag_unsafe_math_optimizations"
16192 for (i=2; i<12; i++)
16193 operands[i] = gen_reg_rtx (XFmode);
16194 temp = standard_80387_constant_rtx (6); /* fldl2t */
16195 emit_move_insn (operands[3], temp);
16196 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16199 (define_expand "exp10df2"
16200 [(set (match_dup 2)
16201 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16202 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16203 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16204 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16205 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16206 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16207 (parallel [(set (match_dup 10)
16208 (unspec:XF [(match_dup 9) (match_dup 5)]
16209 UNSPEC_FSCALE_FRACT))
16210 (set (match_dup 11)
16211 (unspec:XF [(match_dup 9) (match_dup 5)]
16212 UNSPEC_FSCALE_EXP))])
16213 (set (match_operand:DF 0 "register_operand" "")
16214 (float_truncate:DF (match_dup 10)))]
16215 "TARGET_USE_FANCY_MATH_387
16216 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16217 && flag_unsafe_math_optimizations"
16222 for (i=2; i<12; i++)
16223 operands[i] = gen_reg_rtx (XFmode);
16224 temp = standard_80387_constant_rtx (6); /* fldl2t */
16225 emit_move_insn (operands[3], temp);
16226 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16229 (define_expand "exp10xf2"
16230 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16232 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16233 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16234 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16235 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16236 (parallel [(set (match_operand:XF 0 "register_operand" "")
16237 (unspec:XF [(match_dup 8) (match_dup 4)]
16238 UNSPEC_FSCALE_FRACT))
16240 (unspec:XF [(match_dup 8) (match_dup 4)]
16241 UNSPEC_FSCALE_EXP))])]
16242 "TARGET_USE_FANCY_MATH_387
16243 && flag_unsafe_math_optimizations"
16248 for (i=2; i<10; i++)
16249 operands[i] = gen_reg_rtx (XFmode);
16250 temp = standard_80387_constant_rtx (6); /* fldl2t */
16251 emit_move_insn (operands[2], temp);
16252 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16255 (define_expand "exp2sf2"
16256 [(set (match_dup 2)
16257 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16258 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16259 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16260 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16261 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16262 (parallel [(set (match_dup 8)
16263 (unspec:XF [(match_dup 7) (match_dup 3)]
16264 UNSPEC_FSCALE_FRACT))
16266 (unspec:XF [(match_dup 7) (match_dup 3)]
16267 UNSPEC_FSCALE_EXP))])
16268 (set (match_operand:SF 0 "register_operand" "")
16269 (float_truncate:SF (match_dup 8)))]
16270 "TARGET_USE_FANCY_MATH_387
16271 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16272 && flag_unsafe_math_optimizations"
16276 for (i=2; i<10; i++)
16277 operands[i] = gen_reg_rtx (XFmode);
16278 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16281 (define_expand "exp2df2"
16282 [(set (match_dup 2)
16283 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16284 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16285 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16286 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16287 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16288 (parallel [(set (match_dup 8)
16289 (unspec:XF [(match_dup 7) (match_dup 3)]
16290 UNSPEC_FSCALE_FRACT))
16292 (unspec:XF [(match_dup 7) (match_dup 3)]
16293 UNSPEC_FSCALE_EXP))])
16294 (set (match_operand:DF 0 "register_operand" "")
16295 (float_truncate:DF (match_dup 8)))]
16296 "TARGET_USE_FANCY_MATH_387
16297 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16298 && flag_unsafe_math_optimizations"
16302 for (i=2; i<10; i++)
16303 operands[i] = gen_reg_rtx (XFmode);
16304 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16307 (define_expand "exp2xf2"
16308 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16309 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16310 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16311 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16312 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16313 (parallel [(set (match_operand:XF 0 "register_operand" "")
16314 (unspec:XF [(match_dup 7) (match_dup 3)]
16315 UNSPEC_FSCALE_FRACT))
16317 (unspec:XF [(match_dup 7) (match_dup 3)]
16318 UNSPEC_FSCALE_EXP))])]
16319 "TARGET_USE_FANCY_MATH_387
16320 && flag_unsafe_math_optimizations"
16324 for (i=2; i<9; i++)
16325 operands[i] = gen_reg_rtx (XFmode);
16326 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16329 (define_expand "expm1df2"
16330 [(set (match_dup 2)
16331 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16332 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16333 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16334 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16335 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16336 (parallel [(set (match_dup 8)
16337 (unspec:XF [(match_dup 7) (match_dup 5)]
16338 UNSPEC_FSCALE_FRACT))
16340 (unspec:XF [(match_dup 7) (match_dup 5)]
16341 UNSPEC_FSCALE_EXP))])
16342 (parallel [(set (match_dup 11)
16343 (unspec:XF [(match_dup 10) (match_dup 9)]
16344 UNSPEC_FSCALE_FRACT))
16345 (set (match_dup 12)
16346 (unspec:XF [(match_dup 10) (match_dup 9)]
16347 UNSPEC_FSCALE_EXP))])
16348 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16349 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16350 (set (match_operand:DF 0 "register_operand" "")
16351 (float_truncate:DF (match_dup 14)))]
16352 "TARGET_USE_FANCY_MATH_387
16353 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16354 && flag_unsafe_math_optimizations"
16359 for (i=2; i<15; i++)
16360 operands[i] = gen_reg_rtx (XFmode);
16361 temp = standard_80387_constant_rtx (5); /* fldl2e */
16362 emit_move_insn (operands[3], temp);
16363 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16366 (define_expand "expm1sf2"
16367 [(set (match_dup 2)
16368 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16369 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16370 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16371 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16372 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16373 (parallel [(set (match_dup 8)
16374 (unspec:XF [(match_dup 7) (match_dup 5)]
16375 UNSPEC_FSCALE_FRACT))
16377 (unspec:XF [(match_dup 7) (match_dup 5)]
16378 UNSPEC_FSCALE_EXP))])
16379 (parallel [(set (match_dup 11)
16380 (unspec:XF [(match_dup 10) (match_dup 9)]
16381 UNSPEC_FSCALE_FRACT))
16382 (set (match_dup 12)
16383 (unspec:XF [(match_dup 10) (match_dup 9)]
16384 UNSPEC_FSCALE_EXP))])
16385 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16386 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16387 (set (match_operand:SF 0 "register_operand" "")
16388 (float_truncate:SF (match_dup 14)))]
16389 "TARGET_USE_FANCY_MATH_387
16390 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16391 && flag_unsafe_math_optimizations"
16396 for (i=2; i<15; i++)
16397 operands[i] = gen_reg_rtx (XFmode);
16398 temp = standard_80387_constant_rtx (5); /* fldl2e */
16399 emit_move_insn (operands[3], temp);
16400 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16403 (define_expand "expm1xf2"
16404 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16406 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16407 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16408 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16409 (parallel [(set (match_dup 7)
16410 (unspec:XF [(match_dup 6) (match_dup 4)]
16411 UNSPEC_FSCALE_FRACT))
16413 (unspec:XF [(match_dup 6) (match_dup 4)]
16414 UNSPEC_FSCALE_EXP))])
16415 (parallel [(set (match_dup 10)
16416 (unspec:XF [(match_dup 9) (match_dup 8)]
16417 UNSPEC_FSCALE_FRACT))
16418 (set (match_dup 11)
16419 (unspec:XF [(match_dup 9) (match_dup 8)]
16420 UNSPEC_FSCALE_EXP))])
16421 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16422 (set (match_operand:XF 0 "register_operand" "")
16423 (plus:XF (match_dup 12) (match_dup 7)))]
16424 "TARGET_USE_FANCY_MATH_387
16425 && flag_unsafe_math_optimizations"
16430 for (i=2; i<13; i++)
16431 operands[i] = gen_reg_rtx (XFmode);
16432 temp = standard_80387_constant_rtx (5); /* fldl2e */
16433 emit_move_insn (operands[2], temp);
16434 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16437 (define_expand "ldexpdf3"
16438 [(set (match_dup 3)
16439 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16441 (float:XF (match_operand:SI 2 "register_operand" "")))
16442 (parallel [(set (match_dup 5)
16443 (unspec:XF [(match_dup 3) (match_dup 4)]
16444 UNSPEC_FSCALE_FRACT))
16446 (unspec:XF [(match_dup 3) (match_dup 4)]
16447 UNSPEC_FSCALE_EXP))])
16448 (set (match_operand:DF 0 "register_operand" "")
16449 (float_truncate:DF (match_dup 5)))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16452 && flag_unsafe_math_optimizations"
16456 for (i=3; i<7; i++)
16457 operands[i] = gen_reg_rtx (XFmode);
16460 (define_expand "ldexpsf3"
16461 [(set (match_dup 3)
16462 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16464 (float:XF (match_operand:SI 2 "register_operand" "")))
16465 (parallel [(set (match_dup 5)
16466 (unspec:XF [(match_dup 3) (match_dup 4)]
16467 UNSPEC_FSCALE_FRACT))
16469 (unspec:XF [(match_dup 3) (match_dup 4)]
16470 UNSPEC_FSCALE_EXP))])
16471 (set (match_operand:SF 0 "register_operand" "")
16472 (float_truncate:SF (match_dup 5)))]
16473 "TARGET_USE_FANCY_MATH_387
16474 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16475 && flag_unsafe_math_optimizations"
16479 for (i=3; i<7; i++)
16480 operands[i] = gen_reg_rtx (XFmode);
16483 (define_expand "ldexpxf3"
16484 [(set (match_dup 3)
16485 (float:XF (match_operand:SI 2 "register_operand" "")))
16486 (parallel [(set (match_operand:XF 0 " register_operand" "")
16487 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16489 UNSPEC_FSCALE_FRACT))
16491 (unspec:XF [(match_dup 1) (match_dup 3)]
16492 UNSPEC_FSCALE_EXP))])]
16493 "TARGET_USE_FANCY_MATH_387
16494 && flag_unsafe_math_optimizations"
16498 for (i=3; i<5; i++)
16499 operands[i] = gen_reg_rtx (XFmode);
16503 (define_insn "frndintxf2"
16504 [(set (match_operand:XF 0 "register_operand" "=f")
16505 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16507 "TARGET_USE_FANCY_MATH_387
16508 && flag_unsafe_math_optimizations"
16510 [(set_attr "type" "fpspc")
16511 (set_attr "mode" "XF")])
16513 (define_expand "rintdf2"
16514 [(use (match_operand:DF 0 "register_operand" ""))
16515 (use (match_operand:DF 1 "register_operand" ""))]
16516 "TARGET_USE_FANCY_MATH_387
16517 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16518 && flag_unsafe_math_optimizations"
16520 rtx op0 = gen_reg_rtx (XFmode);
16521 rtx op1 = gen_reg_rtx (XFmode);
16523 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16524 emit_insn (gen_frndintxf2 (op0, op1));
16526 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16530 (define_expand "rintsf2"
16531 [(use (match_operand:SF 0 "register_operand" ""))
16532 (use (match_operand:SF 1 "register_operand" ""))]
16533 "TARGET_USE_FANCY_MATH_387
16534 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16535 && flag_unsafe_math_optimizations"
16537 rtx op0 = gen_reg_rtx (XFmode);
16538 rtx op1 = gen_reg_rtx (XFmode);
16540 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16541 emit_insn (gen_frndintxf2 (op0, op1));
16543 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16547 (define_expand "rintxf2"
16548 [(use (match_operand:XF 0 "register_operand" ""))
16549 (use (match_operand:XF 1 "register_operand" ""))]
16550 "TARGET_USE_FANCY_MATH_387
16551 && flag_unsafe_math_optimizations"
16553 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16557 (define_insn_and_split "*fistdi2_1"
16558 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16559 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16561 "TARGET_USE_FANCY_MATH_387
16562 && flag_unsafe_math_optimizations
16563 && !(reload_completed || reload_in_progress)"
16568 if (memory_operand (operands[0], VOIDmode))
16569 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16572 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16573 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16578 [(set_attr "type" "fpspc")
16579 (set_attr "mode" "DI")])
16581 (define_insn "fistdi2"
16582 [(set (match_operand:DI 0 "memory_operand" "=m")
16583 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16585 (clobber (match_scratch:XF 2 "=&1f"))]
16586 "TARGET_USE_FANCY_MATH_387
16587 && flag_unsafe_math_optimizations"
16588 "* return output_fix_trunc (insn, operands, 0);"
16589 [(set_attr "type" "fpspc")
16590 (set_attr "mode" "DI")])
16592 (define_insn "fistdi2_with_temp"
16593 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16594 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16596 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16597 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16598 "TARGET_USE_FANCY_MATH_387
16599 && flag_unsafe_math_optimizations"
16601 [(set_attr "type" "fpspc")
16602 (set_attr "mode" "DI")])
16605 [(set (match_operand:DI 0 "register_operand" "")
16606 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16608 (clobber (match_operand:DI 2 "memory_operand" ""))
16609 (clobber (match_scratch 3 ""))]
16611 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16612 (clobber (match_dup 3))])
16613 (set (match_dup 0) (match_dup 2))]
16617 [(set (match_operand:DI 0 "memory_operand" "")
16618 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16620 (clobber (match_operand:DI 2 "memory_operand" ""))
16621 (clobber (match_scratch 3 ""))]
16623 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16624 (clobber (match_dup 3))])]
16627 (define_insn_and_split "*fist<mode>2_1"
16628 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16629 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16631 "TARGET_USE_FANCY_MATH_387
16632 && flag_unsafe_math_optimizations
16633 && !(reload_completed || reload_in_progress)"
16638 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16639 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16643 [(set_attr "type" "fpspc")
16644 (set_attr "mode" "<MODE>")])
16646 (define_insn "fist<mode>2"
16647 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16648 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16650 "TARGET_USE_FANCY_MATH_387
16651 && flag_unsafe_math_optimizations"
16652 "* return output_fix_trunc (insn, operands, 0);"
16653 [(set_attr "type" "fpspc")
16654 (set_attr "mode" "<MODE>")])
16656 (define_insn "fist<mode>2_with_temp"
16657 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16658 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16660 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16661 "TARGET_USE_FANCY_MATH_387
16662 && flag_unsafe_math_optimizations"
16664 [(set_attr "type" "fpspc")
16665 (set_attr "mode" "<MODE>")])
16668 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16669 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16671 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16673 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16675 (set (match_dup 0) (match_dup 2))]
16679 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16680 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16682 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16684 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16688 (define_expand "lrint<mode>2"
16689 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16690 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16692 "TARGET_USE_FANCY_MATH_387
16693 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16694 && flag_unsafe_math_optimizations"
16697 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16698 (define_insn_and_split "frndintxf2_floor"
16699 [(set (match_operand:XF 0 "register_operand" "=f")
16700 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16701 UNSPEC_FRNDINT_FLOOR))
16702 (clobber (reg:CC FLAGS_REG))]
16703 "TARGET_USE_FANCY_MATH_387
16704 && flag_unsafe_math_optimizations
16705 && !(reload_completed || reload_in_progress)"
16710 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16712 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16713 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16715 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16716 operands[2], operands[3]));
16719 [(set_attr "type" "frndint")
16720 (set_attr "i387_cw" "floor")
16721 (set_attr "mode" "XF")])
16723 (define_insn "frndintxf2_floor_i387"
16724 [(set (match_operand:XF 0 "register_operand" "=f")
16725 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16726 UNSPEC_FRNDINT_FLOOR))
16727 (use (match_operand:HI 2 "memory_operand" "m"))
16728 (use (match_operand:HI 3 "memory_operand" "m"))]
16729 "TARGET_USE_FANCY_MATH_387
16730 && flag_unsafe_math_optimizations"
16731 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16732 [(set_attr "type" "frndint")
16733 (set_attr "i387_cw" "floor")
16734 (set_attr "mode" "XF")])
16736 (define_expand "floorxf2"
16737 [(use (match_operand:XF 0 "register_operand" ""))
16738 (use (match_operand:XF 1 "register_operand" ""))]
16739 "TARGET_USE_FANCY_MATH_387
16740 && flag_unsafe_math_optimizations"
16742 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16746 (define_expand "floordf2"
16747 [(use (match_operand:DF 0 "register_operand" ""))
16748 (use (match_operand:DF 1 "register_operand" ""))]
16749 "TARGET_USE_FANCY_MATH_387
16750 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16751 && flag_unsafe_math_optimizations"
16753 rtx op0 = gen_reg_rtx (XFmode);
16754 rtx op1 = gen_reg_rtx (XFmode);
16756 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16757 emit_insn (gen_frndintxf2_floor (op0, op1));
16759 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16763 (define_expand "floorsf2"
16764 [(use (match_operand:SF 0 "register_operand" ""))
16765 (use (match_operand:SF 1 "register_operand" ""))]
16766 "TARGET_USE_FANCY_MATH_387
16767 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16768 && flag_unsafe_math_optimizations"
16770 rtx op0 = gen_reg_rtx (XFmode);
16771 rtx op1 = gen_reg_rtx (XFmode);
16773 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16774 emit_insn (gen_frndintxf2_floor (op0, op1));
16776 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16780 (define_insn_and_split "*fist<mode>2_floor_1"
16781 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16782 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16783 UNSPEC_FIST_FLOOR))
16784 (clobber (reg:CC FLAGS_REG))]
16785 "TARGET_USE_FANCY_MATH_387
16786 && flag_unsafe_math_optimizations
16787 && !(reload_completed || reload_in_progress)"
16792 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16794 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16795 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16796 if (memory_operand (operands[0], VOIDmode))
16797 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16798 operands[2], operands[3]));
16801 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16802 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16803 operands[2], operands[3],
16808 [(set_attr "type" "fistp")
16809 (set_attr "i387_cw" "floor")
16810 (set_attr "mode" "<MODE>")])
16812 (define_insn "fistdi2_floor"
16813 [(set (match_operand:DI 0 "memory_operand" "=m")
16814 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16815 UNSPEC_FIST_FLOOR))
16816 (use (match_operand:HI 2 "memory_operand" "m"))
16817 (use (match_operand:HI 3 "memory_operand" "m"))
16818 (clobber (match_scratch:XF 4 "=&1f"))]
16819 "TARGET_USE_FANCY_MATH_387
16820 && flag_unsafe_math_optimizations"
16821 "* return output_fix_trunc (insn, operands, 0);"
16822 [(set_attr "type" "fistp")
16823 (set_attr "i387_cw" "floor")
16824 (set_attr "mode" "DI")])
16826 (define_insn "fistdi2_floor_with_temp"
16827 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16828 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16829 UNSPEC_FIST_FLOOR))
16830 (use (match_operand:HI 2 "memory_operand" "m,m"))
16831 (use (match_operand:HI 3 "memory_operand" "m,m"))
16832 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16833 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16834 "TARGET_USE_FANCY_MATH_387
16835 && flag_unsafe_math_optimizations"
16837 [(set_attr "type" "fistp")
16838 (set_attr "i387_cw" "floor")
16839 (set_attr "mode" "DI")])
16842 [(set (match_operand:DI 0 "register_operand" "")
16843 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16844 UNSPEC_FIST_FLOOR))
16845 (use (match_operand:HI 2 "memory_operand" ""))
16846 (use (match_operand:HI 3 "memory_operand" ""))
16847 (clobber (match_operand:DI 4 "memory_operand" ""))
16848 (clobber (match_scratch 5 ""))]
16850 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16851 (use (match_dup 2))
16852 (use (match_dup 3))
16853 (clobber (match_dup 5))])
16854 (set (match_dup 0) (match_dup 4))]
16858 [(set (match_operand:DI 0 "memory_operand" "")
16859 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16860 UNSPEC_FIST_FLOOR))
16861 (use (match_operand:HI 2 "memory_operand" ""))
16862 (use (match_operand:HI 3 "memory_operand" ""))
16863 (clobber (match_operand:DI 4 "memory_operand" ""))
16864 (clobber (match_scratch 5 ""))]
16866 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16867 (use (match_dup 2))
16868 (use (match_dup 3))
16869 (clobber (match_dup 5))])]
16872 (define_insn "fist<mode>2_floor"
16873 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16874 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16875 UNSPEC_FIST_FLOOR))
16876 (use (match_operand:HI 2 "memory_operand" "m"))
16877 (use (match_operand:HI 3 "memory_operand" "m"))]
16878 "TARGET_USE_FANCY_MATH_387
16879 && flag_unsafe_math_optimizations"
16880 "* return output_fix_trunc (insn, operands, 0);"
16881 [(set_attr "type" "fistp")
16882 (set_attr "i387_cw" "floor")
16883 (set_attr "mode" "<MODE>")])
16885 (define_insn "fist<mode>2_floor_with_temp"
16886 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16887 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16888 UNSPEC_FIST_FLOOR))
16889 (use (match_operand:HI 2 "memory_operand" "m,m"))
16890 (use (match_operand:HI 3 "memory_operand" "m,m"))
16891 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16892 "TARGET_USE_FANCY_MATH_387
16893 && flag_unsafe_math_optimizations"
16895 [(set_attr "type" "fistp")
16896 (set_attr "i387_cw" "floor")
16897 (set_attr "mode" "<MODE>")])
16900 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16901 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16902 UNSPEC_FIST_FLOOR))
16903 (use (match_operand:HI 2 "memory_operand" ""))
16904 (use (match_operand:HI 3 "memory_operand" ""))
16905 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16907 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16908 UNSPEC_FIST_FLOOR))
16909 (use (match_dup 2))
16910 (use (match_dup 3))])
16911 (set (match_dup 0) (match_dup 4))]
16915 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16916 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16917 UNSPEC_FIST_FLOOR))
16918 (use (match_operand:HI 2 "memory_operand" ""))
16919 (use (match_operand:HI 3 "memory_operand" ""))
16920 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16922 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16923 UNSPEC_FIST_FLOOR))
16924 (use (match_dup 2))
16925 (use (match_dup 3))])]
16928 (define_expand "lfloor<mode>2"
16929 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16930 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16931 UNSPEC_FIST_FLOOR))
16932 (clobber (reg:CC FLAGS_REG))])]
16933 "TARGET_USE_FANCY_MATH_387
16934 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16935 && flag_unsafe_math_optimizations"
16938 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16939 (define_insn_and_split "frndintxf2_ceil"
16940 [(set (match_operand:XF 0 "register_operand" "=f")
16941 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16942 UNSPEC_FRNDINT_CEIL))
16943 (clobber (reg:CC FLAGS_REG))]
16944 "TARGET_USE_FANCY_MATH_387
16945 && flag_unsafe_math_optimizations
16946 && !(reload_completed || reload_in_progress)"
16951 ix86_optimize_mode_switching[I387_CEIL] = 1;
16953 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16954 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16956 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16957 operands[2], operands[3]));
16960 [(set_attr "type" "frndint")
16961 (set_attr "i387_cw" "ceil")
16962 (set_attr "mode" "XF")])
16964 (define_insn "frndintxf2_ceil_i387"
16965 [(set (match_operand:XF 0 "register_operand" "=f")
16966 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16967 UNSPEC_FRNDINT_CEIL))
16968 (use (match_operand:HI 2 "memory_operand" "m"))
16969 (use (match_operand:HI 3 "memory_operand" "m"))]
16970 "TARGET_USE_FANCY_MATH_387
16971 && flag_unsafe_math_optimizations"
16972 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16973 [(set_attr "type" "frndint")
16974 (set_attr "i387_cw" "ceil")
16975 (set_attr "mode" "XF")])
16977 (define_expand "ceilxf2"
16978 [(use (match_operand:XF 0 "register_operand" ""))
16979 (use (match_operand:XF 1 "register_operand" ""))]
16980 "TARGET_USE_FANCY_MATH_387
16981 && flag_unsafe_math_optimizations"
16983 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16987 (define_expand "ceildf2"
16988 [(use (match_operand:DF 0 "register_operand" ""))
16989 (use (match_operand:DF 1 "register_operand" ""))]
16990 "TARGET_USE_FANCY_MATH_387
16991 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16992 && flag_unsafe_math_optimizations"
16994 rtx op0 = gen_reg_rtx (XFmode);
16995 rtx op1 = gen_reg_rtx (XFmode);
16997 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16998 emit_insn (gen_frndintxf2_ceil (op0, op1));
17000 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17004 (define_expand "ceilsf2"
17005 [(use (match_operand:SF 0 "register_operand" ""))
17006 (use (match_operand:SF 1 "register_operand" ""))]
17007 "TARGET_USE_FANCY_MATH_387
17008 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17009 && flag_unsafe_math_optimizations"
17011 rtx op0 = gen_reg_rtx (XFmode);
17012 rtx op1 = gen_reg_rtx (XFmode);
17014 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17015 emit_insn (gen_frndintxf2_ceil (op0, op1));
17017 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17021 (define_insn_and_split "*fist<mode>2_ceil_1"
17022 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17023 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17025 (clobber (reg:CC FLAGS_REG))]
17026 "TARGET_USE_FANCY_MATH_387
17027 && flag_unsafe_math_optimizations
17028 && !(reload_completed || reload_in_progress)"
17033 ix86_optimize_mode_switching[I387_CEIL] = 1;
17035 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17036 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17037 if (memory_operand (operands[0], VOIDmode))
17038 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17039 operands[2], operands[3]));
17042 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17043 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17044 operands[2], operands[3],
17049 [(set_attr "type" "fistp")
17050 (set_attr "i387_cw" "ceil")
17051 (set_attr "mode" "<MODE>")])
17053 (define_insn "fistdi2_ceil"
17054 [(set (match_operand:DI 0 "memory_operand" "=m")
17055 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17057 (use (match_operand:HI 2 "memory_operand" "m"))
17058 (use (match_operand:HI 3 "memory_operand" "m"))
17059 (clobber (match_scratch:XF 4 "=&1f"))]
17060 "TARGET_USE_FANCY_MATH_387
17061 && flag_unsafe_math_optimizations"
17062 "* return output_fix_trunc (insn, operands, 0);"
17063 [(set_attr "type" "fistp")
17064 (set_attr "i387_cw" "ceil")
17065 (set_attr "mode" "DI")])
17067 (define_insn "fistdi2_ceil_with_temp"
17068 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17069 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17071 (use (match_operand:HI 2 "memory_operand" "m,m"))
17072 (use (match_operand:HI 3 "memory_operand" "m,m"))
17073 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17074 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17075 "TARGET_USE_FANCY_MATH_387
17076 && flag_unsafe_math_optimizations"
17078 [(set_attr "type" "fistp")
17079 (set_attr "i387_cw" "ceil")
17080 (set_attr "mode" "DI")])
17083 [(set (match_operand:DI 0 "register_operand" "")
17084 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17086 (use (match_operand:HI 2 "memory_operand" ""))
17087 (use (match_operand:HI 3 "memory_operand" ""))
17088 (clobber (match_operand:DI 4 "memory_operand" ""))
17089 (clobber (match_scratch 5 ""))]
17091 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17092 (use (match_dup 2))
17093 (use (match_dup 3))
17094 (clobber (match_dup 5))])
17095 (set (match_dup 0) (match_dup 4))]
17099 [(set (match_operand:DI 0 "memory_operand" "")
17100 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17102 (use (match_operand:HI 2 "memory_operand" ""))
17103 (use (match_operand:HI 3 "memory_operand" ""))
17104 (clobber (match_operand:DI 4 "memory_operand" ""))
17105 (clobber (match_scratch 5 ""))]
17107 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17108 (use (match_dup 2))
17109 (use (match_dup 3))
17110 (clobber (match_dup 5))])]
17113 (define_insn "fist<mode>2_ceil"
17114 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17115 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17117 (use (match_operand:HI 2 "memory_operand" "m"))
17118 (use (match_operand:HI 3 "memory_operand" "m"))]
17119 "TARGET_USE_FANCY_MATH_387
17120 && flag_unsafe_math_optimizations"
17121 "* return output_fix_trunc (insn, operands, 0);"
17122 [(set_attr "type" "fistp")
17123 (set_attr "i387_cw" "ceil")
17124 (set_attr "mode" "<MODE>")])
17126 (define_insn "fist<mode>2_ceil_with_temp"
17127 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17128 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17130 (use (match_operand:HI 2 "memory_operand" "m,m"))
17131 (use (match_operand:HI 3 "memory_operand" "m,m"))
17132 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17133 "TARGET_USE_FANCY_MATH_387
17134 && flag_unsafe_math_optimizations"
17136 [(set_attr "type" "fistp")
17137 (set_attr "i387_cw" "ceil")
17138 (set_attr "mode" "<MODE>")])
17141 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17142 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17144 (use (match_operand:HI 2 "memory_operand" ""))
17145 (use (match_operand:HI 3 "memory_operand" ""))
17146 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17148 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17150 (use (match_dup 2))
17151 (use (match_dup 3))])
17152 (set (match_dup 0) (match_dup 4))]
17156 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17157 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17159 (use (match_operand:HI 2 "memory_operand" ""))
17160 (use (match_operand:HI 3 "memory_operand" ""))
17161 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17163 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17165 (use (match_dup 2))
17166 (use (match_dup 3))])]
17169 (define_expand "lceil<mode>2"
17170 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17171 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17173 (clobber (reg:CC FLAGS_REG))])]
17174 "TARGET_USE_FANCY_MATH_387
17175 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17176 && flag_unsafe_math_optimizations"
17179 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17180 (define_insn_and_split "frndintxf2_trunc"
17181 [(set (match_operand:XF 0 "register_operand" "=f")
17182 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17183 UNSPEC_FRNDINT_TRUNC))
17184 (clobber (reg:CC FLAGS_REG))]
17185 "TARGET_USE_FANCY_MATH_387
17186 && flag_unsafe_math_optimizations
17187 && !(reload_completed || reload_in_progress)"
17192 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17194 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17195 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17197 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17198 operands[2], operands[3]));
17201 [(set_attr "type" "frndint")
17202 (set_attr "i387_cw" "trunc")
17203 (set_attr "mode" "XF")])
17205 (define_insn "frndintxf2_trunc_i387"
17206 [(set (match_operand:XF 0 "register_operand" "=f")
17207 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17208 UNSPEC_FRNDINT_TRUNC))
17209 (use (match_operand:HI 2 "memory_operand" "m"))
17210 (use (match_operand:HI 3 "memory_operand" "m"))]
17211 "TARGET_USE_FANCY_MATH_387
17212 && flag_unsafe_math_optimizations"
17213 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17214 [(set_attr "type" "frndint")
17215 (set_attr "i387_cw" "trunc")
17216 (set_attr "mode" "XF")])
17218 (define_expand "btruncxf2"
17219 [(use (match_operand:XF 0 "register_operand" ""))
17220 (use (match_operand:XF 1 "register_operand" ""))]
17221 "TARGET_USE_FANCY_MATH_387
17222 && flag_unsafe_math_optimizations"
17224 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17228 (define_expand "btruncdf2"
17229 [(use (match_operand:DF 0 "register_operand" ""))
17230 (use (match_operand:DF 1 "register_operand" ""))]
17231 "TARGET_USE_FANCY_MATH_387
17232 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17233 && flag_unsafe_math_optimizations"
17235 rtx op0 = gen_reg_rtx (XFmode);
17236 rtx op1 = gen_reg_rtx (XFmode);
17238 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17239 emit_insn (gen_frndintxf2_trunc (op0, op1));
17241 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17245 (define_expand "btruncsf2"
17246 [(use (match_operand:SF 0 "register_operand" ""))
17247 (use (match_operand:SF 1 "register_operand" ""))]
17248 "TARGET_USE_FANCY_MATH_387
17249 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17250 && flag_unsafe_math_optimizations"
17252 rtx op0 = gen_reg_rtx (XFmode);
17253 rtx op1 = gen_reg_rtx (XFmode);
17255 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17256 emit_insn (gen_frndintxf2_trunc (op0, op1));
17258 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17262 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17263 (define_insn_and_split "frndintxf2_mask_pm"
17264 [(set (match_operand:XF 0 "register_operand" "=f")
17265 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17266 UNSPEC_FRNDINT_MASK_PM))
17267 (clobber (reg:CC FLAGS_REG))]
17268 "TARGET_USE_FANCY_MATH_387
17269 && flag_unsafe_math_optimizations
17270 && !(reload_completed || reload_in_progress)"
17275 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17277 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17278 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17280 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17281 operands[2], operands[3]));
17284 [(set_attr "type" "frndint")
17285 (set_attr "i387_cw" "mask_pm")
17286 (set_attr "mode" "XF")])
17288 (define_insn "frndintxf2_mask_pm_i387"
17289 [(set (match_operand:XF 0 "register_operand" "=f")
17290 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17291 UNSPEC_FRNDINT_MASK_PM))
17292 (use (match_operand:HI 2 "memory_operand" "m"))
17293 (use (match_operand:HI 3 "memory_operand" "m"))]
17294 "TARGET_USE_FANCY_MATH_387
17295 && flag_unsafe_math_optimizations"
17296 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17297 [(set_attr "type" "frndint")
17298 (set_attr "i387_cw" "mask_pm")
17299 (set_attr "mode" "XF")])
17301 (define_expand "nearbyintxf2"
17302 [(use (match_operand:XF 0 "register_operand" ""))
17303 (use (match_operand:XF 1 "register_operand" ""))]
17304 "TARGET_USE_FANCY_MATH_387
17305 && flag_unsafe_math_optimizations"
17307 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17312 (define_expand "nearbyintdf2"
17313 [(use (match_operand:DF 0 "register_operand" ""))
17314 (use (match_operand:DF 1 "register_operand" ""))]
17315 "TARGET_USE_FANCY_MATH_387
17316 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17317 && flag_unsafe_math_optimizations"
17319 rtx op0 = gen_reg_rtx (XFmode);
17320 rtx op1 = gen_reg_rtx (XFmode);
17322 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17323 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17325 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17329 (define_expand "nearbyintsf2"
17330 [(use (match_operand:SF 0 "register_operand" ""))
17331 (use (match_operand:SF 1 "register_operand" ""))]
17332 "TARGET_USE_FANCY_MATH_387
17333 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17334 && flag_unsafe_math_optimizations"
17336 rtx op0 = gen_reg_rtx (XFmode);
17337 rtx op1 = gen_reg_rtx (XFmode);
17339 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17340 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17342 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17347 ;; Block operation instructions
17350 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17353 [(set_attr "type" "cld")])
17355 (define_expand "movmemsi"
17356 [(use (match_operand:BLK 0 "memory_operand" ""))
17357 (use (match_operand:BLK 1 "memory_operand" ""))
17358 (use (match_operand:SI 2 "nonmemory_operand" ""))
17359 (use (match_operand:SI 3 "const_int_operand" ""))]
17360 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17362 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17368 (define_expand "movmemdi"
17369 [(use (match_operand:BLK 0 "memory_operand" ""))
17370 (use (match_operand:BLK 1 "memory_operand" ""))
17371 (use (match_operand:DI 2 "nonmemory_operand" ""))
17372 (use (match_operand:DI 3 "const_int_operand" ""))]
17375 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17381 ;; Most CPUs don't like single string operations
17382 ;; Handle this case here to simplify previous expander.
17384 (define_expand "strmov"
17385 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17386 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17387 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17388 (clobber (reg:CC FLAGS_REG))])
17389 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17390 (clobber (reg:CC FLAGS_REG))])]
17393 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17395 /* If .md ever supports :P for Pmode, these can be directly
17396 in the pattern above. */
17397 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17398 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17400 if (TARGET_SINGLE_STRINGOP || optimize_size)
17402 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17403 operands[2], operands[3],
17404 operands[5], operands[6]));
17408 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17411 (define_expand "strmov_singleop"
17412 [(parallel [(set (match_operand 1 "memory_operand" "")
17413 (match_operand 3 "memory_operand" ""))
17414 (set (match_operand 0 "register_operand" "")
17415 (match_operand 4 "" ""))
17416 (set (match_operand 2 "register_operand" "")
17417 (match_operand 5 "" ""))
17418 (use (reg:SI DIRFLAG_REG))])]
17419 "TARGET_SINGLE_STRINGOP || optimize_size"
17422 (define_insn "*strmovdi_rex_1"
17423 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17424 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17425 (set (match_operand:DI 0 "register_operand" "=D")
17426 (plus:DI (match_dup 2)
17428 (set (match_operand:DI 1 "register_operand" "=S")
17429 (plus:DI (match_dup 3)
17431 (use (reg:SI DIRFLAG_REG))]
17432 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17434 [(set_attr "type" "str")
17435 (set_attr "mode" "DI")
17436 (set_attr "memory" "both")])
17438 (define_insn "*strmovsi_1"
17439 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17440 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17441 (set (match_operand:SI 0 "register_operand" "=D")
17442 (plus:SI (match_dup 2)
17444 (set (match_operand:SI 1 "register_operand" "=S")
17445 (plus:SI (match_dup 3)
17447 (use (reg:SI DIRFLAG_REG))]
17448 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17450 [(set_attr "type" "str")
17451 (set_attr "mode" "SI")
17452 (set_attr "memory" "both")])
17454 (define_insn "*strmovsi_rex_1"
17455 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17456 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17457 (set (match_operand:DI 0 "register_operand" "=D")
17458 (plus:DI (match_dup 2)
17460 (set (match_operand:DI 1 "register_operand" "=S")
17461 (plus:DI (match_dup 3)
17463 (use (reg:SI DIRFLAG_REG))]
17464 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17466 [(set_attr "type" "str")
17467 (set_attr "mode" "SI")
17468 (set_attr "memory" "both")])
17470 (define_insn "*strmovhi_1"
17471 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17472 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17473 (set (match_operand:SI 0 "register_operand" "=D")
17474 (plus:SI (match_dup 2)
17476 (set (match_operand:SI 1 "register_operand" "=S")
17477 (plus:SI (match_dup 3)
17479 (use (reg:SI DIRFLAG_REG))]
17480 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17482 [(set_attr "type" "str")
17483 (set_attr "memory" "both")
17484 (set_attr "mode" "HI")])
17486 (define_insn "*strmovhi_rex_1"
17487 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17488 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17489 (set (match_operand:DI 0 "register_operand" "=D")
17490 (plus:DI (match_dup 2)
17492 (set (match_operand:DI 1 "register_operand" "=S")
17493 (plus:DI (match_dup 3)
17495 (use (reg:SI DIRFLAG_REG))]
17496 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17498 [(set_attr "type" "str")
17499 (set_attr "memory" "both")
17500 (set_attr "mode" "HI")])
17502 (define_insn "*strmovqi_1"
17503 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17504 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17505 (set (match_operand:SI 0 "register_operand" "=D")
17506 (plus:SI (match_dup 2)
17508 (set (match_operand:SI 1 "register_operand" "=S")
17509 (plus:SI (match_dup 3)
17511 (use (reg:SI DIRFLAG_REG))]
17512 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17514 [(set_attr "type" "str")
17515 (set_attr "memory" "both")
17516 (set_attr "mode" "QI")])
17518 (define_insn "*strmovqi_rex_1"
17519 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17520 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17521 (set (match_operand:DI 0 "register_operand" "=D")
17522 (plus:DI (match_dup 2)
17524 (set (match_operand:DI 1 "register_operand" "=S")
17525 (plus:DI (match_dup 3)
17527 (use (reg:SI DIRFLAG_REG))]
17528 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17530 [(set_attr "type" "str")
17531 (set_attr "memory" "both")
17532 (set_attr "mode" "QI")])
17534 (define_expand "rep_mov"
17535 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17536 (set (match_operand 0 "register_operand" "")
17537 (match_operand 5 "" ""))
17538 (set (match_operand 2 "register_operand" "")
17539 (match_operand 6 "" ""))
17540 (set (match_operand 1 "memory_operand" "")
17541 (match_operand 3 "memory_operand" ""))
17542 (use (match_dup 4))
17543 (use (reg:SI DIRFLAG_REG))])]
17547 (define_insn "*rep_movdi_rex64"
17548 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17549 (set (match_operand:DI 0 "register_operand" "=D")
17550 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17552 (match_operand:DI 3 "register_operand" "0")))
17553 (set (match_operand:DI 1 "register_operand" "=S")
17554 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17555 (match_operand:DI 4 "register_operand" "1")))
17556 (set (mem:BLK (match_dup 3))
17557 (mem:BLK (match_dup 4)))
17558 (use (match_dup 5))
17559 (use (reg:SI DIRFLAG_REG))]
17561 "{rep\;movsq|rep movsq}"
17562 [(set_attr "type" "str")
17563 (set_attr "prefix_rep" "1")
17564 (set_attr "memory" "both")
17565 (set_attr "mode" "DI")])
17567 (define_insn "*rep_movsi"
17568 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17569 (set (match_operand:SI 0 "register_operand" "=D")
17570 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17572 (match_operand:SI 3 "register_operand" "0")))
17573 (set (match_operand:SI 1 "register_operand" "=S")
17574 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17575 (match_operand:SI 4 "register_operand" "1")))
17576 (set (mem:BLK (match_dup 3))
17577 (mem:BLK (match_dup 4)))
17578 (use (match_dup 5))
17579 (use (reg:SI DIRFLAG_REG))]
17581 "{rep\;movsl|rep movsd}"
17582 [(set_attr "type" "str")
17583 (set_attr "prefix_rep" "1")
17584 (set_attr "memory" "both")
17585 (set_attr "mode" "SI")])
17587 (define_insn "*rep_movsi_rex64"
17588 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17589 (set (match_operand:DI 0 "register_operand" "=D")
17590 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17592 (match_operand:DI 3 "register_operand" "0")))
17593 (set (match_operand:DI 1 "register_operand" "=S")
17594 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17595 (match_operand:DI 4 "register_operand" "1")))
17596 (set (mem:BLK (match_dup 3))
17597 (mem:BLK (match_dup 4)))
17598 (use (match_dup 5))
17599 (use (reg:SI DIRFLAG_REG))]
17601 "{rep\;movsl|rep movsd}"
17602 [(set_attr "type" "str")
17603 (set_attr "prefix_rep" "1")
17604 (set_attr "memory" "both")
17605 (set_attr "mode" "SI")])
17607 (define_insn "*rep_movqi"
17608 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17609 (set (match_operand:SI 0 "register_operand" "=D")
17610 (plus:SI (match_operand:SI 3 "register_operand" "0")
17611 (match_operand:SI 5 "register_operand" "2")))
17612 (set (match_operand:SI 1 "register_operand" "=S")
17613 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17614 (set (mem:BLK (match_dup 3))
17615 (mem:BLK (match_dup 4)))
17616 (use (match_dup 5))
17617 (use (reg:SI DIRFLAG_REG))]
17619 "{rep\;movsb|rep movsb}"
17620 [(set_attr "type" "str")
17621 (set_attr "prefix_rep" "1")
17622 (set_attr "memory" "both")
17623 (set_attr "mode" "SI")])
17625 (define_insn "*rep_movqi_rex64"
17626 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17627 (set (match_operand:DI 0 "register_operand" "=D")
17628 (plus:DI (match_operand:DI 3 "register_operand" "0")
17629 (match_operand:DI 5 "register_operand" "2")))
17630 (set (match_operand:DI 1 "register_operand" "=S")
17631 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17632 (set (mem:BLK (match_dup 3))
17633 (mem:BLK (match_dup 4)))
17634 (use (match_dup 5))
17635 (use (reg:SI DIRFLAG_REG))]
17637 "{rep\;movsb|rep movsb}"
17638 [(set_attr "type" "str")
17639 (set_attr "prefix_rep" "1")
17640 (set_attr "memory" "both")
17641 (set_attr "mode" "SI")])
17643 (define_expand "setmemsi"
17644 [(use (match_operand:BLK 0 "memory_operand" ""))
17645 (use (match_operand:SI 1 "nonmemory_operand" ""))
17646 (use (match_operand 2 "const_int_operand" ""))
17647 (use (match_operand 3 "const_int_operand" ""))]
17650 /* If value to set is not zero, use the library routine. */
17651 if (operands[2] != const0_rtx)
17654 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17660 (define_expand "setmemdi"
17661 [(use (match_operand:BLK 0 "memory_operand" ""))
17662 (use (match_operand:DI 1 "nonmemory_operand" ""))
17663 (use (match_operand 2 "const_int_operand" ""))
17664 (use (match_operand 3 "const_int_operand" ""))]
17667 /* If value to set is not zero, use the library routine. */
17668 if (operands[2] != const0_rtx)
17671 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17677 ;; Most CPUs don't like single string operations
17678 ;; Handle this case here to simplify previous expander.
17680 (define_expand "strset"
17681 [(set (match_operand 1 "memory_operand" "")
17682 (match_operand 2 "register_operand" ""))
17683 (parallel [(set (match_operand 0 "register_operand" "")
17685 (clobber (reg:CC FLAGS_REG))])]
17688 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17689 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17691 /* If .md ever supports :P for Pmode, this can be directly
17692 in the pattern above. */
17693 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17694 GEN_INT (GET_MODE_SIZE (GET_MODE
17696 if (TARGET_SINGLE_STRINGOP || optimize_size)
17698 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17704 (define_expand "strset_singleop"
17705 [(parallel [(set (match_operand 1 "memory_operand" "")
17706 (match_operand 2 "register_operand" ""))
17707 (set (match_operand 0 "register_operand" "")
17708 (match_operand 3 "" ""))
17709 (use (reg:SI DIRFLAG_REG))])]
17710 "TARGET_SINGLE_STRINGOP || optimize_size"
17713 (define_insn "*strsetdi_rex_1"
17714 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17715 (match_operand:DI 2 "register_operand" "a"))
17716 (set (match_operand:DI 0 "register_operand" "=D")
17717 (plus:DI (match_dup 1)
17719 (use (reg:SI DIRFLAG_REG))]
17720 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17722 [(set_attr "type" "str")
17723 (set_attr "memory" "store")
17724 (set_attr "mode" "DI")])
17726 (define_insn "*strsetsi_1"
17727 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17728 (match_operand:SI 2 "register_operand" "a"))
17729 (set (match_operand:SI 0 "register_operand" "=D")
17730 (plus:SI (match_dup 1)
17732 (use (reg:SI DIRFLAG_REG))]
17733 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17735 [(set_attr "type" "str")
17736 (set_attr "memory" "store")
17737 (set_attr "mode" "SI")])
17739 (define_insn "*strsetsi_rex_1"
17740 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17741 (match_operand:SI 2 "register_operand" "a"))
17742 (set (match_operand:DI 0 "register_operand" "=D")
17743 (plus:DI (match_dup 1)
17745 (use (reg:SI DIRFLAG_REG))]
17746 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17748 [(set_attr "type" "str")
17749 (set_attr "memory" "store")
17750 (set_attr "mode" "SI")])
17752 (define_insn "*strsethi_1"
17753 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17754 (match_operand:HI 2 "register_operand" "a"))
17755 (set (match_operand:SI 0 "register_operand" "=D")
17756 (plus:SI (match_dup 1)
17758 (use (reg:SI DIRFLAG_REG))]
17759 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17761 [(set_attr "type" "str")
17762 (set_attr "memory" "store")
17763 (set_attr "mode" "HI")])
17765 (define_insn "*strsethi_rex_1"
17766 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17767 (match_operand:HI 2 "register_operand" "a"))
17768 (set (match_operand:DI 0 "register_operand" "=D")
17769 (plus:DI (match_dup 1)
17771 (use (reg:SI DIRFLAG_REG))]
17772 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17774 [(set_attr "type" "str")
17775 (set_attr "memory" "store")
17776 (set_attr "mode" "HI")])
17778 (define_insn "*strsetqi_1"
17779 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17780 (match_operand:QI 2 "register_operand" "a"))
17781 (set (match_operand:SI 0 "register_operand" "=D")
17782 (plus:SI (match_dup 1)
17784 (use (reg:SI DIRFLAG_REG))]
17785 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17787 [(set_attr "type" "str")
17788 (set_attr "memory" "store")
17789 (set_attr "mode" "QI")])
17791 (define_insn "*strsetqi_rex_1"
17792 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17793 (match_operand:QI 2 "register_operand" "a"))
17794 (set (match_operand:DI 0 "register_operand" "=D")
17795 (plus:DI (match_dup 1)
17797 (use (reg:SI DIRFLAG_REG))]
17798 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17800 [(set_attr "type" "str")
17801 (set_attr "memory" "store")
17802 (set_attr "mode" "QI")])
17804 (define_expand "rep_stos"
17805 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17806 (set (match_operand 0 "register_operand" "")
17807 (match_operand 4 "" ""))
17808 (set (match_operand 2 "memory_operand" "") (const_int 0))
17809 (use (match_operand 3 "register_operand" ""))
17810 (use (match_dup 1))
17811 (use (reg:SI DIRFLAG_REG))])]
17815 (define_insn "*rep_stosdi_rex64"
17816 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17817 (set (match_operand:DI 0 "register_operand" "=D")
17818 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17820 (match_operand:DI 3 "register_operand" "0")))
17821 (set (mem:BLK (match_dup 3))
17823 (use (match_operand:DI 2 "register_operand" "a"))
17824 (use (match_dup 4))
17825 (use (reg:SI DIRFLAG_REG))]
17827 "{rep\;stosq|rep stosq}"
17828 [(set_attr "type" "str")
17829 (set_attr "prefix_rep" "1")
17830 (set_attr "memory" "store")
17831 (set_attr "mode" "DI")])
17833 (define_insn "*rep_stossi"
17834 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17835 (set (match_operand:SI 0 "register_operand" "=D")
17836 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17838 (match_operand:SI 3 "register_operand" "0")))
17839 (set (mem:BLK (match_dup 3))
17841 (use (match_operand:SI 2 "register_operand" "a"))
17842 (use (match_dup 4))
17843 (use (reg:SI DIRFLAG_REG))]
17845 "{rep\;stosl|rep stosd}"
17846 [(set_attr "type" "str")
17847 (set_attr "prefix_rep" "1")
17848 (set_attr "memory" "store")
17849 (set_attr "mode" "SI")])
17851 (define_insn "*rep_stossi_rex64"
17852 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17853 (set (match_operand:DI 0 "register_operand" "=D")
17854 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17856 (match_operand:DI 3 "register_operand" "0")))
17857 (set (mem:BLK (match_dup 3))
17859 (use (match_operand:SI 2 "register_operand" "a"))
17860 (use (match_dup 4))
17861 (use (reg:SI DIRFLAG_REG))]
17863 "{rep\;stosl|rep stosd}"
17864 [(set_attr "type" "str")
17865 (set_attr "prefix_rep" "1")
17866 (set_attr "memory" "store")
17867 (set_attr "mode" "SI")])
17869 (define_insn "*rep_stosqi"
17870 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17871 (set (match_operand:SI 0 "register_operand" "=D")
17872 (plus:SI (match_operand:SI 3 "register_operand" "0")
17873 (match_operand:SI 4 "register_operand" "1")))
17874 (set (mem:BLK (match_dup 3))
17876 (use (match_operand:QI 2 "register_operand" "a"))
17877 (use (match_dup 4))
17878 (use (reg:SI DIRFLAG_REG))]
17880 "{rep\;stosb|rep stosb}"
17881 [(set_attr "type" "str")
17882 (set_attr "prefix_rep" "1")
17883 (set_attr "memory" "store")
17884 (set_attr "mode" "QI")])
17886 (define_insn "*rep_stosqi_rex64"
17887 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17888 (set (match_operand:DI 0 "register_operand" "=D")
17889 (plus:DI (match_operand:DI 3 "register_operand" "0")
17890 (match_operand:DI 4 "register_operand" "1")))
17891 (set (mem:BLK (match_dup 3))
17893 (use (match_operand:QI 2 "register_operand" "a"))
17894 (use (match_dup 4))
17895 (use (reg:SI DIRFLAG_REG))]
17897 "{rep\;stosb|rep stosb}"
17898 [(set_attr "type" "str")
17899 (set_attr "prefix_rep" "1")
17900 (set_attr "memory" "store")
17901 (set_attr "mode" "QI")])
17903 (define_expand "cmpstrnsi"
17904 [(set (match_operand:SI 0 "register_operand" "")
17905 (compare:SI (match_operand:BLK 1 "general_operand" "")
17906 (match_operand:BLK 2 "general_operand" "")))
17907 (use (match_operand 3 "general_operand" ""))
17908 (use (match_operand 4 "immediate_operand" ""))]
17909 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17911 rtx addr1, addr2, out, outlow, count, countreg, align;
17913 /* Can't use this if the user has appropriated esi or edi. */
17914 if (global_regs[4] || global_regs[5])
17918 if (GET_CODE (out) != REG)
17919 out = gen_reg_rtx (SImode);
17921 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17922 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17923 if (addr1 != XEXP (operands[1], 0))
17924 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17925 if (addr2 != XEXP (operands[2], 0))
17926 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17928 count = operands[3];
17929 countreg = ix86_zero_extend_to_Pmode (count);
17931 /* %%% Iff we are testing strict equality, we can use known alignment
17932 to good advantage. This may be possible with combine, particularly
17933 once cc0 is dead. */
17934 align = operands[4];
17936 emit_insn (gen_cld ());
17937 if (GET_CODE (count) == CONST_INT)
17939 if (INTVAL (count) == 0)
17941 emit_move_insn (operands[0], const0_rtx);
17944 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17945 operands[1], operands[2]));
17950 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17952 emit_insn (gen_cmpsi_1 (countreg, countreg));
17953 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17954 operands[1], operands[2]));
17957 outlow = gen_lowpart (QImode, out);
17958 emit_insn (gen_cmpintqi (outlow));
17959 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17961 if (operands[0] != out)
17962 emit_move_insn (operands[0], out);
17967 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17969 (define_expand "cmpintqi"
17970 [(set (match_dup 1)
17971 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17973 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17974 (parallel [(set (match_operand:QI 0 "register_operand" "")
17975 (minus:QI (match_dup 1)
17977 (clobber (reg:CC FLAGS_REG))])]
17979 "operands[1] = gen_reg_rtx (QImode);
17980 operands[2] = gen_reg_rtx (QImode);")
17982 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17983 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17985 (define_expand "cmpstrnqi_nz_1"
17986 [(parallel [(set (reg:CC FLAGS_REG)
17987 (compare:CC (match_operand 4 "memory_operand" "")
17988 (match_operand 5 "memory_operand" "")))
17989 (use (match_operand 2 "register_operand" ""))
17990 (use (match_operand:SI 3 "immediate_operand" ""))
17991 (use (reg:SI DIRFLAG_REG))
17992 (clobber (match_operand 0 "register_operand" ""))
17993 (clobber (match_operand 1 "register_operand" ""))
17994 (clobber (match_dup 2))])]
17998 (define_insn "*cmpstrnqi_nz_1"
17999 [(set (reg:CC FLAGS_REG)
18000 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18001 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18002 (use (match_operand:SI 6 "register_operand" "2"))
18003 (use (match_operand:SI 3 "immediate_operand" "i"))
18004 (use (reg:SI DIRFLAG_REG))
18005 (clobber (match_operand:SI 0 "register_operand" "=S"))
18006 (clobber (match_operand:SI 1 "register_operand" "=D"))
18007 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18010 [(set_attr "type" "str")
18011 (set_attr "mode" "QI")
18012 (set_attr "prefix_rep" "1")])
18014 (define_insn "*cmpstrnqi_nz_rex_1"
18015 [(set (reg:CC FLAGS_REG)
18016 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18017 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18018 (use (match_operand:DI 6 "register_operand" "2"))
18019 (use (match_operand:SI 3 "immediate_operand" "i"))
18020 (use (reg:SI DIRFLAG_REG))
18021 (clobber (match_operand:DI 0 "register_operand" "=S"))
18022 (clobber (match_operand:DI 1 "register_operand" "=D"))
18023 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18026 [(set_attr "type" "str")
18027 (set_attr "mode" "QI")
18028 (set_attr "prefix_rep" "1")])
18030 ;; The same, but the count is not known to not be zero.
18032 (define_expand "cmpstrnqi_1"
18033 [(parallel [(set (reg:CC FLAGS_REG)
18034 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18036 (compare:CC (match_operand 4 "memory_operand" "")
18037 (match_operand 5 "memory_operand" ""))
18039 (use (match_operand:SI 3 "immediate_operand" ""))
18040 (use (reg:CC FLAGS_REG))
18041 (use (reg:SI DIRFLAG_REG))
18042 (clobber (match_operand 0 "register_operand" ""))
18043 (clobber (match_operand 1 "register_operand" ""))
18044 (clobber (match_dup 2))])]
18048 (define_insn "*cmpstrnqi_1"
18049 [(set (reg:CC FLAGS_REG)
18050 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18052 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18053 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18055 (use (match_operand:SI 3 "immediate_operand" "i"))
18056 (use (reg:CC FLAGS_REG))
18057 (use (reg:SI DIRFLAG_REG))
18058 (clobber (match_operand:SI 0 "register_operand" "=S"))
18059 (clobber (match_operand:SI 1 "register_operand" "=D"))
18060 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18063 [(set_attr "type" "str")
18064 (set_attr "mode" "QI")
18065 (set_attr "prefix_rep" "1")])
18067 (define_insn "*cmpstrnqi_rex_1"
18068 [(set (reg:CC FLAGS_REG)
18069 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18071 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18072 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18074 (use (match_operand:SI 3 "immediate_operand" "i"))
18075 (use (reg:CC FLAGS_REG))
18076 (use (reg:SI DIRFLAG_REG))
18077 (clobber (match_operand:DI 0 "register_operand" "=S"))
18078 (clobber (match_operand:DI 1 "register_operand" "=D"))
18079 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18082 [(set_attr "type" "str")
18083 (set_attr "mode" "QI")
18084 (set_attr "prefix_rep" "1")])
18086 (define_expand "strlensi"
18087 [(set (match_operand:SI 0 "register_operand" "")
18088 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18089 (match_operand:QI 2 "immediate_operand" "")
18090 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18093 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18099 (define_expand "strlendi"
18100 [(set (match_operand:DI 0 "register_operand" "")
18101 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18102 (match_operand:QI 2 "immediate_operand" "")
18103 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18106 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18112 (define_expand "strlenqi_1"
18113 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18114 (use (reg:SI DIRFLAG_REG))
18115 (clobber (match_operand 1 "register_operand" ""))
18116 (clobber (reg:CC FLAGS_REG))])]
18120 (define_insn "*strlenqi_1"
18121 [(set (match_operand:SI 0 "register_operand" "=&c")
18122 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18123 (match_operand:QI 2 "register_operand" "a")
18124 (match_operand:SI 3 "immediate_operand" "i")
18125 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18126 (use (reg:SI DIRFLAG_REG))
18127 (clobber (match_operand:SI 1 "register_operand" "=D"))
18128 (clobber (reg:CC FLAGS_REG))]
18131 [(set_attr "type" "str")
18132 (set_attr "mode" "QI")
18133 (set_attr "prefix_rep" "1")])
18135 (define_insn "*strlenqi_rex_1"
18136 [(set (match_operand:DI 0 "register_operand" "=&c")
18137 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18138 (match_operand:QI 2 "register_operand" "a")
18139 (match_operand:DI 3 "immediate_operand" "i")
18140 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18141 (use (reg:SI DIRFLAG_REG))
18142 (clobber (match_operand:DI 1 "register_operand" "=D"))
18143 (clobber (reg:CC FLAGS_REG))]
18146 [(set_attr "type" "str")
18147 (set_attr "mode" "QI")
18148 (set_attr "prefix_rep" "1")])
18150 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18151 ;; handled in combine, but it is not currently up to the task.
18152 ;; When used for their truth value, the cmpstrn* expanders generate
18161 ;; The intermediate three instructions are unnecessary.
18163 ;; This one handles cmpstrn*_nz_1...
18166 (set (reg:CC FLAGS_REG)
18167 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18168 (mem:BLK (match_operand 5 "register_operand" ""))))
18169 (use (match_operand 6 "register_operand" ""))
18170 (use (match_operand:SI 3 "immediate_operand" ""))
18171 (use (reg:SI DIRFLAG_REG))
18172 (clobber (match_operand 0 "register_operand" ""))
18173 (clobber (match_operand 1 "register_operand" ""))
18174 (clobber (match_operand 2 "register_operand" ""))])
18175 (set (match_operand:QI 7 "register_operand" "")
18176 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18177 (set (match_operand:QI 8 "register_operand" "")
18178 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18179 (set (reg FLAGS_REG)
18180 (compare (match_dup 7) (match_dup 8)))
18182 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18184 (set (reg:CC FLAGS_REG)
18185 (compare:CC (mem:BLK (match_dup 4))
18186 (mem:BLK (match_dup 5))))
18187 (use (match_dup 6))
18188 (use (match_dup 3))
18189 (use (reg:SI DIRFLAG_REG))
18190 (clobber (match_dup 0))
18191 (clobber (match_dup 1))
18192 (clobber (match_dup 2))])]
18195 ;; ...and this one handles cmpstrn*_1.
18198 (set (reg:CC FLAGS_REG)
18199 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18201 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18202 (mem:BLK (match_operand 5 "register_operand" "")))
18204 (use (match_operand:SI 3 "immediate_operand" ""))
18205 (use (reg:CC FLAGS_REG))
18206 (use (reg:SI DIRFLAG_REG))
18207 (clobber (match_operand 0 "register_operand" ""))
18208 (clobber (match_operand 1 "register_operand" ""))
18209 (clobber (match_operand 2 "register_operand" ""))])
18210 (set (match_operand:QI 7 "register_operand" "")
18211 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18212 (set (match_operand:QI 8 "register_operand" "")
18213 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18214 (set (reg FLAGS_REG)
18215 (compare (match_dup 7) (match_dup 8)))
18217 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18219 (set (reg:CC FLAGS_REG)
18220 (if_then_else:CC (ne (match_dup 6)
18222 (compare:CC (mem:BLK (match_dup 4))
18223 (mem:BLK (match_dup 5)))
18225 (use (match_dup 3))
18226 (use (reg:CC FLAGS_REG))
18227 (use (reg:SI DIRFLAG_REG))
18228 (clobber (match_dup 0))
18229 (clobber (match_dup 1))
18230 (clobber (match_dup 2))])]
18235 ;; Conditional move instructions.
18237 (define_expand "movdicc"
18238 [(set (match_operand:DI 0 "register_operand" "")
18239 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18240 (match_operand:DI 2 "general_operand" "")
18241 (match_operand:DI 3 "general_operand" "")))]
18243 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18245 (define_insn "x86_movdicc_0_m1_rex64"
18246 [(set (match_operand:DI 0 "register_operand" "=r")
18247 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18250 (clobber (reg:CC FLAGS_REG))]
18253 ; Since we don't have the proper number of operands for an alu insn,
18254 ; fill in all the blanks.
18255 [(set_attr "type" "alu")
18256 (set_attr "pent_pair" "pu")
18257 (set_attr "memory" "none")
18258 (set_attr "imm_disp" "false")
18259 (set_attr "mode" "DI")
18260 (set_attr "length_immediate" "0")])
18262 (define_insn "*movdicc_c_rex64"
18263 [(set (match_operand:DI 0 "register_operand" "=r,r")
18264 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18265 [(reg FLAGS_REG) (const_int 0)])
18266 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18267 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18268 "TARGET_64BIT && TARGET_CMOVE
18269 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18271 cmov%O2%C1\t{%2, %0|%0, %2}
18272 cmov%O2%c1\t{%3, %0|%0, %3}"
18273 [(set_attr "type" "icmov")
18274 (set_attr "mode" "DI")])
18276 (define_expand "movsicc"
18277 [(set (match_operand:SI 0 "register_operand" "")
18278 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18279 (match_operand:SI 2 "general_operand" "")
18280 (match_operand:SI 3 "general_operand" "")))]
18282 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18284 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18285 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18286 ;; So just document what we're doing explicitly.
18288 (define_insn "x86_movsicc_0_m1"
18289 [(set (match_operand:SI 0 "register_operand" "=r")
18290 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18293 (clobber (reg:CC FLAGS_REG))]
18296 ; Since we don't have the proper number of operands for an alu insn,
18297 ; fill in all the blanks.
18298 [(set_attr "type" "alu")
18299 (set_attr "pent_pair" "pu")
18300 (set_attr "memory" "none")
18301 (set_attr "imm_disp" "false")
18302 (set_attr "mode" "SI")
18303 (set_attr "length_immediate" "0")])
18305 (define_insn "*movsicc_noc"
18306 [(set (match_operand:SI 0 "register_operand" "=r,r")
18307 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18308 [(reg FLAGS_REG) (const_int 0)])
18309 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18310 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18312 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18314 cmov%O2%C1\t{%2, %0|%0, %2}
18315 cmov%O2%c1\t{%3, %0|%0, %3}"
18316 [(set_attr "type" "icmov")
18317 (set_attr "mode" "SI")])
18319 (define_expand "movhicc"
18320 [(set (match_operand:HI 0 "register_operand" "")
18321 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18322 (match_operand:HI 2 "general_operand" "")
18323 (match_operand:HI 3 "general_operand" "")))]
18324 "TARGET_HIMODE_MATH"
18325 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18327 (define_insn "*movhicc_noc"
18328 [(set (match_operand:HI 0 "register_operand" "=r,r")
18329 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18330 [(reg FLAGS_REG) (const_int 0)])
18331 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18332 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18334 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18336 cmov%O2%C1\t{%2, %0|%0, %2}
18337 cmov%O2%c1\t{%3, %0|%0, %3}"
18338 [(set_attr "type" "icmov")
18339 (set_attr "mode" "HI")])
18341 (define_expand "movqicc"
18342 [(set (match_operand:QI 0 "register_operand" "")
18343 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18344 (match_operand:QI 2 "general_operand" "")
18345 (match_operand:QI 3 "general_operand" "")))]
18346 "TARGET_QIMODE_MATH"
18347 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18349 (define_insn_and_split "*movqicc_noc"
18350 [(set (match_operand:QI 0 "register_operand" "=r,r")
18351 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18352 [(match_operand 4 "flags_reg_operand" "")
18354 (match_operand:QI 2 "register_operand" "r,0")
18355 (match_operand:QI 3 "register_operand" "0,r")))]
18356 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18358 "&& reload_completed"
18359 [(set (match_dup 0)
18360 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18363 "operands[0] = gen_lowpart (SImode, operands[0]);
18364 operands[2] = gen_lowpart (SImode, operands[2]);
18365 operands[3] = gen_lowpart (SImode, operands[3]);"
18366 [(set_attr "type" "icmov")
18367 (set_attr "mode" "SI")])
18369 (define_expand "movsfcc"
18370 [(set (match_operand:SF 0 "register_operand" "")
18371 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18372 (match_operand:SF 2 "register_operand" "")
18373 (match_operand:SF 3 "register_operand" "")))]
18374 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18375 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18377 (define_insn "*movsfcc_1_387"
18378 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18379 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18380 [(reg FLAGS_REG) (const_int 0)])
18381 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18382 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18383 "TARGET_80387 && TARGET_CMOVE
18384 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18386 fcmov%F1\t{%2, %0|%0, %2}
18387 fcmov%f1\t{%3, %0|%0, %3}
18388 cmov%O2%C1\t{%2, %0|%0, %2}
18389 cmov%O2%c1\t{%3, %0|%0, %3}"
18390 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18391 (set_attr "mode" "SF,SF,SI,SI")])
18393 (define_expand "movdfcc"
18394 [(set (match_operand:DF 0 "register_operand" "")
18395 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18396 (match_operand:DF 2 "register_operand" "")
18397 (match_operand:DF 3 "register_operand" "")))]
18398 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18399 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18401 (define_insn "*movdfcc_1"
18402 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18403 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18404 [(reg FLAGS_REG) (const_int 0)])
18405 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18406 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18407 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18408 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18410 fcmov%F1\t{%2, %0|%0, %2}
18411 fcmov%f1\t{%3, %0|%0, %3}
18414 [(set_attr "type" "fcmov,fcmov,multi,multi")
18415 (set_attr "mode" "DF")])
18417 (define_insn "*movdfcc_1_rex64"
18418 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18419 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18420 [(reg FLAGS_REG) (const_int 0)])
18421 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18422 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18423 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18424 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18426 fcmov%F1\t{%2, %0|%0, %2}
18427 fcmov%f1\t{%3, %0|%0, %3}
18428 cmov%O2%C1\t{%2, %0|%0, %2}
18429 cmov%O2%c1\t{%3, %0|%0, %3}"
18430 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18431 (set_attr "mode" "DF")])
18434 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18435 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18436 [(match_operand 4 "flags_reg_operand" "")
18438 (match_operand:DF 2 "nonimmediate_operand" "")
18439 (match_operand:DF 3 "nonimmediate_operand" "")))]
18440 "!TARGET_64BIT && reload_completed"
18441 [(set (match_dup 2)
18442 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18446 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18449 "split_di (operands+2, 1, operands+5, operands+6);
18450 split_di (operands+3, 1, operands+7, operands+8);
18451 split_di (operands, 1, operands+2, operands+3);")
18453 (define_expand "movxfcc"
18454 [(set (match_operand:XF 0 "register_operand" "")
18455 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18456 (match_operand:XF 2 "register_operand" "")
18457 (match_operand:XF 3 "register_operand" "")))]
18458 "TARGET_80387 && TARGET_CMOVE"
18459 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18461 (define_insn "*movxfcc_1"
18462 [(set (match_operand:XF 0 "register_operand" "=f,f")
18463 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18464 [(reg FLAGS_REG) (const_int 0)])
18465 (match_operand:XF 2 "register_operand" "f,0")
18466 (match_operand:XF 3 "register_operand" "0,f")))]
18467 "TARGET_80387 && TARGET_CMOVE"
18469 fcmov%F1\t{%2, %0|%0, %2}
18470 fcmov%f1\t{%3, %0|%0, %3}"
18471 [(set_attr "type" "fcmov")
18472 (set_attr "mode" "XF")])
18474 ;; These versions of the min/max patterns are intentionally ignorant of
18475 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18476 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18477 ;; are undefined in this condition, we're certain this is correct.
18479 (define_insn "sminsf3"
18480 [(set (match_operand:SF 0 "register_operand" "=x")
18481 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18482 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18484 "minss\t{%2, %0|%0, %2}"
18485 [(set_attr "type" "sseadd")
18486 (set_attr "mode" "SF")])
18488 (define_insn "smaxsf3"
18489 [(set (match_operand:SF 0 "register_operand" "=x")
18490 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18491 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18493 "maxss\t{%2, %0|%0, %2}"
18494 [(set_attr "type" "sseadd")
18495 (set_attr "mode" "SF")])
18497 (define_insn "smindf3"
18498 [(set (match_operand:DF 0 "register_operand" "=x")
18499 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18500 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18501 "TARGET_SSE2 && TARGET_SSE_MATH"
18502 "minsd\t{%2, %0|%0, %2}"
18503 [(set_attr "type" "sseadd")
18504 (set_attr "mode" "DF")])
18506 (define_insn "smaxdf3"
18507 [(set (match_operand:DF 0 "register_operand" "=x")
18508 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18509 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18510 "TARGET_SSE2 && TARGET_SSE_MATH"
18511 "maxsd\t{%2, %0|%0, %2}"
18512 [(set_attr "type" "sseadd")
18513 (set_attr "mode" "DF")])
18515 ;; These versions of the min/max patterns implement exactly the operations
18516 ;; min = (op1 < op2 ? op1 : op2)
18517 ;; max = (!(op1 < op2) ? op1 : op2)
18518 ;; Their operands are not commutative, and thus they may be used in the
18519 ;; presence of -0.0 and NaN.
18521 (define_insn "*ieee_sminsf3"
18522 [(set (match_operand:SF 0 "register_operand" "=x")
18523 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18524 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18527 "minss\t{%2, %0|%0, %2}"
18528 [(set_attr "type" "sseadd")
18529 (set_attr "mode" "SF")])
18531 (define_insn "*ieee_smaxsf3"
18532 [(set (match_operand:SF 0 "register_operand" "=x")
18533 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18534 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18537 "maxss\t{%2, %0|%0, %2}"
18538 [(set_attr "type" "sseadd")
18539 (set_attr "mode" "SF")])
18541 (define_insn "*ieee_smindf3"
18542 [(set (match_operand:DF 0 "register_operand" "=x")
18543 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18544 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18546 "TARGET_SSE2 && TARGET_SSE_MATH"
18547 "minsd\t{%2, %0|%0, %2}"
18548 [(set_attr "type" "sseadd")
18549 (set_attr "mode" "DF")])
18551 (define_insn "*ieee_smaxdf3"
18552 [(set (match_operand:DF 0 "register_operand" "=x")
18553 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18554 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18556 "TARGET_SSE2 && TARGET_SSE_MATH"
18557 "maxsd\t{%2, %0|%0, %2}"
18558 [(set_attr "type" "sseadd")
18559 (set_attr "mode" "DF")])
18561 ;; Conditional addition patterns
18562 (define_expand "addqicc"
18563 [(match_operand:QI 0 "register_operand" "")
18564 (match_operand 1 "comparison_operator" "")
18565 (match_operand:QI 2 "register_operand" "")
18566 (match_operand:QI 3 "const_int_operand" "")]
18568 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18570 (define_expand "addhicc"
18571 [(match_operand:HI 0 "register_operand" "")
18572 (match_operand 1 "comparison_operator" "")
18573 (match_operand:HI 2 "register_operand" "")
18574 (match_operand:HI 3 "const_int_operand" "")]
18576 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18578 (define_expand "addsicc"
18579 [(match_operand:SI 0 "register_operand" "")
18580 (match_operand 1 "comparison_operator" "")
18581 (match_operand:SI 2 "register_operand" "")
18582 (match_operand:SI 3 "const_int_operand" "")]
18584 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18586 (define_expand "adddicc"
18587 [(match_operand:DI 0 "register_operand" "")
18588 (match_operand 1 "comparison_operator" "")
18589 (match_operand:DI 2 "register_operand" "")
18590 (match_operand:DI 3 "const_int_operand" "")]
18592 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18595 ;; Misc patterns (?)
18597 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18598 ;; Otherwise there will be nothing to keep
18600 ;; [(set (reg ebp) (reg esp))]
18601 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18602 ;; (clobber (eflags)]
18603 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18605 ;; in proper program order.
18606 (define_insn "pro_epilogue_adjust_stack_1"
18607 [(set (match_operand:SI 0 "register_operand" "=r,r")
18608 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18609 (match_operand:SI 2 "immediate_operand" "i,i")))
18610 (clobber (reg:CC FLAGS_REG))
18611 (clobber (mem:BLK (scratch)))]
18614 switch (get_attr_type (insn))
18617 return "mov{l}\t{%1, %0|%0, %1}";
18620 if (GET_CODE (operands[2]) == CONST_INT
18621 && (INTVAL (operands[2]) == 128
18622 || (INTVAL (operands[2]) < 0
18623 && INTVAL (operands[2]) != -128)))
18625 operands[2] = GEN_INT (-INTVAL (operands[2]));
18626 return "sub{l}\t{%2, %0|%0, %2}";
18628 return "add{l}\t{%2, %0|%0, %2}";
18631 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18632 return "lea{l}\t{%a2, %0|%0, %a2}";
18635 gcc_unreachable ();
18638 [(set (attr "type")
18639 (cond [(eq_attr "alternative" "0")
18640 (const_string "alu")
18641 (match_operand:SI 2 "const0_operand" "")
18642 (const_string "imov")
18644 (const_string "lea")))
18645 (set_attr "mode" "SI")])
18647 (define_insn "pro_epilogue_adjust_stack_rex64"
18648 [(set (match_operand:DI 0 "register_operand" "=r,r")
18649 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18650 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18651 (clobber (reg:CC FLAGS_REG))
18652 (clobber (mem:BLK (scratch)))]
18655 switch (get_attr_type (insn))
18658 return "mov{q}\t{%1, %0|%0, %1}";
18661 if (GET_CODE (operands[2]) == CONST_INT
18662 /* Avoid overflows. */
18663 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18664 && (INTVAL (operands[2]) == 128
18665 || (INTVAL (operands[2]) < 0
18666 && INTVAL (operands[2]) != -128)))
18668 operands[2] = GEN_INT (-INTVAL (operands[2]));
18669 return "sub{q}\t{%2, %0|%0, %2}";
18671 return "add{q}\t{%2, %0|%0, %2}";
18674 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18675 return "lea{q}\t{%a2, %0|%0, %a2}";
18678 gcc_unreachable ();
18681 [(set (attr "type")
18682 (cond [(eq_attr "alternative" "0")
18683 (const_string "alu")
18684 (match_operand:DI 2 "const0_operand" "")
18685 (const_string "imov")
18687 (const_string "lea")))
18688 (set_attr "mode" "DI")])
18690 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18691 [(set (match_operand:DI 0 "register_operand" "=r,r")
18692 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18693 (match_operand:DI 3 "immediate_operand" "i,i")))
18694 (use (match_operand:DI 2 "register_operand" "r,r"))
18695 (clobber (reg:CC FLAGS_REG))
18696 (clobber (mem:BLK (scratch)))]
18699 switch (get_attr_type (insn))
18702 return "add{q}\t{%2, %0|%0, %2}";
18705 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18706 return "lea{q}\t{%a2, %0|%0, %a2}";
18709 gcc_unreachable ();
18712 [(set_attr "type" "alu,lea")
18713 (set_attr "mode" "DI")])
18715 (define_expand "allocate_stack_worker"
18716 [(match_operand:SI 0 "register_operand" "")]
18717 "TARGET_STACK_PROBE"
18719 if (reload_completed)
18722 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18724 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18729 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18731 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18736 (define_insn "allocate_stack_worker_1"
18737 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18738 UNSPECV_STACK_PROBE)
18739 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18740 (clobber (match_scratch:SI 1 "=0"))
18741 (clobber (reg:CC FLAGS_REG))]
18742 "!TARGET_64BIT && TARGET_STACK_PROBE"
18744 [(set_attr "type" "multi")
18745 (set_attr "length" "5")])
18747 (define_expand "allocate_stack_worker_postreload"
18748 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18749 UNSPECV_STACK_PROBE)
18750 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18751 (clobber (match_dup 0))
18752 (clobber (reg:CC FLAGS_REG))])]
18756 (define_insn "allocate_stack_worker_rex64"
18757 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18758 UNSPECV_STACK_PROBE)
18759 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18760 (clobber (match_scratch:DI 1 "=0"))
18761 (clobber (reg:CC FLAGS_REG))]
18762 "TARGET_64BIT && TARGET_STACK_PROBE"
18764 [(set_attr "type" "multi")
18765 (set_attr "length" "5")])
18767 (define_expand "allocate_stack_worker_rex64_postreload"
18768 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18769 UNSPECV_STACK_PROBE)
18770 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18771 (clobber (match_dup 0))
18772 (clobber (reg:CC FLAGS_REG))])]
18776 (define_expand "allocate_stack"
18777 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18778 (minus:SI (reg:SI SP_REG)
18779 (match_operand:SI 1 "general_operand" "")))
18780 (clobber (reg:CC FLAGS_REG))])
18781 (parallel [(set (reg:SI SP_REG)
18782 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18783 (clobber (reg:CC FLAGS_REG))])]
18784 "TARGET_STACK_PROBE"
18786 #ifdef CHECK_STACK_LIMIT
18787 if (GET_CODE (operands[1]) == CONST_INT
18788 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18789 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18793 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18796 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18800 (define_expand "builtin_setjmp_receiver"
18801 [(label_ref (match_operand 0 "" ""))]
18802 "!TARGET_64BIT && flag_pic"
18804 emit_insn (gen_set_got (pic_offset_table_rtx));
18808 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18811 [(set (match_operand 0 "register_operand" "")
18812 (match_operator 3 "promotable_binary_operator"
18813 [(match_operand 1 "register_operand" "")
18814 (match_operand 2 "aligned_operand" "")]))
18815 (clobber (reg:CC FLAGS_REG))]
18816 "! TARGET_PARTIAL_REG_STALL && reload_completed
18817 && ((GET_MODE (operands[0]) == HImode
18818 && ((!optimize_size && !TARGET_FAST_PREFIX)
18819 || GET_CODE (operands[2]) != CONST_INT
18820 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18821 || (GET_MODE (operands[0]) == QImode
18822 && (TARGET_PROMOTE_QImode || optimize_size)))"
18823 [(parallel [(set (match_dup 0)
18824 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18825 (clobber (reg:CC FLAGS_REG))])]
18826 "operands[0] = gen_lowpart (SImode, operands[0]);
18827 operands[1] = gen_lowpart (SImode, operands[1]);
18828 if (GET_CODE (operands[3]) != ASHIFT)
18829 operands[2] = gen_lowpart (SImode, operands[2]);
18830 PUT_MODE (operands[3], SImode);")
18832 ; Promote the QImode tests, as i386 has encoding of the AND
18833 ; instruction with 32-bit sign-extended immediate and thus the
18834 ; instruction size is unchanged, except in the %eax case for
18835 ; which it is increased by one byte, hence the ! optimize_size.
18837 [(set (match_operand 0 "flags_reg_operand" "")
18838 (match_operator 2 "compare_operator"
18839 [(and (match_operand 3 "aligned_operand" "")
18840 (match_operand 4 "const_int_operand" ""))
18842 (set (match_operand 1 "register_operand" "")
18843 (and (match_dup 3) (match_dup 4)))]
18844 "! TARGET_PARTIAL_REG_STALL && reload_completed
18845 /* Ensure that the operand will remain sign-extended immediate. */
18846 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18848 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18849 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18850 [(parallel [(set (match_dup 0)
18851 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18854 (and:SI (match_dup 3) (match_dup 4)))])]
18857 = gen_int_mode (INTVAL (operands[4])
18858 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18859 operands[1] = gen_lowpart (SImode, operands[1]);
18860 operands[3] = gen_lowpart (SImode, operands[3]);
18863 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18864 ; the TEST instruction with 32-bit sign-extended immediate and thus
18865 ; the instruction size would at least double, which is not what we
18866 ; want even with ! optimize_size.
18868 [(set (match_operand 0 "flags_reg_operand" "")
18869 (match_operator 1 "compare_operator"
18870 [(and (match_operand:HI 2 "aligned_operand" "")
18871 (match_operand:HI 3 "const_int_operand" ""))
18873 "! TARGET_PARTIAL_REG_STALL && reload_completed
18874 /* Ensure that the operand will remain sign-extended immediate. */
18875 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18876 && ! TARGET_FAST_PREFIX
18877 && ! optimize_size"
18878 [(set (match_dup 0)
18879 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18883 = gen_int_mode (INTVAL (operands[3])
18884 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18885 operands[2] = gen_lowpart (SImode, operands[2]);
18889 [(set (match_operand 0 "register_operand" "")
18890 (neg (match_operand 1 "register_operand" "")))
18891 (clobber (reg:CC FLAGS_REG))]
18892 "! TARGET_PARTIAL_REG_STALL && reload_completed
18893 && (GET_MODE (operands[0]) == HImode
18894 || (GET_MODE (operands[0]) == QImode
18895 && (TARGET_PROMOTE_QImode || optimize_size)))"
18896 [(parallel [(set (match_dup 0)
18897 (neg:SI (match_dup 1)))
18898 (clobber (reg:CC FLAGS_REG))])]
18899 "operands[0] = gen_lowpart (SImode, operands[0]);
18900 operands[1] = gen_lowpart (SImode, operands[1]);")
18903 [(set (match_operand 0 "register_operand" "")
18904 (not (match_operand 1 "register_operand" "")))]
18905 "! TARGET_PARTIAL_REG_STALL && reload_completed
18906 && (GET_MODE (operands[0]) == HImode
18907 || (GET_MODE (operands[0]) == QImode
18908 && (TARGET_PROMOTE_QImode || optimize_size)))"
18909 [(set (match_dup 0)
18910 (not:SI (match_dup 1)))]
18911 "operands[0] = gen_lowpart (SImode, operands[0]);
18912 operands[1] = gen_lowpart (SImode, operands[1]);")
18915 [(set (match_operand 0 "register_operand" "")
18916 (if_then_else (match_operator 1 "comparison_operator"
18917 [(reg FLAGS_REG) (const_int 0)])
18918 (match_operand 2 "register_operand" "")
18919 (match_operand 3 "register_operand" "")))]
18920 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18921 && (GET_MODE (operands[0]) == HImode
18922 || (GET_MODE (operands[0]) == QImode
18923 && (TARGET_PROMOTE_QImode || optimize_size)))"
18924 [(set (match_dup 0)
18925 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18926 "operands[0] = gen_lowpart (SImode, operands[0]);
18927 operands[2] = gen_lowpart (SImode, operands[2]);
18928 operands[3] = gen_lowpart (SImode, operands[3]);")
18931 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18932 ;; transform a complex memory operation into two memory to register operations.
18934 ;; Don't push memory operands
18936 [(set (match_operand:SI 0 "push_operand" "")
18937 (match_operand:SI 1 "memory_operand" ""))
18938 (match_scratch:SI 2 "r")]
18939 "!optimize_size && !TARGET_PUSH_MEMORY
18940 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18941 [(set (match_dup 2) (match_dup 1))
18942 (set (match_dup 0) (match_dup 2))]
18946 [(set (match_operand:DI 0 "push_operand" "")
18947 (match_operand:DI 1 "memory_operand" ""))
18948 (match_scratch:DI 2 "r")]
18949 "!optimize_size && !TARGET_PUSH_MEMORY
18950 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18951 [(set (match_dup 2) (match_dup 1))
18952 (set (match_dup 0) (match_dup 2))]
18955 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18958 [(set (match_operand:SF 0 "push_operand" "")
18959 (match_operand:SF 1 "memory_operand" ""))
18960 (match_scratch:SF 2 "r")]
18961 "!optimize_size && !TARGET_PUSH_MEMORY
18962 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18963 [(set (match_dup 2) (match_dup 1))
18964 (set (match_dup 0) (match_dup 2))]
18968 [(set (match_operand:HI 0 "push_operand" "")
18969 (match_operand:HI 1 "memory_operand" ""))
18970 (match_scratch:HI 2 "r")]
18971 "!optimize_size && !TARGET_PUSH_MEMORY
18972 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18973 [(set (match_dup 2) (match_dup 1))
18974 (set (match_dup 0) (match_dup 2))]
18978 [(set (match_operand:QI 0 "push_operand" "")
18979 (match_operand:QI 1 "memory_operand" ""))
18980 (match_scratch:QI 2 "q")]
18981 "!optimize_size && !TARGET_PUSH_MEMORY
18982 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18983 [(set (match_dup 2) (match_dup 1))
18984 (set (match_dup 0) (match_dup 2))]
18987 ;; Don't move an immediate directly to memory when the instruction
18990 [(match_scratch:SI 1 "r")
18991 (set (match_operand:SI 0 "memory_operand" "")
18994 && ! TARGET_USE_MOV0
18995 && TARGET_SPLIT_LONG_MOVES
18996 && get_attr_length (insn) >= ix86_cost->large_insn
18997 && peep2_regno_dead_p (0, FLAGS_REG)"
18998 [(parallel [(set (match_dup 1) (const_int 0))
18999 (clobber (reg:CC FLAGS_REG))])
19000 (set (match_dup 0) (match_dup 1))]
19004 [(match_scratch:HI 1 "r")
19005 (set (match_operand:HI 0 "memory_operand" "")
19008 && ! TARGET_USE_MOV0
19009 && TARGET_SPLIT_LONG_MOVES
19010 && get_attr_length (insn) >= ix86_cost->large_insn
19011 && peep2_regno_dead_p (0, FLAGS_REG)"
19012 [(parallel [(set (match_dup 2) (const_int 0))
19013 (clobber (reg:CC FLAGS_REG))])
19014 (set (match_dup 0) (match_dup 1))]
19015 "operands[2] = gen_lowpart (SImode, operands[1]);")
19018 [(match_scratch:QI 1 "q")
19019 (set (match_operand:QI 0 "memory_operand" "")
19022 && ! TARGET_USE_MOV0
19023 && TARGET_SPLIT_LONG_MOVES
19024 && get_attr_length (insn) >= ix86_cost->large_insn
19025 && peep2_regno_dead_p (0, FLAGS_REG)"
19026 [(parallel [(set (match_dup 2) (const_int 0))
19027 (clobber (reg:CC FLAGS_REG))])
19028 (set (match_dup 0) (match_dup 1))]
19029 "operands[2] = gen_lowpart (SImode, operands[1]);")
19032 [(match_scratch:SI 2 "r")
19033 (set (match_operand:SI 0 "memory_operand" "")
19034 (match_operand:SI 1 "immediate_operand" ""))]
19036 && get_attr_length (insn) >= ix86_cost->large_insn
19037 && TARGET_SPLIT_LONG_MOVES"
19038 [(set (match_dup 2) (match_dup 1))
19039 (set (match_dup 0) (match_dup 2))]
19043 [(match_scratch:HI 2 "r")
19044 (set (match_operand:HI 0 "memory_operand" "")
19045 (match_operand:HI 1 "immediate_operand" ""))]
19046 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19047 && TARGET_SPLIT_LONG_MOVES"
19048 [(set (match_dup 2) (match_dup 1))
19049 (set (match_dup 0) (match_dup 2))]
19053 [(match_scratch:QI 2 "q")
19054 (set (match_operand:QI 0 "memory_operand" "")
19055 (match_operand:QI 1 "immediate_operand" ""))]
19056 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19057 && TARGET_SPLIT_LONG_MOVES"
19058 [(set (match_dup 2) (match_dup 1))
19059 (set (match_dup 0) (match_dup 2))]
19062 ;; Don't compare memory with zero, load and use a test instead.
19064 [(set (match_operand 0 "flags_reg_operand" "")
19065 (match_operator 1 "compare_operator"
19066 [(match_operand:SI 2 "memory_operand" "")
19068 (match_scratch:SI 3 "r")]
19069 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19070 [(set (match_dup 3) (match_dup 2))
19071 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19074 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19075 ;; Don't split NOTs with a displacement operand, because resulting XOR
19076 ;; will not be pairable anyway.
19078 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19079 ;; represented using a modRM byte. The XOR replacement is long decoded,
19080 ;; so this split helps here as well.
19082 ;; Note: Can't do this as a regular split because we can't get proper
19083 ;; lifetime information then.
19086 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19087 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19089 && peep2_regno_dead_p (0, FLAGS_REG)
19090 && ((TARGET_PENTIUM
19091 && (GET_CODE (operands[0]) != MEM
19092 || !memory_displacement_operand (operands[0], SImode)))
19093 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19094 [(parallel [(set (match_dup 0)
19095 (xor:SI (match_dup 1) (const_int -1)))
19096 (clobber (reg:CC FLAGS_REG))])]
19100 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19101 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19103 && peep2_regno_dead_p (0, FLAGS_REG)
19104 && ((TARGET_PENTIUM
19105 && (GET_CODE (operands[0]) != MEM
19106 || !memory_displacement_operand (operands[0], HImode)))
19107 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19108 [(parallel [(set (match_dup 0)
19109 (xor:HI (match_dup 1) (const_int -1)))
19110 (clobber (reg:CC FLAGS_REG))])]
19114 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19115 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19117 && peep2_regno_dead_p (0, FLAGS_REG)
19118 && ((TARGET_PENTIUM
19119 && (GET_CODE (operands[0]) != MEM
19120 || !memory_displacement_operand (operands[0], QImode)))
19121 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19122 [(parallel [(set (match_dup 0)
19123 (xor:QI (match_dup 1) (const_int -1)))
19124 (clobber (reg:CC FLAGS_REG))])]
19127 ;; Non pairable "test imm, reg" instructions can be translated to
19128 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19129 ;; byte opcode instead of two, have a short form for byte operands),
19130 ;; so do it for other CPUs as well. Given that the value was dead,
19131 ;; this should not create any new dependencies. Pass on the sub-word
19132 ;; versions if we're concerned about partial register stalls.
19135 [(set (match_operand 0 "flags_reg_operand" "")
19136 (match_operator 1 "compare_operator"
19137 [(and:SI (match_operand:SI 2 "register_operand" "")
19138 (match_operand:SI 3 "immediate_operand" ""))
19140 "ix86_match_ccmode (insn, CCNOmode)
19141 && (true_regnum (operands[2]) != 0
19142 || (GET_CODE (operands[3]) == CONST_INT
19143 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19144 && peep2_reg_dead_p (1, operands[2])"
19146 [(set (match_dup 0)
19147 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19150 (and:SI (match_dup 2) (match_dup 3)))])]
19153 ;; We don't need to handle HImode case, because it will be promoted to SImode
19154 ;; on ! TARGET_PARTIAL_REG_STALL
19157 [(set (match_operand 0 "flags_reg_operand" "")
19158 (match_operator 1 "compare_operator"
19159 [(and:QI (match_operand:QI 2 "register_operand" "")
19160 (match_operand:QI 3 "immediate_operand" ""))
19162 "! TARGET_PARTIAL_REG_STALL
19163 && ix86_match_ccmode (insn, CCNOmode)
19164 && true_regnum (operands[2]) != 0
19165 && peep2_reg_dead_p (1, operands[2])"
19167 [(set (match_dup 0)
19168 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19171 (and:QI (match_dup 2) (match_dup 3)))])]
19175 [(set (match_operand 0 "flags_reg_operand" "")
19176 (match_operator 1 "compare_operator"
19179 (match_operand 2 "ext_register_operand" "")
19182 (match_operand 3 "const_int_operand" ""))
19184 "! TARGET_PARTIAL_REG_STALL
19185 && ix86_match_ccmode (insn, CCNOmode)
19186 && true_regnum (operands[2]) != 0
19187 && peep2_reg_dead_p (1, operands[2])"
19188 [(parallel [(set (match_dup 0)
19197 (set (zero_extract:SI (match_dup 2)
19208 ;; Don't do logical operations with memory inputs.
19210 [(match_scratch:SI 2 "r")
19211 (parallel [(set (match_operand:SI 0 "register_operand" "")
19212 (match_operator:SI 3 "arith_or_logical_operator"
19214 (match_operand:SI 1 "memory_operand" "")]))
19215 (clobber (reg:CC FLAGS_REG))])]
19216 "! optimize_size && ! TARGET_READ_MODIFY"
19217 [(set (match_dup 2) (match_dup 1))
19218 (parallel [(set (match_dup 0)
19219 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19220 (clobber (reg:CC FLAGS_REG))])]
19224 [(match_scratch:SI 2 "r")
19225 (parallel [(set (match_operand:SI 0 "register_operand" "")
19226 (match_operator:SI 3 "arith_or_logical_operator"
19227 [(match_operand:SI 1 "memory_operand" "")
19229 (clobber (reg:CC FLAGS_REG))])]
19230 "! optimize_size && ! TARGET_READ_MODIFY"
19231 [(set (match_dup 2) (match_dup 1))
19232 (parallel [(set (match_dup 0)
19233 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19234 (clobber (reg:CC FLAGS_REG))])]
19237 ; Don't do logical operations with memory outputs
19239 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19240 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19241 ; the same decoder scheduling characteristics as the original.
19244 [(match_scratch:SI 2 "r")
19245 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19246 (match_operator:SI 3 "arith_or_logical_operator"
19248 (match_operand:SI 1 "nonmemory_operand" "")]))
19249 (clobber (reg:CC FLAGS_REG))])]
19250 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19251 [(set (match_dup 2) (match_dup 0))
19252 (parallel [(set (match_dup 2)
19253 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19254 (clobber (reg:CC FLAGS_REG))])
19255 (set (match_dup 0) (match_dup 2))]
19259 [(match_scratch:SI 2 "r")
19260 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19261 (match_operator:SI 3 "arith_or_logical_operator"
19262 [(match_operand:SI 1 "nonmemory_operand" "")
19264 (clobber (reg:CC FLAGS_REG))])]
19265 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19266 [(set (match_dup 2) (match_dup 0))
19267 (parallel [(set (match_dup 2)
19268 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19269 (clobber (reg:CC FLAGS_REG))])
19270 (set (match_dup 0) (match_dup 2))]
19273 ;; Attempt to always use XOR for zeroing registers.
19275 [(set (match_operand 0 "register_operand" "")
19276 (match_operand 1 "const0_operand" ""))]
19277 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19278 && (! TARGET_USE_MOV0 || optimize_size)
19279 && GENERAL_REG_P (operands[0])
19280 && peep2_regno_dead_p (0, FLAGS_REG)"
19281 [(parallel [(set (match_dup 0) (const_int 0))
19282 (clobber (reg:CC FLAGS_REG))])]
19284 operands[0] = gen_lowpart (word_mode, operands[0]);
19288 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19290 "(GET_MODE (operands[0]) == QImode
19291 || GET_MODE (operands[0]) == HImode)
19292 && (! TARGET_USE_MOV0 || optimize_size)
19293 && peep2_regno_dead_p (0, FLAGS_REG)"
19294 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19295 (clobber (reg:CC FLAGS_REG))])])
19297 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19299 [(set (match_operand 0 "register_operand" "")
19301 "(GET_MODE (operands[0]) == HImode
19302 || GET_MODE (operands[0]) == SImode
19303 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19304 && (optimize_size || TARGET_PENTIUM)
19305 && peep2_regno_dead_p (0, FLAGS_REG)"
19306 [(parallel [(set (match_dup 0) (const_int -1))
19307 (clobber (reg:CC FLAGS_REG))])]
19308 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19311 ;; Attempt to convert simple leas to adds. These can be created by
19314 [(set (match_operand:SI 0 "register_operand" "")
19315 (plus:SI (match_dup 0)
19316 (match_operand:SI 1 "nonmemory_operand" "")))]
19317 "peep2_regno_dead_p (0, FLAGS_REG)"
19318 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19319 (clobber (reg:CC FLAGS_REG))])]
19323 [(set (match_operand:SI 0 "register_operand" "")
19324 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19325 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19326 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19327 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19328 (clobber (reg:CC FLAGS_REG))])]
19329 "operands[2] = gen_lowpart (SImode, operands[2]);")
19332 [(set (match_operand:DI 0 "register_operand" "")
19333 (plus:DI (match_dup 0)
19334 (match_operand:DI 1 "x86_64_general_operand" "")))]
19335 "peep2_regno_dead_p (0, FLAGS_REG)"
19336 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19337 (clobber (reg:CC FLAGS_REG))])]
19341 [(set (match_operand:SI 0 "register_operand" "")
19342 (mult:SI (match_dup 0)
19343 (match_operand:SI 1 "const_int_operand" "")))]
19344 "exact_log2 (INTVAL (operands[1])) >= 0
19345 && peep2_regno_dead_p (0, FLAGS_REG)"
19346 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19347 (clobber (reg:CC FLAGS_REG))])]
19348 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19351 [(set (match_operand:DI 0 "register_operand" "")
19352 (mult:DI (match_dup 0)
19353 (match_operand:DI 1 "const_int_operand" "")))]
19354 "exact_log2 (INTVAL (operands[1])) >= 0
19355 && peep2_regno_dead_p (0, FLAGS_REG)"
19356 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19357 (clobber (reg:CC FLAGS_REG))])]
19358 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19361 [(set (match_operand:SI 0 "register_operand" "")
19362 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19363 (match_operand:DI 2 "const_int_operand" "")) 0))]
19364 "exact_log2 (INTVAL (operands[2])) >= 0
19365 && REGNO (operands[0]) == REGNO (operands[1])
19366 && peep2_regno_dead_p (0, FLAGS_REG)"
19367 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19368 (clobber (reg:CC FLAGS_REG))])]
19369 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19371 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19372 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19373 ;; many CPUs it is also faster, since special hardware to avoid esp
19374 ;; dependencies is present.
19376 ;; While some of these conversions may be done using splitters, we use peepholes
19377 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19379 ;; Convert prologue esp subtractions to push.
19380 ;; We need register to push. In order to keep verify_flow_info happy we have
19382 ;; - use scratch and clobber it in order to avoid dependencies
19383 ;; - use already live register
19384 ;; We can't use the second way right now, since there is no reliable way how to
19385 ;; verify that given register is live. First choice will also most likely in
19386 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19387 ;; call clobbered registers are dead. We may want to use base pointer as an
19388 ;; alternative when no register is available later.
19391 [(match_scratch:SI 0 "r")
19392 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19393 (clobber (reg:CC FLAGS_REG))
19394 (clobber (mem:BLK (scratch)))])]
19395 "optimize_size || !TARGET_SUB_ESP_4"
19396 [(clobber (match_dup 0))
19397 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19398 (clobber (mem:BLK (scratch)))])])
19401 [(match_scratch:SI 0 "r")
19402 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19403 (clobber (reg:CC FLAGS_REG))
19404 (clobber (mem:BLK (scratch)))])]
19405 "optimize_size || !TARGET_SUB_ESP_8"
19406 [(clobber (match_dup 0))
19407 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19408 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19409 (clobber (mem:BLK (scratch)))])])
19411 ;; Convert esp subtractions to push.
19413 [(match_scratch:SI 0 "r")
19414 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19415 (clobber (reg:CC FLAGS_REG))])]
19416 "optimize_size || !TARGET_SUB_ESP_4"
19417 [(clobber (match_dup 0))
19418 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19421 [(match_scratch:SI 0 "r")
19422 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19423 (clobber (reg:CC FLAGS_REG))])]
19424 "optimize_size || !TARGET_SUB_ESP_8"
19425 [(clobber (match_dup 0))
19426 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19427 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19429 ;; Convert epilogue deallocator to pop.
19431 [(match_scratch:SI 0 "r")
19432 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19433 (clobber (reg:CC FLAGS_REG))
19434 (clobber (mem:BLK (scratch)))])]
19435 "optimize_size || !TARGET_ADD_ESP_4"
19436 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19437 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19438 (clobber (mem:BLK (scratch)))])]
19441 ;; Two pops case is tricky, since pop causes dependency on destination register.
19442 ;; We use two registers if available.
19444 [(match_scratch:SI 0 "r")
19445 (match_scratch:SI 1 "r")
19446 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19447 (clobber (reg:CC FLAGS_REG))
19448 (clobber (mem:BLK (scratch)))])]
19449 "optimize_size || !TARGET_ADD_ESP_8"
19450 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19451 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19452 (clobber (mem:BLK (scratch)))])
19453 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19454 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19458 [(match_scratch:SI 0 "r")
19459 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19460 (clobber (reg:CC FLAGS_REG))
19461 (clobber (mem:BLK (scratch)))])]
19463 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19464 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19465 (clobber (mem:BLK (scratch)))])
19466 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19467 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19470 ;; Convert esp additions to pop.
19472 [(match_scratch:SI 0 "r")
19473 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19474 (clobber (reg:CC FLAGS_REG))])]
19476 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19477 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19480 ;; Two pops case is tricky, since pop causes dependency on destination register.
19481 ;; We use two registers if available.
19483 [(match_scratch:SI 0 "r")
19484 (match_scratch:SI 1 "r")
19485 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19486 (clobber (reg:CC FLAGS_REG))])]
19488 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19489 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19490 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19491 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19495 [(match_scratch:SI 0 "r")
19496 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19497 (clobber (reg:CC FLAGS_REG))])]
19499 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19500 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19501 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19502 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19505 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19506 ;; required and register dies. Similarly for 128 to plus -128.
19508 [(set (match_operand 0 "flags_reg_operand" "")
19509 (match_operator 1 "compare_operator"
19510 [(match_operand 2 "register_operand" "")
19511 (match_operand 3 "const_int_operand" "")]))]
19512 "(INTVAL (operands[3]) == -1
19513 || INTVAL (operands[3]) == 1
19514 || INTVAL (operands[3]) == 128)
19515 && ix86_match_ccmode (insn, CCGCmode)
19516 && peep2_reg_dead_p (1, operands[2])"
19517 [(parallel [(set (match_dup 0)
19518 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19519 (clobber (match_dup 2))])]
19523 [(match_scratch:DI 0 "r")
19524 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19525 (clobber (reg:CC FLAGS_REG))
19526 (clobber (mem:BLK (scratch)))])]
19527 "optimize_size || !TARGET_SUB_ESP_4"
19528 [(clobber (match_dup 0))
19529 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19530 (clobber (mem:BLK (scratch)))])])
19533 [(match_scratch:DI 0 "r")
19534 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19535 (clobber (reg:CC FLAGS_REG))
19536 (clobber (mem:BLK (scratch)))])]
19537 "optimize_size || !TARGET_SUB_ESP_8"
19538 [(clobber (match_dup 0))
19539 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19540 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19541 (clobber (mem:BLK (scratch)))])])
19543 ;; Convert esp subtractions to push.
19545 [(match_scratch:DI 0 "r")
19546 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19547 (clobber (reg:CC FLAGS_REG))])]
19548 "optimize_size || !TARGET_SUB_ESP_4"
19549 [(clobber (match_dup 0))
19550 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19553 [(match_scratch:DI 0 "r")
19554 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19555 (clobber (reg:CC FLAGS_REG))])]
19556 "optimize_size || !TARGET_SUB_ESP_8"
19557 [(clobber (match_dup 0))
19558 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19559 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19561 ;; Convert epilogue deallocator to pop.
19563 [(match_scratch:DI 0 "r")
19564 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19565 (clobber (reg:CC FLAGS_REG))
19566 (clobber (mem:BLK (scratch)))])]
19567 "optimize_size || !TARGET_ADD_ESP_4"
19568 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19569 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19570 (clobber (mem:BLK (scratch)))])]
19573 ;; Two pops case is tricky, since pop causes dependency on destination register.
19574 ;; We use two registers if available.
19576 [(match_scratch:DI 0 "r")
19577 (match_scratch:DI 1 "r")
19578 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19579 (clobber (reg:CC FLAGS_REG))
19580 (clobber (mem:BLK (scratch)))])]
19581 "optimize_size || !TARGET_ADD_ESP_8"
19582 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19583 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19584 (clobber (mem:BLK (scratch)))])
19585 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19586 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19590 [(match_scratch:DI 0 "r")
19591 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19592 (clobber (reg:CC FLAGS_REG))
19593 (clobber (mem:BLK (scratch)))])]
19595 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19596 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19597 (clobber (mem:BLK (scratch)))])
19598 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19599 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19602 ;; Convert esp additions to pop.
19604 [(match_scratch:DI 0 "r")
19605 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19606 (clobber (reg:CC FLAGS_REG))])]
19608 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19609 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19612 ;; Two pops case is tricky, since pop causes dependency on destination register.
19613 ;; We use two registers if available.
19615 [(match_scratch:DI 0 "r")
19616 (match_scratch:DI 1 "r")
19617 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19618 (clobber (reg:CC FLAGS_REG))])]
19620 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19621 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19622 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19623 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19627 [(match_scratch:DI 0 "r")
19628 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19629 (clobber (reg:CC FLAGS_REG))])]
19631 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19632 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19633 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19634 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19637 ;; Convert imul by three, five and nine into lea
19640 [(set (match_operand:SI 0 "register_operand" "")
19641 (mult:SI (match_operand:SI 1 "register_operand" "")
19642 (match_operand:SI 2 "const_int_operand" "")))
19643 (clobber (reg:CC FLAGS_REG))])]
19644 "INTVAL (operands[2]) == 3
19645 || INTVAL (operands[2]) == 5
19646 || INTVAL (operands[2]) == 9"
19647 [(set (match_dup 0)
19648 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19650 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19654 [(set (match_operand:SI 0 "register_operand" "")
19655 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19656 (match_operand:SI 2 "const_int_operand" "")))
19657 (clobber (reg:CC FLAGS_REG))])]
19659 && (INTVAL (operands[2]) == 3
19660 || INTVAL (operands[2]) == 5
19661 || INTVAL (operands[2]) == 9)"
19662 [(set (match_dup 0) (match_dup 1))
19664 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19666 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19670 [(set (match_operand:DI 0 "register_operand" "")
19671 (mult:DI (match_operand:DI 1 "register_operand" "")
19672 (match_operand:DI 2 "const_int_operand" "")))
19673 (clobber (reg:CC FLAGS_REG))])]
19675 && (INTVAL (operands[2]) == 3
19676 || INTVAL (operands[2]) == 5
19677 || INTVAL (operands[2]) == 9)"
19678 [(set (match_dup 0)
19679 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19681 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19685 [(set (match_operand:DI 0 "register_operand" "")
19686 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19687 (match_operand:DI 2 "const_int_operand" "")))
19688 (clobber (reg:CC FLAGS_REG))])]
19691 && (INTVAL (operands[2]) == 3
19692 || INTVAL (operands[2]) == 5
19693 || INTVAL (operands[2]) == 9)"
19694 [(set (match_dup 0) (match_dup 1))
19696 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19698 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19700 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19701 ;; imul $32bit_imm, reg, reg is direct decoded.
19703 [(match_scratch:DI 3 "r")
19704 (parallel [(set (match_operand:DI 0 "register_operand" "")
19705 (mult:DI (match_operand:DI 1 "memory_operand" "")
19706 (match_operand:DI 2 "immediate_operand" "")))
19707 (clobber (reg:CC FLAGS_REG))])]
19708 "TARGET_K8 && !optimize_size
19709 && (GET_CODE (operands[2]) != CONST_INT
19710 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19711 [(set (match_dup 3) (match_dup 1))
19712 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19713 (clobber (reg:CC FLAGS_REG))])]
19717 [(match_scratch:SI 3 "r")
19718 (parallel [(set (match_operand:SI 0 "register_operand" "")
19719 (mult:SI (match_operand:SI 1 "memory_operand" "")
19720 (match_operand:SI 2 "immediate_operand" "")))
19721 (clobber (reg:CC FLAGS_REG))])]
19722 "TARGET_K8 && !optimize_size
19723 && (GET_CODE (operands[2]) != CONST_INT
19724 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19725 [(set (match_dup 3) (match_dup 1))
19726 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19727 (clobber (reg:CC FLAGS_REG))])]
19731 [(match_scratch:SI 3 "r")
19732 (parallel [(set (match_operand:DI 0 "register_operand" "")
19734 (mult:SI (match_operand:SI 1 "memory_operand" "")
19735 (match_operand:SI 2 "immediate_operand" ""))))
19736 (clobber (reg:CC FLAGS_REG))])]
19737 "TARGET_K8 && !optimize_size
19738 && (GET_CODE (operands[2]) != CONST_INT
19739 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19740 [(set (match_dup 3) (match_dup 1))
19741 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19742 (clobber (reg:CC FLAGS_REG))])]
19745 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19746 ;; Convert it into imul reg, reg
19747 ;; It would be better to force assembler to encode instruction using long
19748 ;; immediate, but there is apparently no way to do so.
19750 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19751 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19752 (match_operand:DI 2 "const_int_operand" "")))
19753 (clobber (reg:CC FLAGS_REG))])
19754 (match_scratch:DI 3 "r")]
19755 "TARGET_K8 && !optimize_size
19756 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19757 [(set (match_dup 3) (match_dup 2))
19758 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19759 (clobber (reg:CC FLAGS_REG))])]
19761 if (!rtx_equal_p (operands[0], operands[1]))
19762 emit_move_insn (operands[0], operands[1]);
19766 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19767 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19768 (match_operand:SI 2 "const_int_operand" "")))
19769 (clobber (reg:CC FLAGS_REG))])
19770 (match_scratch:SI 3 "r")]
19771 "TARGET_K8 && !optimize_size
19772 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19773 [(set (match_dup 3) (match_dup 2))
19774 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19775 (clobber (reg:CC FLAGS_REG))])]
19777 if (!rtx_equal_p (operands[0], operands[1]))
19778 emit_move_insn (operands[0], operands[1]);
19782 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19783 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19784 (match_operand:HI 2 "immediate_operand" "")))
19785 (clobber (reg:CC FLAGS_REG))])
19786 (match_scratch:HI 3 "r")]
19787 "TARGET_K8 && !optimize_size"
19788 [(set (match_dup 3) (match_dup 2))
19789 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19790 (clobber (reg:CC FLAGS_REG))])]
19792 if (!rtx_equal_p (operands[0], operands[1]))
19793 emit_move_insn (operands[0], operands[1]);
19796 ;; After splitting up read-modify operations, array accesses with memory
19797 ;; operands might end up in form:
19799 ;; movl 4(%esp), %edx
19801 ;; instead of pre-splitting:
19803 ;; addl 4(%esp), %eax
19805 ;; movl 4(%esp), %edx
19806 ;; leal (%edx,%eax,4), %eax
19809 [(parallel [(set (match_operand 0 "register_operand" "")
19810 (ashift (match_operand 1 "register_operand" "")
19811 (match_operand 2 "const_int_operand" "")))
19812 (clobber (reg:CC FLAGS_REG))])
19813 (set (match_operand 3 "register_operand")
19814 (match_operand 4 "x86_64_general_operand" ""))
19815 (parallel [(set (match_operand 5 "register_operand" "")
19816 (plus (match_operand 6 "register_operand" "")
19817 (match_operand 7 "register_operand" "")))
19818 (clobber (reg:CC FLAGS_REG))])]
19819 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19820 /* Validate MODE for lea. */
19821 && ((!TARGET_PARTIAL_REG_STALL
19822 && (GET_MODE (operands[0]) == QImode
19823 || GET_MODE (operands[0]) == HImode))
19824 || GET_MODE (operands[0]) == SImode
19825 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19826 /* We reorder load and the shift. */
19827 && !rtx_equal_p (operands[1], operands[3])
19828 && !reg_overlap_mentioned_p (operands[0], operands[4])
19829 /* Last PLUS must consist of operand 0 and 3. */
19830 && !rtx_equal_p (operands[0], operands[3])
19831 && (rtx_equal_p (operands[3], operands[6])
19832 || rtx_equal_p (operands[3], operands[7]))
19833 && (rtx_equal_p (operands[0], operands[6])
19834 || rtx_equal_p (operands[0], operands[7]))
19835 /* The intermediate operand 0 must die or be same as output. */
19836 && (rtx_equal_p (operands[0], operands[5])
19837 || peep2_reg_dead_p (3, operands[0]))"
19838 [(set (match_dup 3) (match_dup 4))
19839 (set (match_dup 0) (match_dup 1))]
19841 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19842 int scale = 1 << INTVAL (operands[2]);
19843 rtx index = gen_lowpart (Pmode, operands[1]);
19844 rtx base = gen_lowpart (Pmode, operands[3]);
19845 rtx dest = gen_lowpart (mode, operands[5]);
19847 operands[1] = gen_rtx_PLUS (Pmode, base,
19848 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19850 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19851 operands[0] = dest;
19854 ;; Call-value patterns last so that the wildcard operand does not
19855 ;; disrupt insn-recog's switch tables.
19857 (define_insn "*call_value_pop_0"
19858 [(set (match_operand 0 "" "")
19859 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19860 (match_operand:SI 2 "" "")))
19861 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19862 (match_operand:SI 3 "immediate_operand" "")))]
19865 if (SIBLING_CALL_P (insn))
19868 return "call\t%P1";
19870 [(set_attr "type" "callv")])
19872 (define_insn "*call_value_pop_1"
19873 [(set (match_operand 0 "" "")
19874 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19875 (match_operand:SI 2 "" "")))
19876 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19877 (match_operand:SI 3 "immediate_operand" "i")))]
19880 if (constant_call_address_operand (operands[1], Pmode))
19882 if (SIBLING_CALL_P (insn))
19885 return "call\t%P1";
19887 if (SIBLING_CALL_P (insn))
19890 return "call\t%A1";
19892 [(set_attr "type" "callv")])
19894 (define_insn "*call_value_0"
19895 [(set (match_operand 0 "" "")
19896 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19897 (match_operand:SI 2 "" "")))]
19900 if (SIBLING_CALL_P (insn))
19903 return "call\t%P1";
19905 [(set_attr "type" "callv")])
19907 (define_insn "*call_value_0_rex64"
19908 [(set (match_operand 0 "" "")
19909 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19910 (match_operand:DI 2 "const_int_operand" "")))]
19913 if (SIBLING_CALL_P (insn))
19916 return "call\t%P1";
19918 [(set_attr "type" "callv")])
19920 (define_insn "*call_value_1"
19921 [(set (match_operand 0 "" "")
19922 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19923 (match_operand:SI 2 "" "")))]
19924 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19926 if (constant_call_address_operand (operands[1], Pmode))
19927 return "call\t%P1";
19928 return "call\t%A1";
19930 [(set_attr "type" "callv")])
19932 (define_insn "*sibcall_value_1"
19933 [(set (match_operand 0 "" "")
19934 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19935 (match_operand:SI 2 "" "")))]
19936 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19938 if (constant_call_address_operand (operands[1], Pmode))
19942 [(set_attr "type" "callv")])
19944 (define_insn "*call_value_1_rex64"
19945 [(set (match_operand 0 "" "")
19946 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19947 (match_operand:DI 2 "" "")))]
19948 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19950 if (constant_call_address_operand (operands[1], Pmode))
19951 return "call\t%P1";
19952 return "call\t%A1";
19954 [(set_attr "type" "callv")])
19956 (define_insn "*sibcall_value_1_rex64"
19957 [(set (match_operand 0 "" "")
19958 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19959 (match_operand:DI 2 "" "")))]
19960 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19962 [(set_attr "type" "callv")])
19964 (define_insn "*sibcall_value_1_rex64_v"
19965 [(set (match_operand 0 "" "")
19966 (call (mem:QI (reg:DI 40))
19967 (match_operand:DI 1 "" "")))]
19968 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19970 [(set_attr "type" "callv")])
19972 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19973 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19974 ;; caught for use by garbage collectors and the like. Using an insn that
19975 ;; maps to SIGILL makes it more likely the program will rightfully die.
19976 ;; Keeping with tradition, "6" is in honor of #UD.
19977 (define_insn "trap"
19978 [(trap_if (const_int 1) (const_int 6))]
19981 [(set_attr "length" "2")])
19983 (define_expand "sse_prologue_save"
19984 [(parallel [(set (match_operand:BLK 0 "" "")
19985 (unspec:BLK [(reg:DI 21)
19992 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19993 (use (match_operand:DI 1 "register_operand" ""))
19994 (use (match_operand:DI 2 "immediate_operand" ""))
19995 (use (label_ref:DI (match_operand 3 "" "")))])]
19999 (define_insn "*sse_prologue_save_insn"
20000 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20001 (match_operand:DI 4 "const_int_operand" "n")))
20002 (unspec:BLK [(reg:DI 21)
20009 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20010 (use (match_operand:DI 1 "register_operand" "r"))
20011 (use (match_operand:DI 2 "const_int_operand" "i"))
20012 (use (label_ref:DI (match_operand 3 "" "X")))]
20014 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20015 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20019 operands[0] = gen_rtx_MEM (Pmode,
20020 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20021 output_asm_insn (\"jmp\\t%A1\", operands);
20022 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20024 operands[4] = adjust_address (operands[0], DImode, i*16);
20025 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20026 PUT_MODE (operands[4], TImode);
20027 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20028 output_asm_insn (\"rex\", operands);
20029 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20031 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20032 CODE_LABEL_NUMBER (operands[3]));
20036 [(set_attr "type" "other")
20037 (set_attr "length_immediate" "0")
20038 (set_attr "length_address" "0")
20039 (set_attr "length" "135")
20040 (set_attr "memory" "store")
20041 (set_attr "modrm" "0")
20042 (set_attr "mode" "DI")])
20044 (define_expand "prefetch"
20045 [(prefetch (match_operand 0 "address_operand" "")
20046 (match_operand:SI 1 "const_int_operand" "")
20047 (match_operand:SI 2 "const_int_operand" ""))]
20048 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20050 int rw = INTVAL (operands[1]);
20051 int locality = INTVAL (operands[2]);
20053 gcc_assert (rw == 0 || rw == 1);
20054 gcc_assert (locality >= 0 && locality <= 3);
20055 gcc_assert (GET_MODE (operands[0]) == Pmode
20056 || GET_MODE (operands[0]) == VOIDmode);
20058 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20059 supported by SSE counterpart or the SSE prefetch is not available
20060 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20062 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20063 operands[2] = GEN_INT (3);
20065 operands[1] = const0_rtx;
20068 (define_insn "*prefetch_sse"
20069 [(prefetch (match_operand:SI 0 "address_operand" "p")
20071 (match_operand:SI 1 "const_int_operand" ""))]
20072 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20074 static const char * const patterns[4] = {
20075 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20078 int locality = INTVAL (operands[1]);
20079 gcc_assert (locality >= 0 && locality <= 3);
20081 return patterns[locality];
20083 [(set_attr "type" "sse")
20084 (set_attr "memory" "none")])
20086 (define_insn "*prefetch_sse_rex"
20087 [(prefetch (match_operand:DI 0 "address_operand" "p")
20089 (match_operand:SI 1 "const_int_operand" ""))]
20090 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20092 static const char * const patterns[4] = {
20093 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20096 int locality = INTVAL (operands[1]);
20097 gcc_assert (locality >= 0 && locality <= 3);
20099 return patterns[locality];
20101 [(set_attr "type" "sse")
20102 (set_attr "memory" "none")])
20104 (define_insn "*prefetch_3dnow"
20105 [(prefetch (match_operand:SI 0 "address_operand" "p")
20106 (match_operand:SI 1 "const_int_operand" "n")
20108 "TARGET_3DNOW && !TARGET_64BIT"
20110 if (INTVAL (operands[1]) == 0)
20111 return "prefetch\t%a0";
20113 return "prefetchw\t%a0";
20115 [(set_attr "type" "mmx")
20116 (set_attr "memory" "none")])
20118 (define_insn "*prefetch_3dnow_rex"
20119 [(prefetch (match_operand:DI 0 "address_operand" "p")
20120 (match_operand:SI 1 "const_int_operand" "n")
20122 "TARGET_3DNOW && TARGET_64BIT"
20124 if (INTVAL (operands[1]) == 0)
20125 return "prefetch\t%a0";
20127 return "prefetchw\t%a0";
20129 [(set_attr "type" "mmx")
20130 (set_attr "memory" "none")])
20132 (define_expand "stack_protect_set"
20133 [(match_operand 0 "memory_operand" "")
20134 (match_operand 1 "memory_operand" "")]
20137 #ifdef TARGET_THREAD_SSP_OFFSET
20139 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20140 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20142 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20143 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20146 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20148 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20153 (define_insn "stack_protect_set_si"
20154 [(set (match_operand:SI 0 "memory_operand" "=m")
20155 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20156 (set (match_scratch:SI 2 "=&r") (const_int 0))
20157 (clobber (reg:CC FLAGS_REG))]
20159 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20160 [(set_attr "type" "multi")])
20162 (define_insn "stack_protect_set_di"
20163 [(set (match_operand:DI 0 "memory_operand" "=m")
20164 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20165 (set (match_scratch:DI 2 "=&r") (const_int 0))
20166 (clobber (reg:CC FLAGS_REG))]
20168 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20169 [(set_attr "type" "multi")])
20171 (define_insn "stack_tls_protect_set_si"
20172 [(set (match_operand:SI 0 "memory_operand" "=m")
20173 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20174 (set (match_scratch:SI 2 "=&r") (const_int 0))
20175 (clobber (reg:CC FLAGS_REG))]
20177 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20178 [(set_attr "type" "multi")])
20180 (define_insn "stack_tls_protect_set_di"
20181 [(set (match_operand:DI 0 "memory_operand" "=m")
20182 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20183 (set (match_scratch:DI 2 "=&r") (const_int 0))
20184 (clobber (reg:CC FLAGS_REG))]
20186 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20187 [(set_attr "type" "multi")])
20189 (define_expand "stack_protect_test"
20190 [(match_operand 0 "memory_operand" "")
20191 (match_operand 1 "memory_operand" "")
20192 (match_operand 2 "" "")]
20195 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20196 ix86_compare_op0 = operands[0];
20197 ix86_compare_op1 = operands[1];
20198 ix86_compare_emitted = flags;
20200 #ifdef TARGET_THREAD_SSP_OFFSET
20202 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20203 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20205 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20206 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20209 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20211 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20213 emit_jump_insn (gen_beq (operands[2]));
20217 (define_insn "stack_protect_test_si"
20218 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20219 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20220 (match_operand:SI 2 "memory_operand" "m")]
20222 (clobber (match_scratch:SI 3 "=&r"))]
20224 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20225 [(set_attr "type" "multi")])
20227 (define_insn "stack_protect_test_di"
20228 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20229 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20230 (match_operand:DI 2 "memory_operand" "m")]
20232 (clobber (match_scratch:DI 3 "=&r"))]
20234 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20235 [(set_attr "type" "multi")])
20237 (define_insn "stack_tls_protect_test_si"
20238 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20239 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20240 (match_operand:SI 2 "const_int_operand" "i")]
20241 UNSPEC_SP_TLS_TEST))
20242 (clobber (match_scratch:SI 3 "=r"))]
20244 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20245 [(set_attr "type" "multi")])
20247 (define_insn "stack_tls_protect_test_di"
20248 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20249 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20250 (match_operand:DI 2 "const_int_operand" "i")]
20251 UNSPEC_SP_TLS_TEST))
20252 (clobber (match_scratch:DI 3 "=r"))]
20254 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20255 [(set_attr "type" "multi")])
20259 (include "sync.md")