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" "=<,<")
1278 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1281 push{w}\t{|WORD PTR }%1
1283 [(set_attr "type" "push")
1284 (set_attr "mode" "HI")])
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288 [(set (match_operand:HI 0 "push_operand" "=X")
1289 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1292 [(set_attr "type" "push")
1293 (set_attr "mode" "QI")])
1295 (define_insn "*movhi_1"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300 switch (get_attr_type (insn))
1303 /* movzwl is faster than movw on p2 due to partial word stalls,
1304 though not as fast as an aligned movl. */
1305 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307 if (get_attr_mode (insn) == MODE_SI)
1308 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310 return "mov{w}\t{%1, %0|%0, %1}";
1314 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315 (const_string "imov")
1316 (and (eq_attr "alternative" "0")
1317 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319 (eq (symbol_ref "TARGET_HIMODE_MATH")
1321 (const_string "imov")
1322 (and (eq_attr "alternative" "1,2")
1323 (match_operand:HI 1 "aligned_operand" ""))
1324 (const_string "imov")
1325 (and (ne (symbol_ref "TARGET_MOVX")
1327 (eq_attr "alternative" "0,2"))
1328 (const_string "imovx")
1330 (const_string "imov")))
1332 (cond [(eq_attr "type" "imovx")
1334 (and (eq_attr "alternative" "1,2")
1335 (match_operand:HI 1 "aligned_operand" ""))
1337 (and (eq_attr "alternative" "0")
1338 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340 (eq (symbol_ref "TARGET_HIMODE_MATH")
1344 (const_string "HI")))])
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354 movabs{w}\t{%1, %P0|%P0, %1}
1355 mov{w}\t{%1, %a0|%a0, %1}"
1356 [(set_attr "type" "imov")
1357 (set_attr "modrm" "0,*")
1358 (set_attr "length_address" "8,0")
1359 (set_attr "length_immediate" "0,*")
1360 (set_attr "memory" "store")
1361 (set_attr "mode" "HI")])
1363 (define_insn "*movabshi_2_rex64"
1364 [(set (match_operand:HI 0 "register_operand" "=a,r")
1365 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368 movabs{w}\t{%P1, %0|%0, %P1}
1369 mov{w}\t{%a1, %0|%0, %a1}"
1370 [(set_attr "type" "imov")
1371 (set_attr "modrm" "0,*")
1372 (set_attr "length_address" "8,0")
1373 (set_attr "length_immediate" "0")
1374 (set_attr "memory" "load")
1375 (set_attr "mode" "HI")])
1377 (define_insn "*swaphi_1"
1378 [(set (match_operand:HI 0 "register_operand" "+r")
1379 (match_operand:HI 1 "register_operand" "+r"))
1382 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384 [(set_attr "type" "imov")
1385 (set_attr "mode" "SI")
1386 (set_attr "pent_pair" "np")
1387 (set_attr "athlon_decode" "vector")])
1389 (define_insn "*swaphi_2"
1390 [(set (match_operand:HI 0 "register_operand" "+r")
1391 (match_operand:HI 1 "register_operand" "+r"))
1394 "TARGET_PARTIAL_REG_STALL"
1396 [(set_attr "type" "imov")
1397 (set_attr "mode" "HI")
1398 (set_attr "pent_pair" "np")
1399 (set_attr "athlon_decode" "vector")])
1401 (define_expand "movstricthi"
1402 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403 (match_operand:HI 1 "general_operand" ""))]
1404 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406 /* Don't generate memory->memory moves, go through a register */
1407 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408 operands[1] = force_reg (HImode, operands[1]);
1411 (define_insn "*movstricthi_1"
1412 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413 (match_operand:HI 1 "general_operand" "rn,m"))]
1414 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416 "mov{w}\t{%1, %0|%0, %1}"
1417 [(set_attr "type" "imov")
1418 (set_attr "mode" "HI")])
1420 (define_insn "*movstricthi_xor"
1421 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422 (match_operand:HI 1 "const0_operand" "i"))
1423 (clobber (reg:CC FLAGS_REG))]
1425 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426 "xor{w}\t{%0, %0|%0, %0}"
1427 [(set_attr "type" "alu1")
1428 (set_attr "mode" "HI")
1429 (set_attr "length_immediate" "0")])
1431 (define_expand "movqi"
1432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433 (match_operand:QI 1 "general_operand" ""))]
1435 "ix86_expand_move (QImode, operands); DONE;")
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte". But actually we use pushw, which has the effect
1439 ;; of rounding the amount pushed up to a halfword.
1441 (define_insn "*pushqi2"
1442 [(set (match_operand:QI 0 "push_operand" "=X,X")
1443 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1446 push{w}\t{|word ptr }%1
1448 [(set_attr "type" "push")
1449 (set_attr "mode" "HI")])
1451 ;; For 64BIT abi we always round up to 8 bytes.
1452 (define_insn "*pushqi2_rex64"
1453 [(set (match_operand:QI 0 "push_operand" "=X")
1454 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1457 [(set_attr "type" "push")
1458 (set_attr "mode" "QI")])
1460 ;; Situation is quite tricky about when to choose full sized (SImode) move
1461 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1462 ;; partial register dependency machines (such as AMD Athlon), where QImode
1463 ;; moves issue extra dependency and for partial register stalls machines
1464 ;; that don't use QImode patterns (and QImode move cause stall on the next
1467 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468 ;; register stall machines with, where we use QImode instructions, since
1469 ;; partial register stall can be caused there. Then we use movzx.
1470 (define_insn "*movqi_1"
1471 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,m ,qn"))]
1473 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1475 switch (get_attr_type (insn))
1478 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1479 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1481 if (get_attr_mode (insn) == MODE_SI)
1482 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1484 return "mov{b}\t{%1, %0|%0, %1}";
1488 (cond [(eq_attr "alternative" "5")
1489 (const_string "imovx")
1490 (ne (symbol_ref "optimize_size") (const_int 0))
1491 (const_string "imov")
1492 (and (eq_attr "alternative" "3")
1493 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1495 (eq (symbol_ref "TARGET_QIMODE_MATH")
1497 (const_string "imov")
1498 (eq_attr "alternative" "3")
1499 (const_string "imovx")
1500 (and (ne (symbol_ref "TARGET_MOVX")
1502 (eq_attr "alternative" "2"))
1503 (const_string "imovx")
1505 (const_string "imov")))
1507 (cond [(eq_attr "alternative" "3,4,5")
1509 (eq_attr "alternative" "6")
1511 (eq_attr "type" "imovx")
1513 (and (eq_attr "type" "imov")
1514 (and (eq_attr "alternative" "0,1")
1515 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1518 ;; Avoid partial register stalls when not using QImode arithmetic
1519 (and (eq_attr "type" "imov")
1520 (and (eq_attr "alternative" "0,1")
1521 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1523 (eq (symbol_ref "TARGET_QIMODE_MATH")
1527 (const_string "QI")))])
1529 (define_expand "reload_outqi"
1530 [(parallel [(match_operand:QI 0 "" "=m")
1531 (match_operand:QI 1 "register_operand" "r")
1532 (match_operand:QI 2 "register_operand" "=&q")])]
1536 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1538 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1539 if (! q_regs_operand (op1, QImode))
1541 emit_insn (gen_movqi (op2, op1));
1544 emit_insn (gen_movqi (op0, op1));
1548 (define_insn "*swapqi_1"
1549 [(set (match_operand:QI 0 "register_operand" "+r")
1550 (match_operand:QI 1 "register_operand" "+r"))
1553 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1555 [(set_attr "type" "imov")
1556 (set_attr "mode" "SI")
1557 (set_attr "pent_pair" "np")
1558 (set_attr "athlon_decode" "vector")])
1560 (define_insn "*swapqi_2"
1561 [(set (match_operand:QI 0 "register_operand" "+q")
1562 (match_operand:QI 1 "register_operand" "+q"))
1565 "TARGET_PARTIAL_REG_STALL"
1567 [(set_attr "type" "imov")
1568 (set_attr "mode" "QI")
1569 (set_attr "pent_pair" "np")
1570 (set_attr "athlon_decode" "vector")])
1572 (define_expand "movstrictqi"
1573 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1574 (match_operand:QI 1 "general_operand" ""))]
1575 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1577 /* Don't generate memory->memory moves, go through a register. */
1578 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1579 operands[1] = force_reg (QImode, operands[1]);
1582 (define_insn "*movstrictqi_1"
1583 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1584 (match_operand:QI 1 "general_operand" "*qn,m"))]
1585 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1586 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1587 "mov{b}\t{%1, %0|%0, %1}"
1588 [(set_attr "type" "imov")
1589 (set_attr "mode" "QI")])
1591 (define_insn "*movstrictqi_xor"
1592 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1593 (match_operand:QI 1 "const0_operand" "i"))
1594 (clobber (reg:CC FLAGS_REG))]
1595 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1596 "xor{b}\t{%0, %0|%0, %0}"
1597 [(set_attr "type" "alu1")
1598 (set_attr "mode" "QI")
1599 (set_attr "length_immediate" "0")])
1601 (define_insn "*movsi_extv_1"
1602 [(set (match_operand:SI 0 "register_operand" "=R")
1603 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1607 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1608 [(set_attr "type" "imovx")
1609 (set_attr "mode" "SI")])
1611 (define_insn "*movhi_extv_1"
1612 [(set (match_operand:HI 0 "register_operand" "=R")
1613 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1617 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1618 [(set_attr "type" "imovx")
1619 (set_attr "mode" "SI")])
1621 (define_insn "*movqi_extv_1"
1622 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1623 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1628 switch (get_attr_type (insn))
1631 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1633 return "mov{b}\t{%h1, %0|%0, %h1}";
1637 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1638 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1639 (ne (symbol_ref "TARGET_MOVX")
1641 (const_string "imovx")
1642 (const_string "imov")))
1644 (if_then_else (eq_attr "type" "imovx")
1646 (const_string "QI")))])
1648 (define_insn "*movqi_extv_1_rex64"
1649 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1650 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1655 switch (get_attr_type (insn))
1658 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1660 return "mov{b}\t{%h1, %0|%0, %h1}";
1664 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1665 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1666 (ne (symbol_ref "TARGET_MOVX")
1668 (const_string "imovx")
1669 (const_string "imov")))
1671 (if_then_else (eq_attr "type" "imovx")
1673 (const_string "QI")))])
1675 ;; Stores and loads of ax to arbitrary constant address.
1676 ;; We fake an second form of instruction to force reload to load address
1677 ;; into register when rax is not available
1678 (define_insn "*movabsqi_1_rex64"
1679 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1680 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1681 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1683 movabs{b}\t{%1, %P0|%P0, %1}
1684 mov{b}\t{%1, %a0|%a0, %1}"
1685 [(set_attr "type" "imov")
1686 (set_attr "modrm" "0,*")
1687 (set_attr "length_address" "8,0")
1688 (set_attr "length_immediate" "0,*")
1689 (set_attr "memory" "store")
1690 (set_attr "mode" "QI")])
1692 (define_insn "*movabsqi_2_rex64"
1693 [(set (match_operand:QI 0 "register_operand" "=a,r")
1694 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1695 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1697 movabs{b}\t{%P1, %0|%0, %P1}
1698 mov{b}\t{%a1, %0|%0, %a1}"
1699 [(set_attr "type" "imov")
1700 (set_attr "modrm" "0,*")
1701 (set_attr "length_address" "8,0")
1702 (set_attr "length_immediate" "0")
1703 (set_attr "memory" "load")
1704 (set_attr "mode" "QI")])
1706 (define_insn "*movdi_extzv_1"
1707 [(set (match_operand:DI 0 "register_operand" "=R")
1708 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1712 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1713 [(set_attr "type" "imovx")
1714 (set_attr "mode" "DI")])
1716 (define_insn "*movsi_extzv_1"
1717 [(set (match_operand:SI 0 "register_operand" "=R")
1718 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1722 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1723 [(set_attr "type" "imovx")
1724 (set_attr "mode" "SI")])
1726 (define_insn "*movqi_extzv_2"
1727 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1728 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733 switch (get_attr_type (insn))
1736 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1738 return "mov{b}\t{%h1, %0|%0, %h1}";
1742 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1743 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1744 (ne (symbol_ref "TARGET_MOVX")
1746 (const_string "imovx")
1747 (const_string "imov")))
1749 (if_then_else (eq_attr "type" "imovx")
1751 (const_string "QI")))])
1753 (define_insn "*movqi_extzv_2_rex64"
1754 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1755 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1760 switch (get_attr_type (insn))
1763 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1765 return "mov{b}\t{%h1, %0|%0, %h1}";
1769 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1770 (ne (symbol_ref "TARGET_MOVX")
1772 (const_string "imovx")
1773 (const_string "imov")))
1775 (if_then_else (eq_attr "type" "imovx")
1777 (const_string "QI")))])
1779 (define_insn "movsi_insv_1"
1780 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1783 (match_operand:SI 1 "general_operand" "Qmn"))]
1785 "mov{b}\t{%b1, %h0|%h0, %b1}"
1786 [(set_attr "type" "imov")
1787 (set_attr "mode" "QI")])
1789 (define_insn "movdi_insv_1_rex64"
1790 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1793 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1795 "mov{b}\t{%b1, %h0|%h0, %b1}"
1796 [(set_attr "type" "imov")
1797 (set_attr "mode" "QI")])
1799 (define_insn "*movqi_insv_2"
1800 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1803 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1806 "mov{b}\t{%h1, %h0|%h0, %h1}"
1807 [(set_attr "type" "imov")
1808 (set_attr "mode" "QI")])
1810 (define_expand "movdi"
1811 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1812 (match_operand:DI 1 "general_operand" ""))]
1814 "ix86_expand_move (DImode, operands); DONE;")
1816 (define_insn "*pushdi"
1817 [(set (match_operand:DI 0 "push_operand" "=<")
1818 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1822 (define_insn "*pushdi2_rex64"
1823 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1824 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1829 [(set_attr "type" "push,multi")
1830 (set_attr "mode" "DI")])
1832 ;; Convert impossible pushes of immediate to existing instructions.
1833 ;; First try to get scratch register and go through it. In case this
1834 ;; fails, push sign extended lower part first and then overwrite
1835 ;; upper part by 32bit move.
1837 [(match_scratch:DI 2 "r")
1838 (set (match_operand:DI 0 "push_operand" "")
1839 (match_operand:DI 1 "immediate_operand" ""))]
1840 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1841 && !x86_64_immediate_operand (operands[1], DImode)"
1842 [(set (match_dup 2) (match_dup 1))
1843 (set (match_dup 0) (match_dup 2))]
1846 ;; We need to define this as both peepholer and splitter for case
1847 ;; peephole2 pass is not run.
1848 ;; "&& 1" is needed to keep it from matching the previous pattern.
1850 [(set (match_operand:DI 0 "push_operand" "")
1851 (match_operand:DI 1 "immediate_operand" ""))]
1852 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1853 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1854 [(set (match_dup 0) (match_dup 1))
1855 (set (match_dup 2) (match_dup 3))]
1856 "split_di (operands + 1, 1, operands + 2, operands + 3);
1857 operands[1] = gen_lowpart (DImode, operands[2]);
1858 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1863 [(set (match_operand:DI 0 "push_operand" "")
1864 (match_operand:DI 1 "immediate_operand" ""))]
1865 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1866 ? flow2_completed : reload_completed)
1867 && !symbolic_operand (operands[1], DImode)
1868 && !x86_64_immediate_operand (operands[1], DImode)"
1869 [(set (match_dup 0) (match_dup 1))
1870 (set (match_dup 2) (match_dup 3))]
1871 "split_di (operands + 1, 1, operands + 2, operands + 3);
1872 operands[1] = gen_lowpart (DImode, operands[2]);
1873 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1877 (define_insn "*pushdi2_prologue_rex64"
1878 [(set (match_operand:DI 0 "push_operand" "=<")
1879 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1880 (clobber (mem:BLK (scratch)))]
1883 [(set_attr "type" "push")
1884 (set_attr "mode" "DI")])
1886 (define_insn "*popdi1_epilogue_rex64"
1887 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1888 (mem:DI (reg:DI SP_REG)))
1889 (set (reg:DI SP_REG)
1890 (plus:DI (reg:DI SP_REG) (const_int 8)))
1891 (clobber (mem:BLK (scratch)))]
1894 [(set_attr "type" "pop")
1895 (set_attr "mode" "DI")])
1897 (define_insn "popdi1"
1898 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1899 (mem:DI (reg:DI SP_REG)))
1900 (set (reg:DI SP_REG)
1901 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1904 [(set_attr "type" "pop")
1905 (set_attr "mode" "DI")])
1907 (define_insn "*movdi_xor_rex64"
1908 [(set (match_operand:DI 0 "register_operand" "=r")
1909 (match_operand:DI 1 "const0_operand" "i"))
1910 (clobber (reg:CC FLAGS_REG))]
1911 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1912 && reload_completed"
1913 "xor{l}\t{%k0, %k0|%k0, %k0}"
1914 [(set_attr "type" "alu1")
1915 (set_attr "mode" "SI")
1916 (set_attr "length_immediate" "0")])
1918 (define_insn "*movdi_or_rex64"
1919 [(set (match_operand:DI 0 "register_operand" "=r")
1920 (match_operand:DI 1 "const_int_operand" "i"))
1921 (clobber (reg:CC FLAGS_REG))]
1922 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1924 && operands[1] == constm1_rtx"
1926 operands[1] = constm1_rtx;
1927 return "or{q}\t{%1, %0|%0, %1}";
1929 [(set_attr "type" "alu1")
1930 (set_attr "mode" "DI")
1931 (set_attr "length_immediate" "1")])
1933 (define_insn "*movdi_2"
1934 [(set (match_operand:DI 0 "nonimmediate_operand"
1935 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1936 (match_operand:DI 1 "general_operand"
1937 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1938 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943 movq\t{%1, %0|%0, %1}
1944 movq\t{%1, %0|%0, %1}
1946 movq\t{%1, %0|%0, %1}
1947 movdqa\t{%1, %0|%0, %1}
1948 movq\t{%1, %0|%0, %1}
1950 movlps\t{%1, %0|%0, %1}
1951 movaps\t{%1, %0|%0, %1}
1952 movlps\t{%1, %0|%0, %1}"
1953 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1954 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1957 [(set (match_operand:DI 0 "push_operand" "")
1958 (match_operand:DI 1 "general_operand" ""))]
1959 "!TARGET_64BIT && reload_completed
1960 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1962 "ix86_split_long_move (operands); DONE;")
1964 ;; %%% This multiword shite has got to go.
1966 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1967 (match_operand:DI 1 "general_operand" ""))]
1968 "!TARGET_64BIT && reload_completed
1969 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1970 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1972 "ix86_split_long_move (operands); DONE;")
1974 (define_insn "*movdi_1_rex64"
1975 [(set (match_operand:DI 0 "nonimmediate_operand"
1976 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1977 (match_operand:DI 1 "general_operand"
1978 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1979 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1981 switch (get_attr_type (insn))
1984 if (which_alternative == 13)
1985 return "movq2dq\t{%1, %0|%0, %1}";
1987 return "movdq2q\t{%1, %0|%0, %1}";
1989 if (get_attr_mode (insn) == MODE_TI)
1990 return "movdqa\t{%1, %0|%0, %1}";
1993 /* Moves from and into integer register is done using movd opcode with
1995 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1996 return "movd\t{%1, %0|%0, %1}";
1997 return "movq\t{%1, %0|%0, %1}";
2000 return "pxor\t%0, %0";
2004 return "lea{q}\t{%a1, %0|%0, %a1}";
2006 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2007 if (get_attr_mode (insn) == MODE_SI)
2008 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2009 else if (which_alternative == 2)
2010 return "movabs{q}\t{%1, %0|%0, %1}";
2012 return "mov{q}\t{%1, %0|%0, %1}";
2016 (cond [(eq_attr "alternative" "5")
2017 (const_string "mmxadd")
2018 (eq_attr "alternative" "6,7,8")
2019 (const_string "mmxmov")
2020 (eq_attr "alternative" "9")
2021 (const_string "sselog1")
2022 (eq_attr "alternative" "10,11,12")
2023 (const_string "ssemov")
2024 (eq_attr "alternative" "13,14")
2025 (const_string "ssecvt")
2026 (eq_attr "alternative" "4")
2027 (const_string "multi")
2028 (match_operand:DI 1 "pic_32bit_operand" "")
2029 (const_string "lea")
2031 (const_string "imov")))
2032 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2033 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2034 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2036 ;; Stores and loads of ax to arbitrary constant address.
2037 ;; We fake an second form of instruction to force reload to load address
2038 ;; into register when rax is not available
2039 (define_insn "*movabsdi_1_rex64"
2040 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2041 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2042 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2044 movabs{q}\t{%1, %P0|%P0, %1}
2045 mov{q}\t{%1, %a0|%a0, %1}"
2046 [(set_attr "type" "imov")
2047 (set_attr "modrm" "0,*")
2048 (set_attr "length_address" "8,0")
2049 (set_attr "length_immediate" "0,*")
2050 (set_attr "memory" "store")
2051 (set_attr "mode" "DI")])
2053 (define_insn "*movabsdi_2_rex64"
2054 [(set (match_operand:DI 0 "register_operand" "=a,r")
2055 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2056 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2058 movabs{q}\t{%P1, %0|%0, %P1}
2059 mov{q}\t{%a1, %0|%0, %a1}"
2060 [(set_attr "type" "imov")
2061 (set_attr "modrm" "0,*")
2062 (set_attr "length_address" "8,0")
2063 (set_attr "length_immediate" "0")
2064 (set_attr "memory" "load")
2065 (set_attr "mode" "DI")])
2067 ;; Convert impossible stores of immediate to existing instructions.
2068 ;; First try to get scratch register and go through it. In case this
2069 ;; fails, move by 32bit parts.
2071 [(match_scratch:DI 2 "r")
2072 (set (match_operand:DI 0 "memory_operand" "")
2073 (match_operand:DI 1 "immediate_operand" ""))]
2074 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2075 && !x86_64_immediate_operand (operands[1], DImode)"
2076 [(set (match_dup 2) (match_dup 1))
2077 (set (match_dup 0) (match_dup 2))]
2080 ;; We need to define this as both peepholer and splitter for case
2081 ;; peephole2 pass is not run.
2082 ;; "&& 1" is needed to keep it from matching the previous pattern.
2084 [(set (match_operand:DI 0 "memory_operand" "")
2085 (match_operand:DI 1 "immediate_operand" ""))]
2086 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2087 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2088 [(set (match_dup 2) (match_dup 3))
2089 (set (match_dup 4) (match_dup 5))]
2090 "split_di (operands, 2, operands + 2, operands + 4);")
2093 [(set (match_operand:DI 0 "memory_operand" "")
2094 (match_operand:DI 1 "immediate_operand" ""))]
2095 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2096 ? flow2_completed : reload_completed)
2097 && !symbolic_operand (operands[1], DImode)
2098 && !x86_64_immediate_operand (operands[1], DImode)"
2099 [(set (match_dup 2) (match_dup 3))
2100 (set (match_dup 4) (match_dup 5))]
2101 "split_di (operands, 2, operands + 2, operands + 4);")
2103 (define_insn "*swapdi_rex64"
2104 [(set (match_operand:DI 0 "register_operand" "+r")
2105 (match_operand:DI 1 "register_operand" "+r"))
2110 [(set_attr "type" "imov")
2111 (set_attr "mode" "DI")
2112 (set_attr "pent_pair" "np")
2113 (set_attr "athlon_decode" "vector")])
2115 (define_expand "movti"
2116 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2117 (match_operand:TI 1 "nonimmediate_operand" ""))]
2118 "TARGET_SSE || TARGET_64BIT"
2121 ix86_expand_move (TImode, operands);
2123 ix86_expand_vector_move (TImode, operands);
2127 (define_insn "*movti_internal"
2128 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2129 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2130 "TARGET_SSE && !TARGET_64BIT
2131 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2133 switch (which_alternative)
2136 if (get_attr_mode (insn) == MODE_V4SF)
2137 return "xorps\t%0, %0";
2139 return "pxor\t%0, %0";
2142 if (get_attr_mode (insn) == MODE_V4SF)
2143 return "movaps\t{%1, %0|%0, %1}";
2145 return "movdqa\t{%1, %0|%0, %1}";
2150 [(set_attr "type" "ssemov,ssemov,ssemov")
2152 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2153 (const_string "V4SF")
2155 (eq_attr "alternative" "0,1")
2157 (ne (symbol_ref "optimize_size")
2159 (const_string "V4SF")
2160 (const_string "TI"))
2161 (eq_attr "alternative" "2")
2163 (ne (symbol_ref "optimize_size")
2165 (const_string "V4SF")
2166 (const_string "TI"))]
2167 (const_string "TI")))])
2169 (define_insn "*movti_rex64"
2170 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2171 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2173 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2175 switch (which_alternative)
2181 if (get_attr_mode (insn) == MODE_V4SF)
2182 return "xorps\t%0, %0";
2184 return "pxor\t%0, %0";
2187 if (get_attr_mode (insn) == MODE_V4SF)
2188 return "movaps\t{%1, %0|%0, %1}";
2190 return "movdqa\t{%1, %0|%0, %1}";
2195 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2197 (cond [(eq_attr "alternative" "2,3")
2199 (ne (symbol_ref "optimize_size")
2201 (const_string "V4SF")
2202 (const_string "TI"))
2203 (eq_attr "alternative" "4")
2205 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2207 (ne (symbol_ref "optimize_size")
2209 (const_string "V4SF")
2210 (const_string "TI"))]
2211 (const_string "DI")))])
2214 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2215 (match_operand:TI 1 "general_operand" ""))]
2216 "reload_completed && !SSE_REG_P (operands[0])
2217 && !SSE_REG_P (operands[1])"
2219 "ix86_split_long_move (operands); DONE;")
2221 (define_expand "movsf"
2222 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2223 (match_operand:SF 1 "general_operand" ""))]
2225 "ix86_expand_move (SFmode, operands); DONE;")
2227 (define_insn "*pushsf"
2228 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2229 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2232 /* Anything else should be already split before reg-stack. */
2233 gcc_assert (which_alternative == 1);
2234 return "push{l}\t%1";
2236 [(set_attr "type" "multi,push,multi")
2237 (set_attr "unit" "i387,*,*")
2238 (set_attr "mode" "SF,SI,SF")])
2240 (define_insn "*pushsf_rex64"
2241 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2242 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2245 /* Anything else should be already split before reg-stack. */
2246 gcc_assert (which_alternative == 1);
2247 return "push{q}\t%q1";
2249 [(set_attr "type" "multi,push,multi")
2250 (set_attr "unit" "i387,*,*")
2251 (set_attr "mode" "SF,DI,SF")])
2254 [(set (match_operand:SF 0 "push_operand" "")
2255 (match_operand:SF 1 "memory_operand" ""))]
2257 && GET_CODE (operands[1]) == MEM
2258 && constant_pool_reference_p (operands[1])"
2261 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2264 ;; %%% Kill this when call knows how to work this out.
2266 [(set (match_operand:SF 0 "push_operand" "")
2267 (match_operand:SF 1 "any_fp_register_operand" ""))]
2269 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2270 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2273 [(set (match_operand:SF 0 "push_operand" "")
2274 (match_operand:SF 1 "any_fp_register_operand" ""))]
2276 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2277 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2279 (define_insn "*movsf_1"
2280 [(set (match_operand:SF 0 "nonimmediate_operand"
2281 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2282 (match_operand:SF 1 "general_operand"
2283 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2284 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2285 && (reload_in_progress || reload_completed
2286 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2287 || GET_CODE (operands[1]) != CONST_DOUBLE
2288 || memory_operand (operands[0], SFmode))"
2290 switch (which_alternative)
2293 return output_387_reg_move (insn, operands);
2296 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2297 return "fstp%z0\t%y0";
2299 return "fst%z0\t%y0";
2302 return standard_80387_constant_opcode (operands[1]);
2306 return "mov{l}\t{%1, %0|%0, %1}";
2308 if (get_attr_mode (insn) == MODE_TI)
2309 return "pxor\t%0, %0";
2311 return "xorps\t%0, %0";
2313 if (get_attr_mode (insn) == MODE_V4SF)
2314 return "movaps\t{%1, %0|%0, %1}";
2316 return "movss\t{%1, %0|%0, %1}";
2319 return "movss\t{%1, %0|%0, %1}";
2323 return "movd\t{%1, %0|%0, %1}";
2326 return "movq\t{%1, %0|%0, %1}";
2332 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2334 (cond [(eq_attr "alternative" "3,4,9,10")
2336 (eq_attr "alternative" "5")
2338 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2340 (ne (symbol_ref "TARGET_SSE2")
2342 (eq (symbol_ref "optimize_size")
2345 (const_string "V4SF"))
2346 /* For architectures resolving dependencies on
2347 whole SSE registers use APS move to break dependency
2348 chains, otherwise use short move to avoid extra work.
2350 Do the same for architectures resolving dependencies on
2351 the parts. While in DF mode it is better to always handle
2352 just register parts, the SF mode is different due to lack
2353 of instructions to load just part of the register. It is
2354 better to maintain the whole registers in single format
2355 to avoid problems on using packed logical operations. */
2356 (eq_attr "alternative" "6")
2358 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2360 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2362 (const_string "V4SF")
2363 (const_string "SF"))
2364 (eq_attr "alternative" "11")
2365 (const_string "DI")]
2366 (const_string "SF")))])
2368 (define_insn "*swapsf"
2369 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2370 (match_operand:SF 1 "fp_register_operand" "+f"))
2373 "reload_completed || TARGET_80387"
2375 if (STACK_TOP_P (operands[0]))
2380 [(set_attr "type" "fxch")
2381 (set_attr "mode" "SF")])
2383 (define_expand "movdf"
2384 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2385 (match_operand:DF 1 "general_operand" ""))]
2387 "ix86_expand_move (DFmode, operands); DONE;")
2389 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2390 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2391 ;; On the average, pushdf using integers can be still shorter. Allow this
2392 ;; pattern for optimize_size too.
2394 (define_insn "*pushdf_nointeger"
2395 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2396 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2397 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2399 /* This insn should be already split before reg-stack. */
2402 [(set_attr "type" "multi")
2403 (set_attr "unit" "i387,*,*,*")
2404 (set_attr "mode" "DF,SI,SI,DF")])
2406 (define_insn "*pushdf_integer"
2407 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2408 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2409 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2411 /* This insn should be already split before reg-stack. */
2414 [(set_attr "type" "multi")
2415 (set_attr "unit" "i387,*,*")
2416 (set_attr "mode" "DF,SI,DF")])
2418 ;; %%% Kill this when call knows how to work this out.
2420 [(set (match_operand:DF 0 "push_operand" "")
2421 (match_operand:DF 1 "any_fp_register_operand" ""))]
2422 "!TARGET_64BIT && reload_completed"
2423 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2424 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2428 [(set (match_operand:DF 0 "push_operand" "")
2429 (match_operand:DF 1 "any_fp_register_operand" ""))]
2430 "TARGET_64BIT && reload_completed"
2431 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2432 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2436 [(set (match_operand:DF 0 "push_operand" "")
2437 (match_operand:DF 1 "general_operand" ""))]
2440 "ix86_split_long_move (operands); DONE;")
2442 ;; Moving is usually shorter when only FP registers are used. This separate
2443 ;; movdf pattern avoids the use of integer registers for FP operations
2444 ;; when optimizing for size.
2446 (define_insn "*movdf_nointeger"
2447 [(set (match_operand:DF 0 "nonimmediate_operand"
2448 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2449 (match_operand:DF 1 "general_operand"
2450 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2451 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2452 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2453 && (reload_in_progress || reload_completed
2454 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2455 || GET_CODE (operands[1]) != CONST_DOUBLE
2456 || memory_operand (operands[0], DFmode))"
2458 switch (which_alternative)
2461 return output_387_reg_move (insn, operands);
2464 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2465 return "fstp%z0\t%y0";
2467 return "fst%z0\t%y0";
2470 return standard_80387_constant_opcode (operands[1]);
2476 switch (get_attr_mode (insn))
2479 return "xorps\t%0, %0";
2481 return "xorpd\t%0, %0";
2483 return "pxor\t%0, %0";
2490 switch (get_attr_mode (insn))
2493 return "movaps\t{%1, %0|%0, %1}";
2495 return "movapd\t{%1, %0|%0, %1}";
2497 return "movdqa\t{%1, %0|%0, %1}";
2499 return "movq\t{%1, %0|%0, %1}";
2501 return "movsd\t{%1, %0|%0, %1}";
2503 return "movlpd\t{%1, %0|%0, %1}";
2505 return "movlps\t{%1, %0|%0, %1}";
2514 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2516 (cond [(eq_attr "alternative" "0,1,2")
2518 (eq_attr "alternative" "3,4")
2521 /* For SSE1, we have many fewer alternatives. */
2522 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2523 (cond [(eq_attr "alternative" "5,6")
2524 (const_string "V4SF")
2526 (const_string "V2SF"))
2528 /* xorps is one byte shorter. */
2529 (eq_attr "alternative" "5")
2530 (cond [(ne (symbol_ref "optimize_size")
2532 (const_string "V4SF")
2533 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2537 (const_string "V2DF"))
2539 /* For architectures resolving dependencies on
2540 whole SSE registers use APD move to break dependency
2541 chains, otherwise use short move to avoid extra work.
2543 movaps encodes one byte shorter. */
2544 (eq_attr "alternative" "6")
2546 [(ne (symbol_ref "optimize_size")
2548 (const_string "V4SF")
2549 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2551 (const_string "V2DF")
2553 (const_string "DF"))
2554 /* For architectures resolving dependencies on register
2555 parts we may avoid extra work to zero out upper part
2557 (eq_attr "alternative" "7")
2559 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2561 (const_string "V1DF")
2562 (const_string "DF"))
2564 (const_string "DF")))])
2566 (define_insn "*movdf_integer"
2567 [(set (match_operand:DF 0 "nonimmediate_operand"
2568 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2569 (match_operand:DF 1 "general_operand"
2570 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2571 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2572 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2573 && (reload_in_progress || reload_completed
2574 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2575 || GET_CODE (operands[1]) != CONST_DOUBLE
2576 || memory_operand (operands[0], DFmode))"
2578 switch (which_alternative)
2581 return output_387_reg_move (insn, operands);
2584 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2585 return "fstp%z0\t%y0";
2587 return "fst%z0\t%y0";
2590 return standard_80387_constant_opcode (operands[1]);
2597 switch (get_attr_mode (insn))
2600 return "xorps\t%0, %0";
2602 return "xorpd\t%0, %0";
2604 return "pxor\t%0, %0";
2611 switch (get_attr_mode (insn))
2614 return "movaps\t{%1, %0|%0, %1}";
2616 return "movapd\t{%1, %0|%0, %1}";
2618 return "movdqa\t{%1, %0|%0, %1}";
2620 return "movq\t{%1, %0|%0, %1}";
2622 return "movsd\t{%1, %0|%0, %1}";
2624 return "movlpd\t{%1, %0|%0, %1}";
2626 return "movlps\t{%1, %0|%0, %1}";
2635 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2637 (cond [(eq_attr "alternative" "0,1,2")
2639 (eq_attr "alternative" "3,4")
2642 /* For SSE1, we have many fewer alternatives. */
2643 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2644 (cond [(eq_attr "alternative" "5,6")
2645 (const_string "V4SF")
2647 (const_string "V2SF"))
2649 /* xorps is one byte shorter. */
2650 (eq_attr "alternative" "5")
2651 (cond [(ne (symbol_ref "optimize_size")
2653 (const_string "V4SF")
2654 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2658 (const_string "V2DF"))
2660 /* For architectures resolving dependencies on
2661 whole SSE registers use APD move to break dependency
2662 chains, otherwise use short move to avoid extra work.
2664 movaps encodes one byte shorter. */
2665 (eq_attr "alternative" "6")
2667 [(ne (symbol_ref "optimize_size")
2669 (const_string "V4SF")
2670 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2672 (const_string "V2DF")
2674 (const_string "DF"))
2675 /* For architectures resolving dependencies on register
2676 parts we may avoid extra work to zero out upper part
2678 (eq_attr "alternative" "7")
2680 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2682 (const_string "V1DF")
2683 (const_string "DF"))
2685 (const_string "DF")))])
2688 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2689 (match_operand:DF 1 "general_operand" ""))]
2691 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2692 && ! (ANY_FP_REG_P (operands[0]) ||
2693 (GET_CODE (operands[0]) == SUBREG
2694 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2695 && ! (ANY_FP_REG_P (operands[1]) ||
2696 (GET_CODE (operands[1]) == SUBREG
2697 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2699 "ix86_split_long_move (operands); DONE;")
2701 (define_insn "*swapdf"
2702 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2703 (match_operand:DF 1 "fp_register_operand" "+f"))
2706 "reload_completed || TARGET_80387"
2708 if (STACK_TOP_P (operands[0]))
2713 [(set_attr "type" "fxch")
2714 (set_attr "mode" "DF")])
2716 (define_expand "movxf"
2717 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2718 (match_operand:XF 1 "general_operand" ""))]
2720 "ix86_expand_move (XFmode, operands); DONE;")
2722 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2723 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2724 ;; Pushing using integer instructions is longer except for constants
2725 ;; and direct memory references.
2726 ;; (assuming that any given constant is pushed only once, but this ought to be
2727 ;; handled elsewhere).
2729 (define_insn "*pushxf_nointeger"
2730 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2731 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2734 /* This insn should be already split before reg-stack. */
2737 [(set_attr "type" "multi")
2738 (set_attr "unit" "i387,*,*")
2739 (set_attr "mode" "XF,SI,SI")])
2741 (define_insn "*pushxf_integer"
2742 [(set (match_operand:XF 0 "push_operand" "=<,<")
2743 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2746 /* This insn should be already split before reg-stack. */
2749 [(set_attr "type" "multi")
2750 (set_attr "unit" "i387,*")
2751 (set_attr "mode" "XF,SI")])
2754 [(set (match_operand 0 "push_operand" "")
2755 (match_operand 1 "general_operand" ""))]
2757 && (GET_MODE (operands[0]) == XFmode
2758 || GET_MODE (operands[0]) == DFmode)
2759 && !ANY_FP_REG_P (operands[1])"
2761 "ix86_split_long_move (operands); DONE;")
2764 [(set (match_operand:XF 0 "push_operand" "")
2765 (match_operand:XF 1 "any_fp_register_operand" ""))]
2767 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2768 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2769 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2772 [(set (match_operand:XF 0 "push_operand" "")
2773 (match_operand:XF 1 "any_fp_register_operand" ""))]
2775 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2776 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2777 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2779 ;; Do not use integer registers when optimizing for size
2780 (define_insn "*movxf_nointeger"
2781 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2782 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2784 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2785 && (reload_in_progress || reload_completed
2786 || GET_CODE (operands[1]) != CONST_DOUBLE
2787 || memory_operand (operands[0], XFmode))"
2789 switch (which_alternative)
2792 return output_387_reg_move (insn, operands);
2795 /* There is no non-popping store to memory for XFmode. So if
2796 we need one, follow the store with a load. */
2797 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2798 return "fstp%z0\t%y0\;fld%z0\t%y0";
2800 return "fstp%z0\t%y0";
2803 return standard_80387_constant_opcode (operands[1]);
2811 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2812 (set_attr "mode" "XF,XF,XF,SI,SI")])
2814 (define_insn "*movxf_integer"
2815 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2816 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2818 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2819 && (reload_in_progress || reload_completed
2820 || GET_CODE (operands[1]) != CONST_DOUBLE
2821 || memory_operand (operands[0], XFmode))"
2823 switch (which_alternative)
2826 return output_387_reg_move (insn, operands);
2829 /* There is no non-popping store to memory for XFmode. So if
2830 we need one, follow the store with a load. */
2831 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2832 return "fstp%z0\t%y0\;fld%z0\t%y0";
2834 return "fstp%z0\t%y0";
2837 return standard_80387_constant_opcode (operands[1]);
2846 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2847 (set_attr "mode" "XF,XF,XF,SI,SI")])
2850 [(set (match_operand 0 "nonimmediate_operand" "")
2851 (match_operand 1 "general_operand" ""))]
2853 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2854 && GET_MODE (operands[0]) == XFmode
2855 && ! (ANY_FP_REG_P (operands[0]) ||
2856 (GET_CODE (operands[0]) == SUBREG
2857 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2858 && ! (ANY_FP_REG_P (operands[1]) ||
2859 (GET_CODE (operands[1]) == SUBREG
2860 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2862 "ix86_split_long_move (operands); DONE;")
2865 [(set (match_operand 0 "register_operand" "")
2866 (match_operand 1 "memory_operand" ""))]
2868 && GET_CODE (operands[1]) == MEM
2869 && (GET_MODE (operands[0]) == XFmode
2870 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2871 && constant_pool_reference_p (operands[1])"
2872 [(set (match_dup 0) (match_dup 1))]
2874 rtx c = avoid_constant_pool_reference (operands[1]);
2875 rtx r = operands[0];
2877 if (GET_CODE (r) == SUBREG)
2882 if (!standard_sse_constant_p (c))
2885 else if (FP_REG_P (r))
2887 if (!standard_80387_constant_p (c))
2890 else if (MMX_REG_P (r))
2896 (define_insn "swapxf"
2897 [(set (match_operand:XF 0 "register_operand" "+f")
2898 (match_operand:XF 1 "register_operand" "+f"))
2903 if (STACK_TOP_P (operands[0]))
2908 [(set_attr "type" "fxch")
2909 (set_attr "mode" "XF")])
2911 (define_expand "movtf"
2912 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2913 (match_operand:TF 1 "nonimmediate_operand" ""))]
2916 ix86_expand_move (TFmode, operands);
2920 (define_insn "*movtf_internal"
2921 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2922 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2924 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2926 switch (which_alternative)
2932 if (get_attr_mode (insn) == MODE_V4SF)
2933 return "xorps\t%0, %0";
2935 return "pxor\t%0, %0";
2938 if (get_attr_mode (insn) == MODE_V4SF)
2939 return "movaps\t{%1, %0|%0, %1}";
2941 return "movdqa\t{%1, %0|%0, %1}";
2946 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2948 (cond [(eq_attr "alternative" "2,3")
2950 (ne (symbol_ref "optimize_size")
2952 (const_string "V4SF")
2953 (const_string "TI"))
2954 (eq_attr "alternative" "4")
2956 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2958 (ne (symbol_ref "optimize_size")
2960 (const_string "V4SF")
2961 (const_string "TI"))]
2962 (const_string "DI")))])
2965 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2966 (match_operand:TF 1 "general_operand" ""))]
2967 "reload_completed && !SSE_REG_P (operands[0])
2968 && !SSE_REG_P (operands[1])"
2970 "ix86_split_long_move (operands); DONE;")
2972 ;; Zero extension instructions
2974 (define_expand "zero_extendhisi2"
2975 [(set (match_operand:SI 0 "register_operand" "")
2976 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2979 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2981 operands[1] = force_reg (HImode, operands[1]);
2982 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2987 (define_insn "zero_extendhisi2_and"
2988 [(set (match_operand:SI 0 "register_operand" "=r")
2989 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2990 (clobber (reg:CC FLAGS_REG))]
2991 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2993 [(set_attr "type" "alu1")
2994 (set_attr "mode" "SI")])
2997 [(set (match_operand:SI 0 "register_operand" "")
2998 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2999 (clobber (reg:CC FLAGS_REG))]
3000 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3001 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3002 (clobber (reg:CC FLAGS_REG))])]
3005 (define_insn "*zero_extendhisi2_movzwl"
3006 [(set (match_operand:SI 0 "register_operand" "=r")
3007 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3008 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3009 "movz{wl|x}\t{%1, %0|%0, %1}"
3010 [(set_attr "type" "imovx")
3011 (set_attr "mode" "SI")])
3013 (define_expand "zero_extendqihi2"
3015 [(set (match_operand:HI 0 "register_operand" "")
3016 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3017 (clobber (reg:CC FLAGS_REG))])]
3021 (define_insn "*zero_extendqihi2_and"
3022 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3023 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3024 (clobber (reg:CC FLAGS_REG))]
3025 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3027 [(set_attr "type" "alu1")
3028 (set_attr "mode" "HI")])
3030 (define_insn "*zero_extendqihi2_movzbw_and"
3031 [(set (match_operand:HI 0 "register_operand" "=r,r")
3032 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3033 (clobber (reg:CC FLAGS_REG))]
3034 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3036 [(set_attr "type" "imovx,alu1")
3037 (set_attr "mode" "HI")])
3039 (define_insn "*zero_extendqihi2_movzbw"
3040 [(set (match_operand:HI 0 "register_operand" "=r")
3041 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3042 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3043 "movz{bw|x}\t{%1, %0|%0, %1}"
3044 [(set_attr "type" "imovx")
3045 (set_attr "mode" "HI")])
3047 ;; For the movzbw case strip only the clobber
3049 [(set (match_operand:HI 0 "register_operand" "")
3050 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3051 (clobber (reg:CC FLAGS_REG))]
3053 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3054 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3055 [(set (match_operand:HI 0 "register_operand" "")
3056 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3058 ;; When source and destination does not overlap, clear destination
3059 ;; first and then do the movb
3061 [(set (match_operand:HI 0 "register_operand" "")
3062 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3063 (clobber (reg:CC FLAGS_REG))]
3065 && ANY_QI_REG_P (operands[0])
3066 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3067 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3068 [(set (match_dup 0) (const_int 0))
3069 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3070 "operands[2] = gen_lowpart (QImode, operands[0]);")
3072 ;; Rest is handled by single and.
3074 [(set (match_operand:HI 0 "register_operand" "")
3075 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3076 (clobber (reg:CC FLAGS_REG))]
3078 && true_regnum (operands[0]) == true_regnum (operands[1])"
3079 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3080 (clobber (reg:CC FLAGS_REG))])]
3083 (define_expand "zero_extendqisi2"
3085 [(set (match_operand:SI 0 "register_operand" "")
3086 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3087 (clobber (reg:CC FLAGS_REG))])]
3091 (define_insn "*zero_extendqisi2_and"
3092 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3093 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3094 (clobber (reg:CC FLAGS_REG))]
3095 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3097 [(set_attr "type" "alu1")
3098 (set_attr "mode" "SI")])
3100 (define_insn "*zero_extendqisi2_movzbw_and"
3101 [(set (match_operand:SI 0 "register_operand" "=r,r")
3102 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3103 (clobber (reg:CC FLAGS_REG))]
3104 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3106 [(set_attr "type" "imovx,alu1")
3107 (set_attr "mode" "SI")])
3109 (define_insn "*zero_extendqisi2_movzbw"
3110 [(set (match_operand:SI 0 "register_operand" "=r")
3111 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3112 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3113 "movz{bl|x}\t{%1, %0|%0, %1}"
3114 [(set_attr "type" "imovx")
3115 (set_attr "mode" "SI")])
3117 ;; For the movzbl case strip only the clobber
3119 [(set (match_operand:SI 0 "register_operand" "")
3120 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3121 (clobber (reg:CC FLAGS_REG))]
3123 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3124 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3126 (zero_extend:SI (match_dup 1)))])
3128 ;; When source and destination does not overlap, clear destination
3129 ;; first and then do the movb
3131 [(set (match_operand:SI 0 "register_operand" "")
3132 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3133 (clobber (reg:CC FLAGS_REG))]
3135 && ANY_QI_REG_P (operands[0])
3136 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3137 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3138 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3139 [(set (match_dup 0) (const_int 0))
3140 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3141 "operands[2] = gen_lowpart (QImode, operands[0]);")
3143 ;; Rest is handled by single and.
3145 [(set (match_operand:SI 0 "register_operand" "")
3146 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3147 (clobber (reg:CC FLAGS_REG))]
3149 && true_regnum (operands[0]) == true_regnum (operands[1])"
3150 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3151 (clobber (reg:CC FLAGS_REG))])]
3154 ;; %%% Kill me once multi-word ops are sane.
3155 (define_expand "zero_extendsidi2"
3156 [(set (match_operand:DI 0 "register_operand" "=r")
3157 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3161 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3166 (define_insn "zero_extendsidi2_32"
3167 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3168 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3169 (clobber (reg:CC FLAGS_REG))]
3175 movd\t{%1, %0|%0, %1}
3176 movd\t{%1, %0|%0, %1}"
3177 [(set_attr "mode" "SI,SI,SI,DI,TI")
3178 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3180 (define_insn "zero_extendsidi2_rex64"
3181 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3182 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3185 mov\t{%k1, %k0|%k0, %k1}
3187 movd\t{%1, %0|%0, %1}
3188 movd\t{%1, %0|%0, %1}"
3189 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3190 (set_attr "mode" "SI,DI,SI,SI")])
3193 [(set (match_operand:DI 0 "memory_operand" "")
3194 (zero_extend:DI (match_dup 0)))]
3196 [(set (match_dup 4) (const_int 0))]
3197 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3200 [(set (match_operand:DI 0 "register_operand" "")
3201 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3202 (clobber (reg:CC FLAGS_REG))]
3203 "!TARGET_64BIT && reload_completed
3204 && true_regnum (operands[0]) == true_regnum (operands[1])"
3205 [(set (match_dup 4) (const_int 0))]
3206 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3209 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3210 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3211 (clobber (reg:CC FLAGS_REG))]
3212 "!TARGET_64BIT && reload_completed
3213 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3214 [(set (match_dup 3) (match_dup 1))
3215 (set (match_dup 4) (const_int 0))]
3216 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3218 (define_insn "zero_extendhidi2"
3219 [(set (match_operand:DI 0 "register_operand" "=r")
3220 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3222 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3223 [(set_attr "type" "imovx")
3224 (set_attr "mode" "DI")])
3226 (define_insn "zero_extendqidi2"
3227 [(set (match_operand:DI 0 "register_operand" "=r")
3228 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3230 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3231 [(set_attr "type" "imovx")
3232 (set_attr "mode" "DI")])
3234 ;; Sign extension instructions
3236 (define_expand "extendsidi2"
3237 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3238 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3239 (clobber (reg:CC FLAGS_REG))
3240 (clobber (match_scratch:SI 2 ""))])]
3245 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3250 (define_insn "*extendsidi2_1"
3251 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3252 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3253 (clobber (reg:CC FLAGS_REG))
3254 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3258 (define_insn "extendsidi2_rex64"
3259 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3260 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3264 movs{lq|x}\t{%1,%0|%0, %1}"
3265 [(set_attr "type" "imovx")
3266 (set_attr "mode" "DI")
3267 (set_attr "prefix_0f" "0")
3268 (set_attr "modrm" "0,1")])
3270 (define_insn "extendhidi2"
3271 [(set (match_operand:DI 0 "register_operand" "=r")
3272 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3274 "movs{wq|x}\t{%1,%0|%0, %1}"
3275 [(set_attr "type" "imovx")
3276 (set_attr "mode" "DI")])
3278 (define_insn "extendqidi2"
3279 [(set (match_operand:DI 0 "register_operand" "=r")
3280 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3282 "movs{bq|x}\t{%1,%0|%0, %1}"
3283 [(set_attr "type" "imovx")
3284 (set_attr "mode" "DI")])
3286 ;; Extend to memory case when source register does die.
3288 [(set (match_operand:DI 0 "memory_operand" "")
3289 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3290 (clobber (reg:CC FLAGS_REG))
3291 (clobber (match_operand:SI 2 "register_operand" ""))]
3293 && dead_or_set_p (insn, operands[1])
3294 && !reg_mentioned_p (operands[1], operands[0]))"
3295 [(set (match_dup 3) (match_dup 1))
3296 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3297 (clobber (reg:CC FLAGS_REG))])
3298 (set (match_dup 4) (match_dup 1))]
3299 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3301 ;; Extend to memory case when source register does not die.
3303 [(set (match_operand:DI 0 "memory_operand" "")
3304 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3305 (clobber (reg:CC FLAGS_REG))
3306 (clobber (match_operand:SI 2 "register_operand" ""))]
3310 split_di (&operands[0], 1, &operands[3], &operands[4]);
3312 emit_move_insn (operands[3], operands[1]);
3314 /* Generate a cltd if possible and doing so it profitable. */
3315 if (true_regnum (operands[1]) == 0
3316 && true_regnum (operands[2]) == 1
3317 && (optimize_size || TARGET_USE_CLTD))
3319 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3323 emit_move_insn (operands[2], operands[1]);
3324 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3326 emit_move_insn (operands[4], operands[2]);
3330 ;; Extend to register case. Optimize case where source and destination
3331 ;; registers match and cases where we can use cltd.
3333 [(set (match_operand:DI 0 "register_operand" "")
3334 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3335 (clobber (reg:CC FLAGS_REG))
3336 (clobber (match_scratch:SI 2 ""))]
3340 split_di (&operands[0], 1, &operands[3], &operands[4]);
3342 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3343 emit_move_insn (operands[3], operands[1]);
3345 /* Generate a cltd if possible and doing so it profitable. */
3346 if (true_regnum (operands[3]) == 0
3347 && (optimize_size || TARGET_USE_CLTD))
3349 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3353 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3354 emit_move_insn (operands[4], operands[1]);
3356 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3360 (define_insn "extendhisi2"
3361 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3362 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3365 switch (get_attr_prefix_0f (insn))
3368 return "{cwtl|cwde}";
3370 return "movs{wl|x}\t{%1,%0|%0, %1}";
3373 [(set_attr "type" "imovx")
3374 (set_attr "mode" "SI")
3375 (set (attr "prefix_0f")
3376 ;; movsx is short decodable while cwtl is vector decoded.
3377 (if_then_else (and (eq_attr "cpu" "!k6")
3378 (eq_attr "alternative" "0"))
3380 (const_string "1")))
3382 (if_then_else (eq_attr "prefix_0f" "0")
3384 (const_string "1")))])
3386 (define_insn "*extendhisi2_zext"
3387 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3389 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3392 switch (get_attr_prefix_0f (insn))
3395 return "{cwtl|cwde}";
3397 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3400 [(set_attr "type" "imovx")
3401 (set_attr "mode" "SI")
3402 (set (attr "prefix_0f")
3403 ;; movsx is short decodable while cwtl is vector decoded.
3404 (if_then_else (and (eq_attr "cpu" "!k6")
3405 (eq_attr "alternative" "0"))
3407 (const_string "1")))
3409 (if_then_else (eq_attr "prefix_0f" "0")
3411 (const_string "1")))])
3413 (define_insn "extendqihi2"
3414 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3415 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3418 switch (get_attr_prefix_0f (insn))
3421 return "{cbtw|cbw}";
3423 return "movs{bw|x}\t{%1,%0|%0, %1}";
3426 [(set_attr "type" "imovx")
3427 (set_attr "mode" "HI")
3428 (set (attr "prefix_0f")
3429 ;; movsx is short decodable while cwtl is vector decoded.
3430 (if_then_else (and (eq_attr "cpu" "!k6")
3431 (eq_attr "alternative" "0"))
3433 (const_string "1")))
3435 (if_then_else (eq_attr "prefix_0f" "0")
3437 (const_string "1")))])
3439 (define_insn "extendqisi2"
3440 [(set (match_operand:SI 0 "register_operand" "=r")
3441 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3443 "movs{bl|x}\t{%1,%0|%0, %1}"
3444 [(set_attr "type" "imovx")
3445 (set_attr "mode" "SI")])
3447 (define_insn "*extendqisi2_zext"
3448 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3452 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3453 [(set_attr "type" "imovx")
3454 (set_attr "mode" "SI")])
3456 ;; Conversions between float and double.
3458 ;; These are all no-ops in the model used for the 80387. So just
3461 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3462 (define_insn "*dummy_extendsfdf2"
3463 [(set (match_operand:DF 0 "push_operand" "=<")
3464 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3469 [(set (match_operand:DF 0 "push_operand" "")
3470 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3472 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3473 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3476 [(set (match_operand:DF 0 "push_operand" "")
3477 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3479 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3480 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3482 (define_insn "*dummy_extendsfxf2"
3483 [(set (match_operand:XF 0 "push_operand" "=<")
3484 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3489 [(set (match_operand:XF 0 "push_operand" "")
3490 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3492 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3493 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3494 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3497 [(set (match_operand:XF 0 "push_operand" "")
3498 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3500 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3501 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3502 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3505 [(set (match_operand:XF 0 "push_operand" "")
3506 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3508 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3509 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3510 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3513 [(set (match_operand:XF 0 "push_operand" "")
3514 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3516 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3517 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3518 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3520 (define_expand "extendsfdf2"
3521 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3522 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3523 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3525 /* ??? Needed for compress_float_constant since all fp constants
3526 are LEGITIMATE_CONSTANT_P. */
3527 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3528 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3529 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3530 operands[1] = force_reg (SFmode, operands[1]);
3533 (define_insn "*extendsfdf2_mixed"
3534 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3535 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3536 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3537 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3539 switch (which_alternative)
3542 return output_387_reg_move (insn, operands);
3545 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3546 return "fstp%z0\t%y0";
3548 return "fst%z0\t%y0";
3551 return "cvtss2sd\t{%1, %0|%0, %1}";
3557 [(set_attr "type" "fmov,fmov,ssecvt")
3558 (set_attr "mode" "SF,XF,DF")])
3560 (define_insn "*extendsfdf2_sse"
3561 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3562 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3563 "TARGET_SSE2 && TARGET_SSE_MATH
3564 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3565 "cvtss2sd\t{%1, %0|%0, %1}"
3566 [(set_attr "type" "ssecvt")
3567 (set_attr "mode" "DF")])
3569 (define_insn "*extendsfdf2_i387"
3570 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3571 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3573 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3575 switch (which_alternative)
3578 return output_387_reg_move (insn, operands);
3581 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3582 return "fstp%z0\t%y0";
3584 return "fst%z0\t%y0";
3590 [(set_attr "type" "fmov")
3591 (set_attr "mode" "SF,XF")])
3593 (define_expand "extendsfxf2"
3594 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3595 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3598 /* ??? Needed for compress_float_constant since all fp constants
3599 are LEGITIMATE_CONSTANT_P. */
3600 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3601 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3602 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3603 operands[1] = force_reg (SFmode, operands[1]);
3606 (define_insn "*extendsfxf2_i387"
3607 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3608 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3610 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3612 switch (which_alternative)
3615 return output_387_reg_move (insn, operands);
3618 /* There is no non-popping store to memory for XFmode. So if
3619 we need one, follow the store with a load. */
3620 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3621 return "fstp%z0\t%y0";
3623 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3629 [(set_attr "type" "fmov")
3630 (set_attr "mode" "SF,XF")])
3632 (define_expand "extenddfxf2"
3633 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3634 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3637 /* ??? Needed for compress_float_constant since all fp constants
3638 are LEGITIMATE_CONSTANT_P. */
3639 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3640 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3641 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3642 operands[1] = force_reg (DFmode, operands[1]);
3645 (define_insn "*extenddfxf2_i387"
3646 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3647 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3649 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3651 switch (which_alternative)
3654 return output_387_reg_move (insn, operands);
3657 /* There is no non-popping store to memory for XFmode. So if
3658 we need one, follow the store with a load. */
3659 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3660 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3662 return "fstp%z0\t%y0";
3668 [(set_attr "type" "fmov")
3669 (set_attr "mode" "DF,XF")])
3671 ;; %%% This seems bad bad news.
3672 ;; This cannot output into an f-reg because there is no way to be sure
3673 ;; of truncating in that case. Otherwise this is just like a simple move
3674 ;; insn. So we pretend we can output to a reg in order to get better
3675 ;; register preferencing, but we really use a stack slot.
3677 ;; Conversion from DFmode to SFmode.
3679 (define_expand "truncdfsf2"
3680 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3682 (match_operand:DF 1 "nonimmediate_operand" "")))]
3683 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3685 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3686 operands[1] = force_reg (DFmode, operands[1]);
3688 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3690 else if (flag_unsafe_math_optimizations)
3694 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3695 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3700 (define_expand "truncdfsf2_with_temp"
3701 [(parallel [(set (match_operand:SF 0 "" "")
3702 (float_truncate:SF (match_operand:DF 1 "" "")))
3703 (clobber (match_operand:SF 2 "" ""))])]
3706 (define_insn "*truncdfsf_fast_mixed"
3707 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3709 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3710 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3712 switch (which_alternative)
3715 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3716 return "fstp%z0\t%y0";
3718 return "fst%z0\t%y0";
3720 return output_387_reg_move (insn, operands);
3722 return "cvtsd2ss\t{%1, %0|%0, %1}";
3727 [(set_attr "type" "fmov,fmov,ssecvt")
3728 (set_attr "mode" "SF")])
3730 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3731 ;; because nothing we do here is unsafe.
3732 (define_insn "*truncdfsf_fast_sse"
3733 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3735 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3736 "TARGET_SSE2 && TARGET_SSE_MATH"
3737 "cvtsd2ss\t{%1, %0|%0, %1}"
3738 [(set_attr "type" "ssecvt")
3739 (set_attr "mode" "SF")])
3741 (define_insn "*truncdfsf_fast_i387"
3742 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3744 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3745 "TARGET_80387 && flag_unsafe_math_optimizations"
3746 "* return output_387_reg_move (insn, operands);"
3747 [(set_attr "type" "fmov")
3748 (set_attr "mode" "SF")])
3750 (define_insn "*truncdfsf_mixed"
3751 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3753 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3754 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3755 "TARGET_MIX_SSE_I387"
3757 switch (which_alternative)
3760 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3761 return "fstp%z0\t%y0";
3763 return "fst%z0\t%y0";
3767 return "cvtsd2ss\t{%1, %0|%0, %1}";
3772 [(set_attr "type" "fmov,multi,ssecvt")
3773 (set_attr "unit" "*,i387,*")
3774 (set_attr "mode" "SF")])
3776 (define_insn "*truncdfsf_i387"
3777 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3779 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3780 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3783 switch (which_alternative)
3786 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3787 return "fstp%z0\t%y0";
3789 return "fst%z0\t%y0";
3796 [(set_attr "type" "fmov,multi")
3797 (set_attr "unit" "*,i387")
3798 (set_attr "mode" "SF")])
3800 (define_insn "*truncdfsf2_i387_1"
3801 [(set (match_operand:SF 0 "memory_operand" "=m")
3803 (match_operand:DF 1 "register_operand" "f")))]
3805 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3806 && !TARGET_MIX_SSE_I387"
3808 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3809 return "fstp%z0\t%y0";
3811 return "fst%z0\t%y0";
3813 [(set_attr "type" "fmov")
3814 (set_attr "mode" "SF")])
3817 [(set (match_operand:SF 0 "register_operand" "")
3819 (match_operand:DF 1 "fp_register_operand" "")))
3820 (clobber (match_operand 2 "" ""))]
3822 [(set (match_dup 2) (match_dup 1))
3823 (set (match_dup 0) (match_dup 2))]
3825 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3828 ;; Conversion from XFmode to SFmode.
3830 (define_expand "truncxfsf2"
3831 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3833 (match_operand:XF 1 "register_operand" "")))
3834 (clobber (match_dup 2))])]
3837 if (flag_unsafe_math_optimizations)
3839 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3840 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3841 if (reg != operands[0])
3842 emit_move_insn (operands[0], reg);
3846 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3849 (define_insn "*truncxfsf2_mixed"
3850 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3852 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3853 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3854 "TARGET_MIX_SSE_I387"
3856 gcc_assert (!which_alternative);
3857 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3858 return "fstp%z0\t%y0";
3860 return "fst%z0\t%y0";
3862 [(set_attr "type" "fmov,multi,multi,multi")
3863 (set_attr "unit" "*,i387,i387,i387")
3864 (set_attr "mode" "SF")])
3866 (define_insn "truncxfsf2_i387_noop"
3867 [(set (match_operand:SF 0 "register_operand" "=f")
3868 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3869 "TARGET_80387 && flag_unsafe_math_optimizations"
3871 return output_387_reg_move (insn, operands);
3873 [(set_attr "type" "fmov")
3874 (set_attr "mode" "SF")])
3876 (define_insn "*truncxfsf2_i387"
3877 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3879 (match_operand:XF 1 "register_operand" "f,f,f")))
3880 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3883 gcc_assert (!which_alternative);
3884 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3885 return "fstp%z0\t%y0";
3887 return "fst%z0\t%y0";
3889 [(set_attr "type" "fmov,multi,multi")
3890 (set_attr "unit" "*,i387,i387")
3891 (set_attr "mode" "SF")])
3893 (define_insn "*truncxfsf2_i387_1"
3894 [(set (match_operand:SF 0 "memory_operand" "=m")
3896 (match_operand:XF 1 "register_operand" "f")))]
3899 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3900 return "fstp%z0\t%y0";
3902 return "fst%z0\t%y0";
3904 [(set_attr "type" "fmov")
3905 (set_attr "mode" "SF")])
3908 [(set (match_operand:SF 0 "register_operand" "")
3910 (match_operand:XF 1 "register_operand" "")))
3911 (clobber (match_operand:SF 2 "memory_operand" ""))]
3912 "TARGET_80387 && reload_completed"
3913 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3914 (set (match_dup 0) (match_dup 2))]
3918 [(set (match_operand:SF 0 "memory_operand" "")
3920 (match_operand:XF 1 "register_operand" "")))
3921 (clobber (match_operand:SF 2 "memory_operand" ""))]
3923 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3926 ;; Conversion from XFmode to DFmode.
3928 (define_expand "truncxfdf2"
3929 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3931 (match_operand:XF 1 "register_operand" "")))
3932 (clobber (match_dup 2))])]
3935 if (flag_unsafe_math_optimizations)
3937 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3938 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3939 if (reg != operands[0])
3940 emit_move_insn (operands[0], reg);
3944 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3947 (define_insn "*truncxfdf2_mixed"
3948 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3950 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3951 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3952 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3954 gcc_assert (!which_alternative);
3955 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3956 return "fstp%z0\t%y0";
3958 return "fst%z0\t%y0";
3960 [(set_attr "type" "fmov,multi,multi,multi")
3961 (set_attr "unit" "*,i387,i387,i387")
3962 (set_attr "mode" "DF")])
3964 (define_insn "truncxfdf2_i387_noop"
3965 [(set (match_operand:DF 0 "register_operand" "=f")
3966 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3967 "TARGET_80387 && flag_unsafe_math_optimizations"
3969 return output_387_reg_move (insn, operands);
3971 [(set_attr "type" "fmov")
3972 (set_attr "mode" "DF")])
3974 (define_insn "*truncxfdf2_i387"
3975 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3977 (match_operand:XF 1 "register_operand" "f,f,f")))
3978 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3981 gcc_assert (!which_alternative);
3982 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3983 return "fstp%z0\t%y0";
3985 return "fst%z0\t%y0";
3987 [(set_attr "type" "fmov,multi,multi")
3988 (set_attr "unit" "*,i387,i387")
3989 (set_attr "mode" "DF")])
3991 (define_insn "*truncxfdf2_i387_1"
3992 [(set (match_operand:DF 0 "memory_operand" "=m")
3994 (match_operand:XF 1 "register_operand" "f")))]
3997 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3998 return "fstp%z0\t%y0";
4000 return "fst%z0\t%y0";
4002 [(set_attr "type" "fmov")
4003 (set_attr "mode" "DF")])
4006 [(set (match_operand:DF 0 "register_operand" "")
4008 (match_operand:XF 1 "register_operand" "")))
4009 (clobber (match_operand:DF 2 "memory_operand" ""))]
4010 "TARGET_80387 && reload_completed"
4011 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4012 (set (match_dup 0) (match_dup 2))]
4016 [(set (match_operand:DF 0 "memory_operand" "")
4018 (match_operand:XF 1 "register_operand" "")))
4019 (clobber (match_operand:DF 2 "memory_operand" ""))]
4021 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4024 ;; Signed conversion to DImode.
4026 (define_expand "fix_truncxfdi2"
4027 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028 (fix:DI (match_operand:XF 1 "register_operand" "")))
4029 (clobber (reg:CC FLAGS_REG))])]
4034 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4039 (define_expand "fix_trunc<mode>di2"
4040 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4041 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4042 (clobber (reg:CC FLAGS_REG))])]
4043 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4046 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4048 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4051 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4053 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4054 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4055 if (out != operands[0])
4056 emit_move_insn (operands[0], out);
4061 ;; Signed conversion to SImode.
4063 (define_expand "fix_truncxfsi2"
4064 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4065 (fix:SI (match_operand:XF 1 "register_operand" "")))
4066 (clobber (reg:CC FLAGS_REG))])]
4071 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4076 (define_expand "fix_trunc<mode>si2"
4077 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4078 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4079 (clobber (reg:CC FLAGS_REG))])]
4080 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4083 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4085 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4088 if (SSE_FLOAT_MODE_P (<MODE>mode))
4090 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4091 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4092 if (out != operands[0])
4093 emit_move_insn (operands[0], out);
4098 ;; Signed conversion to HImode.
4100 (define_expand "fix_trunc<mode>hi2"
4101 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4102 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4103 (clobber (reg:CC FLAGS_REG))])]
4105 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4109 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4114 ;; When SSE is available, it is always faster to use it!
4115 (define_insn "fix_truncsfdi_sse"
4116 [(set (match_operand:DI 0 "register_operand" "=r,r")
4117 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4118 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4119 "cvttss2si{q}\t{%1, %0|%0, %1}"
4120 [(set_attr "type" "sseicvt")
4121 (set_attr "mode" "SF")
4122 (set_attr "athlon_decode" "double,vector")])
4124 (define_insn "fix_truncdfdi_sse"
4125 [(set (match_operand:DI 0 "register_operand" "=r,r")
4126 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4127 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4128 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4129 [(set_attr "type" "sseicvt")
4130 (set_attr "mode" "DF")
4131 (set_attr "athlon_decode" "double,vector")])
4133 (define_insn "fix_truncsfsi_sse"
4134 [(set (match_operand:SI 0 "register_operand" "=r,r")
4135 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4136 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4137 "cvttss2si\t{%1, %0|%0, %1}"
4138 [(set_attr "type" "sseicvt")
4139 (set_attr "mode" "DF")
4140 (set_attr "athlon_decode" "double,vector")])
4142 (define_insn "fix_truncdfsi_sse"
4143 [(set (match_operand:SI 0 "register_operand" "=r,r")
4144 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4145 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4146 "cvttsd2si\t{%1, %0|%0, %1}"
4147 [(set_attr "type" "sseicvt")
4148 (set_attr "mode" "DF")
4149 (set_attr "athlon_decode" "double,vector")])
4151 ;; Avoid vector decoded forms of the instruction.
4153 [(match_scratch:DF 2 "Y")
4154 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4155 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4156 "TARGET_K8 && !optimize_size"
4157 [(set (match_dup 2) (match_dup 1))
4158 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4162 [(match_scratch:SF 2 "x")
4163 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4164 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4165 "TARGET_K8 && !optimize_size"
4166 [(set (match_dup 2) (match_dup 1))
4167 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4170 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4171 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4172 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4174 && FLOAT_MODE_P (GET_MODE (operands[1]))
4175 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4176 && (TARGET_64BIT || <MODE>mode != DImode))
4178 && !(reload_completed || reload_in_progress)"
4183 if (memory_operand (operands[0], VOIDmode))
4184 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4187 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4188 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4194 [(set_attr "type" "fisttp")
4195 (set_attr "mode" "<MODE>")])
4197 (define_insn "fix_trunc<mode>_i387_fisttp"
4198 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4199 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4200 (clobber (match_scratch:XF 2 "=&1f"))]
4202 && FLOAT_MODE_P (GET_MODE (operands[1]))
4203 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4204 && (TARGET_64BIT || <MODE>mode != DImode))
4205 && TARGET_SSE_MATH)"
4206 "* return output_fix_trunc (insn, operands, 1);"
4207 [(set_attr "type" "fisttp")
4208 (set_attr "mode" "<MODE>")])
4210 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4211 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4212 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4213 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4214 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4216 && FLOAT_MODE_P (GET_MODE (operands[1]))
4217 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4218 && (TARGET_64BIT || <MODE>mode != DImode))
4219 && TARGET_SSE_MATH)"
4221 [(set_attr "type" "fisttp")
4222 (set_attr "mode" "<MODE>")])
4225 [(set (match_operand:X87MODEI 0 "register_operand" "")
4226 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4227 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4228 (clobber (match_scratch 3 ""))]
4230 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4231 (clobber (match_dup 3))])
4232 (set (match_dup 0) (match_dup 2))]
4236 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4237 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4238 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4239 (clobber (match_scratch 3 ""))]
4241 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4242 (clobber (match_dup 3))])]
4245 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4246 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4247 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4248 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4249 ;; function in i386.c.
4250 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4251 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4253 (clobber (reg:CC FLAGS_REG))]
4254 "TARGET_80387 && !TARGET_FISTTP
4255 && FLOAT_MODE_P (GET_MODE (operands[1]))
4256 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4257 && (TARGET_64BIT || <MODE>mode != DImode))
4258 && !(reload_completed || reload_in_progress)"
4263 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4265 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4266 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4267 if (memory_operand (operands[0], VOIDmode))
4268 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4269 operands[2], operands[3]));
4272 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4273 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4274 operands[2], operands[3],
4279 [(set_attr "type" "fistp")
4280 (set_attr "i387_cw" "trunc")
4281 (set_attr "mode" "<MODE>")])
4283 (define_insn "fix_truncdi_i387"
4284 [(set (match_operand:DI 0 "memory_operand" "=m")
4285 (fix:DI (match_operand 1 "register_operand" "f")))
4286 (use (match_operand:HI 2 "memory_operand" "m"))
4287 (use (match_operand:HI 3 "memory_operand" "m"))
4288 (clobber (match_scratch:XF 4 "=&1f"))]
4289 "TARGET_80387 && !TARGET_FISTTP
4290 && FLOAT_MODE_P (GET_MODE (operands[1]))
4291 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4292 "* return output_fix_trunc (insn, operands, 0);"
4293 [(set_attr "type" "fistp")
4294 (set_attr "i387_cw" "trunc")
4295 (set_attr "mode" "DI")])
4297 (define_insn "fix_truncdi_i387_with_temp"
4298 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4299 (fix:DI (match_operand 1 "register_operand" "f,f")))
4300 (use (match_operand:HI 2 "memory_operand" "m,m"))
4301 (use (match_operand:HI 3 "memory_operand" "m,m"))
4302 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4303 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4304 "TARGET_80387 && !TARGET_FISTTP
4305 && FLOAT_MODE_P (GET_MODE (operands[1]))
4306 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4308 [(set_attr "type" "fistp")
4309 (set_attr "i387_cw" "trunc")
4310 (set_attr "mode" "DI")])
4313 [(set (match_operand:DI 0 "register_operand" "")
4314 (fix:DI (match_operand 1 "register_operand" "")))
4315 (use (match_operand:HI 2 "memory_operand" ""))
4316 (use (match_operand:HI 3 "memory_operand" ""))
4317 (clobber (match_operand:DI 4 "memory_operand" ""))
4318 (clobber (match_scratch 5 ""))]
4320 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4323 (clobber (match_dup 5))])
4324 (set (match_dup 0) (match_dup 4))]
4328 [(set (match_operand:DI 0 "memory_operand" "")
4329 (fix:DI (match_operand 1 "register_operand" "")))
4330 (use (match_operand:HI 2 "memory_operand" ""))
4331 (use (match_operand:HI 3 "memory_operand" ""))
4332 (clobber (match_operand:DI 4 "memory_operand" ""))
4333 (clobber (match_scratch 5 ""))]
4335 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4338 (clobber (match_dup 5))])]
4341 (define_insn "fix_trunc<mode>_i387"
4342 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4343 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4344 (use (match_operand:HI 2 "memory_operand" "m"))
4345 (use (match_operand:HI 3 "memory_operand" "m"))]
4346 "TARGET_80387 && !TARGET_FISTTP
4347 && FLOAT_MODE_P (GET_MODE (operands[1]))
4348 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4349 "* return output_fix_trunc (insn, operands, 0);"
4350 [(set_attr "type" "fistp")
4351 (set_attr "i387_cw" "trunc")
4352 (set_attr "mode" "<MODE>")])
4354 (define_insn "fix_trunc<mode>_i387_with_temp"
4355 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4356 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4357 (use (match_operand:HI 2 "memory_operand" "m,m"))
4358 (use (match_operand:HI 3 "memory_operand" "m,m"))
4359 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4360 "TARGET_80387 && !TARGET_FISTTP
4361 && FLOAT_MODE_P (GET_MODE (operands[1]))
4362 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4364 [(set_attr "type" "fistp")
4365 (set_attr "i387_cw" "trunc")
4366 (set_attr "mode" "<MODE>")])
4369 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4370 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4371 (use (match_operand:HI 2 "memory_operand" ""))
4372 (use (match_operand:HI 3 "memory_operand" ""))
4373 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4375 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4377 (use (match_dup 3))])
4378 (set (match_dup 0) (match_dup 4))]
4382 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4383 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4384 (use (match_operand:HI 2 "memory_operand" ""))
4385 (use (match_operand:HI 3 "memory_operand" ""))
4386 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4388 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4390 (use (match_dup 3))])]
4393 (define_insn "x86_fnstcw_1"
4394 [(set (match_operand:HI 0 "memory_operand" "=m")
4395 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4398 [(set_attr "length" "2")
4399 (set_attr "mode" "HI")
4400 (set_attr "unit" "i387")])
4402 (define_insn "x86_fldcw_1"
4403 [(set (reg:HI FPSR_REG)
4404 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4407 [(set_attr "length" "2")
4408 (set_attr "mode" "HI")
4409 (set_attr "unit" "i387")
4410 (set_attr "athlon_decode" "vector")])
4412 ;; Conversion between fixed point and floating point.
4414 ;; Even though we only accept memory inputs, the backend _really_
4415 ;; wants to be able to do this between registers.
4417 (define_expand "floathisf2"
4418 [(set (match_operand:SF 0 "register_operand" "")
4419 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4420 "TARGET_80387 || TARGET_SSE_MATH"
4422 if (TARGET_SSE_MATH)
4424 emit_insn (gen_floatsisf2 (operands[0],
4425 convert_to_mode (SImode, operands[1], 0)));
4430 (define_insn "*floathisf2_i387"
4431 [(set (match_operand:SF 0 "register_operand" "=f,f")
4432 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4433 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4437 [(set_attr "type" "fmov,multi")
4438 (set_attr "mode" "SF")
4439 (set_attr "unit" "*,i387")
4440 (set_attr "fp_int_src" "true")])
4442 (define_expand "floatsisf2"
4443 [(set (match_operand:SF 0 "register_operand" "")
4444 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4445 "TARGET_80387 || TARGET_SSE_MATH"
4448 (define_insn "*floatsisf2_mixed"
4449 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4450 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4451 "TARGET_MIX_SSE_I387"
4455 cvtsi2ss\t{%1, %0|%0, %1}
4456 cvtsi2ss\t{%1, %0|%0, %1}"
4457 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4458 (set_attr "mode" "SF")
4459 (set_attr "unit" "*,i387,*,*")
4460 (set_attr "athlon_decode" "*,*,vector,double")
4461 (set_attr "fp_int_src" "true")])
4463 (define_insn "*floatsisf2_sse"
4464 [(set (match_operand:SF 0 "register_operand" "=x,x")
4465 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4467 "cvtsi2ss\t{%1, %0|%0, %1}"
4468 [(set_attr "type" "sseicvt")
4469 (set_attr "mode" "SF")
4470 (set_attr "athlon_decode" "vector,double")
4471 (set_attr "fp_int_src" "true")])
4473 (define_insn "*floatsisf2_i387"
4474 [(set (match_operand:SF 0 "register_operand" "=f,f")
4475 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4480 [(set_attr "type" "fmov,multi")
4481 (set_attr "mode" "SF")
4482 (set_attr "unit" "*,i387")
4483 (set_attr "fp_int_src" "true")])
4485 (define_expand "floatdisf2"
4486 [(set (match_operand:SF 0 "register_operand" "")
4487 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4488 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4491 (define_insn "*floatdisf2_mixed"
4492 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4493 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4494 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4498 cvtsi2ss{q}\t{%1, %0|%0, %1}
4499 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4500 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4501 (set_attr "mode" "SF")
4502 (set_attr "unit" "*,i387,*,*")
4503 (set_attr "athlon_decode" "*,*,vector,double")
4504 (set_attr "fp_int_src" "true")])
4506 (define_insn "*floatdisf2_sse"
4507 [(set (match_operand:SF 0 "register_operand" "=x,x")
4508 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4509 "TARGET_64BIT && TARGET_SSE_MATH"
4510 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4511 [(set_attr "type" "sseicvt")
4512 (set_attr "mode" "SF")
4513 (set_attr "athlon_decode" "vector,double")
4514 (set_attr "fp_int_src" "true")])
4516 (define_insn "*floatdisf2_i387"
4517 [(set (match_operand:SF 0 "register_operand" "=f,f")
4518 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4523 [(set_attr "type" "fmov,multi")
4524 (set_attr "mode" "SF")
4525 (set_attr "unit" "*,i387")
4526 (set_attr "fp_int_src" "true")])
4528 (define_expand "floathidf2"
4529 [(set (match_operand:DF 0 "register_operand" "")
4530 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4531 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4533 if (TARGET_SSE2 && TARGET_SSE_MATH)
4535 emit_insn (gen_floatsidf2 (operands[0],
4536 convert_to_mode (SImode, operands[1], 0)));
4541 (define_insn "*floathidf2_i387"
4542 [(set (match_operand:DF 0 "register_operand" "=f,f")
4543 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4544 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4548 [(set_attr "type" "fmov,multi")
4549 (set_attr "mode" "DF")
4550 (set_attr "unit" "*,i387")
4551 (set_attr "fp_int_src" "true")])
4553 (define_expand "floatsidf2"
4554 [(set (match_operand:DF 0 "register_operand" "")
4555 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4556 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4559 (define_insn "*floatsidf2_mixed"
4560 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4561 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4562 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4566 cvtsi2sd\t{%1, %0|%0, %1}
4567 cvtsi2sd\t{%1, %0|%0, %1}"
4568 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4569 (set_attr "mode" "DF")
4570 (set_attr "unit" "*,i387,*,*")
4571 (set_attr "athlon_decode" "*,*,double,direct")
4572 (set_attr "fp_int_src" "true")])
4574 (define_insn "*floatsidf2_sse"
4575 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4576 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4577 "TARGET_SSE2 && TARGET_SSE_MATH"
4578 "cvtsi2sd\t{%1, %0|%0, %1}"
4579 [(set_attr "type" "sseicvt")
4580 (set_attr "mode" "DF")
4581 (set_attr "athlon_decode" "double,direct")
4582 (set_attr "fp_int_src" "true")])
4584 (define_insn "*floatsidf2_i387"
4585 [(set (match_operand:DF 0 "register_operand" "=f,f")
4586 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4591 [(set_attr "type" "fmov,multi")
4592 (set_attr "mode" "DF")
4593 (set_attr "unit" "*,i387")
4594 (set_attr "fp_int_src" "true")])
4596 (define_expand "floatdidf2"
4597 [(set (match_operand:DF 0 "register_operand" "")
4598 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4599 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4602 (define_insn "*floatdidf2_mixed"
4603 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4604 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4605 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4609 cvtsi2sd{q}\t{%1, %0|%0, %1}
4610 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4611 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4612 (set_attr "mode" "DF")
4613 (set_attr "unit" "*,i387,*,*")
4614 (set_attr "athlon_decode" "*,*,double,direct")
4615 (set_attr "fp_int_src" "true")])
4617 (define_insn "*floatdidf2_sse"
4618 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4619 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4620 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4621 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4622 [(set_attr "type" "sseicvt")
4623 (set_attr "mode" "DF")
4624 (set_attr "athlon_decode" "double,direct")
4625 (set_attr "fp_int_src" "true")])
4627 (define_insn "*floatdidf2_i387"
4628 [(set (match_operand:DF 0 "register_operand" "=f,f")
4629 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4634 [(set_attr "type" "fmov,multi")
4635 (set_attr "mode" "DF")
4636 (set_attr "unit" "*,i387")
4637 (set_attr "fp_int_src" "true")])
4639 (define_insn "floathixf2"
4640 [(set (match_operand:XF 0 "register_operand" "=f,f")
4641 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4646 [(set_attr "type" "fmov,multi")
4647 (set_attr "mode" "XF")
4648 (set_attr "unit" "*,i387")
4649 (set_attr "fp_int_src" "true")])
4651 (define_insn "floatsixf2"
4652 [(set (match_operand:XF 0 "register_operand" "=f,f")
4653 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4658 [(set_attr "type" "fmov,multi")
4659 (set_attr "mode" "XF")
4660 (set_attr "unit" "*,i387")
4661 (set_attr "fp_int_src" "true")])
4663 (define_insn "floatdixf2"
4664 [(set (match_operand:XF 0 "register_operand" "=f,f")
4665 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4670 [(set_attr "type" "fmov,multi")
4671 (set_attr "mode" "XF")
4672 (set_attr "unit" "*,i387")
4673 (set_attr "fp_int_src" "true")])
4675 ;; %%% Kill these when reload knows how to do it.
4677 [(set (match_operand 0 "fp_register_operand" "")
4678 (float (match_operand 1 "register_operand" "")))]
4681 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4684 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4685 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4686 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4687 ix86_free_from_memory (GET_MODE (operands[1]));
4691 (define_expand "floatunssisf2"
4692 [(use (match_operand:SF 0 "register_operand" ""))
4693 (use (match_operand:SI 1 "register_operand" ""))]
4694 "!TARGET_64BIT && TARGET_SSE_MATH"
4695 "x86_emit_floatuns (operands); DONE;")
4697 (define_expand "floatunsdisf2"
4698 [(use (match_operand:SF 0 "register_operand" ""))
4699 (use (match_operand:DI 1 "register_operand" ""))]
4700 "TARGET_64BIT && TARGET_SSE_MATH"
4701 "x86_emit_floatuns (operands); DONE;")
4703 (define_expand "floatunsdidf2"
4704 [(use (match_operand:DF 0 "register_operand" ""))
4705 (use (match_operand:DI 1 "register_operand" ""))]
4706 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4707 "x86_emit_floatuns (operands); DONE;")
4709 ;; SSE extract/set expanders
4714 ;; %%% splits for addditi3
4716 (define_expand "addti3"
4717 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4718 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4719 (match_operand:TI 2 "x86_64_general_operand" "")))
4720 (clobber (reg:CC FLAGS_REG))]
4722 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4724 (define_insn "*addti3_1"
4725 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4726 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4727 (match_operand:TI 2 "general_operand" "roiF,riF")))
4728 (clobber (reg:CC FLAGS_REG))]
4729 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4733 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4734 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4735 (match_operand:TI 2 "general_operand" "")))
4736 (clobber (reg:CC FLAGS_REG))]
4737 "TARGET_64BIT && reload_completed"
4738 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4740 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4741 (parallel [(set (match_dup 3)
4742 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4745 (clobber (reg:CC FLAGS_REG))])]
4746 "split_ti (operands+0, 1, operands+0, operands+3);
4747 split_ti (operands+1, 1, operands+1, operands+4);
4748 split_ti (operands+2, 1, operands+2, operands+5);")
4750 ;; %%% splits for addsidi3
4751 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4752 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4753 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4755 (define_expand "adddi3"
4756 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4757 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4758 (match_operand:DI 2 "x86_64_general_operand" "")))
4759 (clobber (reg:CC FLAGS_REG))]
4761 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4763 (define_insn "*adddi3_1"
4764 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4765 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4766 (match_operand:DI 2 "general_operand" "roiF,riF")))
4767 (clobber (reg:CC FLAGS_REG))]
4768 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4772 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4773 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4774 (match_operand:DI 2 "general_operand" "")))
4775 (clobber (reg:CC FLAGS_REG))]
4776 "!TARGET_64BIT && reload_completed"
4777 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4779 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4780 (parallel [(set (match_dup 3)
4781 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4784 (clobber (reg:CC FLAGS_REG))])]
4785 "split_di (operands+0, 1, operands+0, operands+3);
4786 split_di (operands+1, 1, operands+1, operands+4);
4787 split_di (operands+2, 1, operands+2, operands+5);")
4789 (define_insn "adddi3_carry_rex64"
4790 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4791 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4792 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4793 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4794 (clobber (reg:CC FLAGS_REG))]
4795 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4796 "adc{q}\t{%2, %0|%0, %2}"
4797 [(set_attr "type" "alu")
4798 (set_attr "pent_pair" "pu")
4799 (set_attr "mode" "DI")])
4801 (define_insn "*adddi3_cc_rex64"
4802 [(set (reg:CC FLAGS_REG)
4803 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4804 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4806 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4807 (plus:DI (match_dup 1) (match_dup 2)))]
4808 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4809 "add{q}\t{%2, %0|%0, %2}"
4810 [(set_attr "type" "alu")
4811 (set_attr "mode" "DI")])
4813 (define_insn "addqi3_carry"
4814 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4815 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4816 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4817 (match_operand:QI 2 "general_operand" "qi,qm")))
4818 (clobber (reg:CC FLAGS_REG))]
4819 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4820 "adc{b}\t{%2, %0|%0, %2}"
4821 [(set_attr "type" "alu")
4822 (set_attr "pent_pair" "pu")
4823 (set_attr "mode" "QI")])
4825 (define_insn "addhi3_carry"
4826 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4827 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4828 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4829 (match_operand:HI 2 "general_operand" "ri,rm")))
4830 (clobber (reg:CC FLAGS_REG))]
4831 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4832 "adc{w}\t{%2, %0|%0, %2}"
4833 [(set_attr "type" "alu")
4834 (set_attr "pent_pair" "pu")
4835 (set_attr "mode" "HI")])
4837 (define_insn "addsi3_carry"
4838 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4839 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4840 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4841 (match_operand:SI 2 "general_operand" "ri,rm")))
4842 (clobber (reg:CC FLAGS_REG))]
4843 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4844 "adc{l}\t{%2, %0|%0, %2}"
4845 [(set_attr "type" "alu")
4846 (set_attr "pent_pair" "pu")
4847 (set_attr "mode" "SI")])
4849 (define_insn "*addsi3_carry_zext"
4850 [(set (match_operand:DI 0 "register_operand" "=r")
4852 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4853 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4854 (match_operand:SI 2 "general_operand" "rim"))))
4855 (clobber (reg:CC FLAGS_REG))]
4856 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4857 "adc{l}\t{%2, %k0|%k0, %2}"
4858 [(set_attr "type" "alu")
4859 (set_attr "pent_pair" "pu")
4860 (set_attr "mode" "SI")])
4862 (define_insn "*addsi3_cc"
4863 [(set (reg:CC FLAGS_REG)
4864 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4865 (match_operand:SI 2 "general_operand" "ri,rm")]
4867 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4868 (plus:SI (match_dup 1) (match_dup 2)))]
4869 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4870 "add{l}\t{%2, %0|%0, %2}"
4871 [(set_attr "type" "alu")
4872 (set_attr "mode" "SI")])
4874 (define_insn "addqi3_cc"
4875 [(set (reg:CC FLAGS_REG)
4876 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4877 (match_operand:QI 2 "general_operand" "qi,qm")]
4879 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4880 (plus:QI (match_dup 1) (match_dup 2)))]
4881 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4882 "add{b}\t{%2, %0|%0, %2}"
4883 [(set_attr "type" "alu")
4884 (set_attr "mode" "QI")])
4886 (define_expand "addsi3"
4887 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4888 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4889 (match_operand:SI 2 "general_operand" "")))
4890 (clobber (reg:CC FLAGS_REG))])]
4892 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4894 (define_insn "*lea_1"
4895 [(set (match_operand:SI 0 "register_operand" "=r")
4896 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4898 "lea{l}\t{%a1, %0|%0, %a1}"
4899 [(set_attr "type" "lea")
4900 (set_attr "mode" "SI")])
4902 (define_insn "*lea_1_rex64"
4903 [(set (match_operand:SI 0 "register_operand" "=r")
4904 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4906 "lea{l}\t{%a1, %0|%0, %a1}"
4907 [(set_attr "type" "lea")
4908 (set_attr "mode" "SI")])
4910 (define_insn "*lea_1_zext"
4911 [(set (match_operand:DI 0 "register_operand" "=r")
4913 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4915 "lea{l}\t{%a1, %k0|%k0, %a1}"
4916 [(set_attr "type" "lea")
4917 (set_attr "mode" "SI")])
4919 (define_insn "*lea_2_rex64"
4920 [(set (match_operand:DI 0 "register_operand" "=r")
4921 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4923 "lea{q}\t{%a1, %0|%0, %a1}"
4924 [(set_attr "type" "lea")
4925 (set_attr "mode" "DI")])
4927 ;; The lea patterns for non-Pmodes needs to be matched by several
4928 ;; insns converted to real lea by splitters.
4930 (define_insn_and_split "*lea_general_1"
4931 [(set (match_operand 0 "register_operand" "=r")
4932 (plus (plus (match_operand 1 "index_register_operand" "l")
4933 (match_operand 2 "register_operand" "r"))
4934 (match_operand 3 "immediate_operand" "i")))]
4935 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4936 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4937 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4938 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4939 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4940 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4941 || GET_MODE (operands[3]) == VOIDmode)"
4943 "&& reload_completed"
4947 operands[0] = gen_lowpart (SImode, operands[0]);
4948 operands[1] = gen_lowpart (Pmode, operands[1]);
4949 operands[2] = gen_lowpart (Pmode, operands[2]);
4950 operands[3] = gen_lowpart (Pmode, operands[3]);
4951 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4953 if (Pmode != SImode)
4954 pat = gen_rtx_SUBREG (SImode, pat, 0);
4955 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4958 [(set_attr "type" "lea")
4959 (set_attr "mode" "SI")])
4961 (define_insn_and_split "*lea_general_1_zext"
4962 [(set (match_operand:DI 0 "register_operand" "=r")
4964 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4965 (match_operand:SI 2 "register_operand" "r"))
4966 (match_operand:SI 3 "immediate_operand" "i"))))]
4969 "&& reload_completed"
4971 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4973 (match_dup 3)) 0)))]
4975 operands[1] = gen_lowpart (Pmode, operands[1]);
4976 operands[2] = gen_lowpart (Pmode, operands[2]);
4977 operands[3] = gen_lowpart (Pmode, operands[3]);
4979 [(set_attr "type" "lea")
4980 (set_attr "mode" "SI")])
4982 (define_insn_and_split "*lea_general_2"
4983 [(set (match_operand 0 "register_operand" "=r")
4984 (plus (mult (match_operand 1 "index_register_operand" "l")
4985 (match_operand 2 "const248_operand" "i"))
4986 (match_operand 3 "nonmemory_operand" "ri")))]
4987 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4988 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4989 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4990 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4991 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4992 || GET_MODE (operands[3]) == VOIDmode)"
4994 "&& reload_completed"
4998 operands[0] = gen_lowpart (SImode, operands[0]);
4999 operands[1] = gen_lowpart (Pmode, operands[1]);
5000 operands[3] = gen_lowpart (Pmode, operands[3]);
5001 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5003 if (Pmode != SImode)
5004 pat = gen_rtx_SUBREG (SImode, pat, 0);
5005 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5008 [(set_attr "type" "lea")
5009 (set_attr "mode" "SI")])
5011 (define_insn_and_split "*lea_general_2_zext"
5012 [(set (match_operand:DI 0 "register_operand" "=r")
5014 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5015 (match_operand:SI 2 "const248_operand" "n"))
5016 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5019 "&& reload_completed"
5021 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5023 (match_dup 3)) 0)))]
5025 operands[1] = gen_lowpart (Pmode, operands[1]);
5026 operands[3] = gen_lowpart (Pmode, operands[3]);
5028 [(set_attr "type" "lea")
5029 (set_attr "mode" "SI")])
5031 (define_insn_and_split "*lea_general_3"
5032 [(set (match_operand 0 "register_operand" "=r")
5033 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5034 (match_operand 2 "const248_operand" "i"))
5035 (match_operand 3 "register_operand" "r"))
5036 (match_operand 4 "immediate_operand" "i")))]
5037 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5038 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5039 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5040 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5041 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5043 "&& reload_completed"
5047 operands[0] = gen_lowpart (SImode, operands[0]);
5048 operands[1] = gen_lowpart (Pmode, operands[1]);
5049 operands[3] = gen_lowpart (Pmode, operands[3]);
5050 operands[4] = gen_lowpart (Pmode, operands[4]);
5051 pat = gen_rtx_PLUS (Pmode,
5052 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5056 if (Pmode != SImode)
5057 pat = gen_rtx_SUBREG (SImode, pat, 0);
5058 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5061 [(set_attr "type" "lea")
5062 (set_attr "mode" "SI")])
5064 (define_insn_and_split "*lea_general_3_zext"
5065 [(set (match_operand:DI 0 "register_operand" "=r")
5067 (plus:SI (plus:SI (mult:SI
5068 (match_operand:SI 1 "index_register_operand" "l")
5069 (match_operand:SI 2 "const248_operand" "n"))
5070 (match_operand:SI 3 "register_operand" "r"))
5071 (match_operand:SI 4 "immediate_operand" "i"))))]
5074 "&& reload_completed"
5076 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5079 (match_dup 4)) 0)))]
5081 operands[1] = gen_lowpart (Pmode, operands[1]);
5082 operands[3] = gen_lowpart (Pmode, operands[3]);
5083 operands[4] = gen_lowpart (Pmode, operands[4]);
5085 [(set_attr "type" "lea")
5086 (set_attr "mode" "SI")])
5088 (define_insn "*adddi_1_rex64"
5089 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5090 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5091 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5092 (clobber (reg:CC FLAGS_REG))]
5093 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5095 switch (get_attr_type (insn))
5098 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5099 return "lea{q}\t{%a2, %0|%0, %a2}";
5102 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5103 if (operands[2] == const1_rtx)
5104 return "inc{q}\t%0";
5107 gcc_assert (operands[2] == constm1_rtx);
5108 return "dec{q}\t%0";
5112 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5114 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5115 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5116 if (GET_CODE (operands[2]) == CONST_INT
5117 /* Avoid overflows. */
5118 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5119 && (INTVAL (operands[2]) == 128
5120 || (INTVAL (operands[2]) < 0
5121 && INTVAL (operands[2]) != -128)))
5123 operands[2] = GEN_INT (-INTVAL (operands[2]));
5124 return "sub{q}\t{%2, %0|%0, %2}";
5126 return "add{q}\t{%2, %0|%0, %2}";
5130 (cond [(eq_attr "alternative" "2")
5131 (const_string "lea")
5132 ; Current assemblers are broken and do not allow @GOTOFF in
5133 ; ought but a memory context.
5134 (match_operand:DI 2 "pic_symbolic_operand" "")
5135 (const_string "lea")
5136 (match_operand:DI 2 "incdec_operand" "")
5137 (const_string "incdec")
5139 (const_string "alu")))
5140 (set_attr "mode" "DI")])
5142 ;; Convert lea to the lea pattern to avoid flags dependency.
5144 [(set (match_operand:DI 0 "register_operand" "")
5145 (plus:DI (match_operand:DI 1 "register_operand" "")
5146 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5147 (clobber (reg:CC FLAGS_REG))]
5148 "TARGET_64BIT && reload_completed
5149 && true_regnum (operands[0]) != true_regnum (operands[1])"
5151 (plus:DI (match_dup 1)
5155 (define_insn "*adddi_2_rex64"
5156 [(set (reg FLAGS_REG)
5158 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5159 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5161 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5162 (plus:DI (match_dup 1) (match_dup 2)))]
5163 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5164 && ix86_binary_operator_ok (PLUS, DImode, operands)
5165 /* Current assemblers are broken and do not allow @GOTOFF in
5166 ought but a memory context. */
5167 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5169 switch (get_attr_type (insn))
5172 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5173 if (operands[2] == const1_rtx)
5174 return "inc{q}\t%0";
5177 gcc_assert (operands[2] == constm1_rtx);
5178 return "dec{q}\t%0";
5182 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5183 /* ???? We ought to handle there the 32bit case too
5184 - do we need new constraint? */
5185 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5186 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5187 if (GET_CODE (operands[2]) == CONST_INT
5188 /* Avoid overflows. */
5189 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5190 && (INTVAL (operands[2]) == 128
5191 || (INTVAL (operands[2]) < 0
5192 && INTVAL (operands[2]) != -128)))
5194 operands[2] = GEN_INT (-INTVAL (operands[2]));
5195 return "sub{q}\t{%2, %0|%0, %2}";
5197 return "add{q}\t{%2, %0|%0, %2}";
5201 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5202 (const_string "incdec")
5203 (const_string "alu")))
5204 (set_attr "mode" "DI")])
5206 (define_insn "*adddi_3_rex64"
5207 [(set (reg FLAGS_REG)
5208 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5209 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5210 (clobber (match_scratch:DI 0 "=r"))]
5212 && ix86_match_ccmode (insn, CCZmode)
5213 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5214 /* Current assemblers are broken and do not allow @GOTOFF in
5215 ought but a memory context. */
5216 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5218 switch (get_attr_type (insn))
5221 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5222 if (operands[2] == const1_rtx)
5223 return "inc{q}\t%0";
5226 gcc_assert (operands[2] == constm1_rtx);
5227 return "dec{q}\t%0";
5231 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5232 /* ???? We ought to handle there the 32bit case too
5233 - do we need new constraint? */
5234 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5235 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5236 if (GET_CODE (operands[2]) == CONST_INT
5237 /* Avoid overflows. */
5238 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5239 && (INTVAL (operands[2]) == 128
5240 || (INTVAL (operands[2]) < 0
5241 && INTVAL (operands[2]) != -128)))
5243 operands[2] = GEN_INT (-INTVAL (operands[2]));
5244 return "sub{q}\t{%2, %0|%0, %2}";
5246 return "add{q}\t{%2, %0|%0, %2}";
5250 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5251 (const_string "incdec")
5252 (const_string "alu")))
5253 (set_attr "mode" "DI")])
5255 ; For comparisons against 1, -1 and 128, we may generate better code
5256 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5257 ; is matched then. We can't accept general immediate, because for
5258 ; case of overflows, the result is messed up.
5259 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5261 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5262 ; only for comparisons not depending on it.
5263 (define_insn "*adddi_4_rex64"
5264 [(set (reg FLAGS_REG)
5265 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5266 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5267 (clobber (match_scratch:DI 0 "=rm"))]
5269 && ix86_match_ccmode (insn, CCGCmode)"
5271 switch (get_attr_type (insn))
5274 if (operands[2] == constm1_rtx)
5275 return "inc{q}\t%0";
5278 gcc_assert (operands[2] == const1_rtx);
5279 return "dec{q}\t%0";
5283 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5284 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5285 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5286 if ((INTVAL (operands[2]) == -128
5287 || (INTVAL (operands[2]) > 0
5288 && INTVAL (operands[2]) != 128))
5289 /* Avoid overflows. */
5290 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5291 return "sub{q}\t{%2, %0|%0, %2}";
5292 operands[2] = GEN_INT (-INTVAL (operands[2]));
5293 return "add{q}\t{%2, %0|%0, %2}";
5297 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5298 (const_string "incdec")
5299 (const_string "alu")))
5300 (set_attr "mode" "DI")])
5302 (define_insn "*adddi_5_rex64"
5303 [(set (reg FLAGS_REG)
5305 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5306 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5308 (clobber (match_scratch:DI 0 "=r"))]
5310 && ix86_match_ccmode (insn, CCGOCmode)
5311 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5312 /* Current assemblers are broken and do not allow @GOTOFF in
5313 ought but a memory context. */
5314 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5316 switch (get_attr_type (insn))
5319 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5320 if (operands[2] == const1_rtx)
5321 return "inc{q}\t%0";
5324 gcc_assert (operands[2] == constm1_rtx);
5325 return "dec{q}\t%0";
5329 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5330 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5331 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5332 if (GET_CODE (operands[2]) == CONST_INT
5333 /* Avoid overflows. */
5334 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5335 && (INTVAL (operands[2]) == 128
5336 || (INTVAL (operands[2]) < 0
5337 && INTVAL (operands[2]) != -128)))
5339 operands[2] = GEN_INT (-INTVAL (operands[2]));
5340 return "sub{q}\t{%2, %0|%0, %2}";
5342 return "add{q}\t{%2, %0|%0, %2}";
5346 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5347 (const_string "incdec")
5348 (const_string "alu")))
5349 (set_attr "mode" "DI")])
5352 (define_insn "*addsi_1"
5353 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5354 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5355 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5356 (clobber (reg:CC FLAGS_REG))]
5357 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5359 switch (get_attr_type (insn))
5362 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5363 return "lea{l}\t{%a2, %0|%0, %a2}";
5366 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5367 if (operands[2] == const1_rtx)
5368 return "inc{l}\t%0";
5371 gcc_assert (operands[2] == constm1_rtx);
5372 return "dec{l}\t%0";
5376 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5378 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5379 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5380 if (GET_CODE (operands[2]) == CONST_INT
5381 && (INTVAL (operands[2]) == 128
5382 || (INTVAL (operands[2]) < 0
5383 && INTVAL (operands[2]) != -128)))
5385 operands[2] = GEN_INT (-INTVAL (operands[2]));
5386 return "sub{l}\t{%2, %0|%0, %2}";
5388 return "add{l}\t{%2, %0|%0, %2}";
5392 (cond [(eq_attr "alternative" "2")
5393 (const_string "lea")
5394 ; Current assemblers are broken and do not allow @GOTOFF in
5395 ; ought but a memory context.
5396 (match_operand:SI 2 "pic_symbolic_operand" "")
5397 (const_string "lea")
5398 (match_operand:SI 2 "incdec_operand" "")
5399 (const_string "incdec")
5401 (const_string "alu")))
5402 (set_attr "mode" "SI")])
5404 ;; Convert lea to the lea pattern to avoid flags dependency.
5406 [(set (match_operand 0 "register_operand" "")
5407 (plus (match_operand 1 "register_operand" "")
5408 (match_operand 2 "nonmemory_operand" "")))
5409 (clobber (reg:CC FLAGS_REG))]
5411 && true_regnum (operands[0]) != true_regnum (operands[1])"
5415 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5416 may confuse gen_lowpart. */
5417 if (GET_MODE (operands[0]) != Pmode)
5419 operands[1] = gen_lowpart (Pmode, operands[1]);
5420 operands[2] = gen_lowpart (Pmode, operands[2]);
5422 operands[0] = gen_lowpart (SImode, operands[0]);
5423 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5424 if (Pmode != SImode)
5425 pat = gen_rtx_SUBREG (SImode, pat, 0);
5426 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5430 ;; It may seem that nonimmediate operand is proper one for operand 1.
5431 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5432 ;; we take care in ix86_binary_operator_ok to not allow two memory
5433 ;; operands so proper swapping will be done in reload. This allow
5434 ;; patterns constructed from addsi_1 to match.
5435 (define_insn "addsi_1_zext"
5436 [(set (match_operand:DI 0 "register_operand" "=r,r")
5438 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5439 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5440 (clobber (reg:CC FLAGS_REG))]
5441 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5443 switch (get_attr_type (insn))
5446 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5447 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5450 if (operands[2] == const1_rtx)
5451 return "inc{l}\t%k0";
5454 gcc_assert (operands[2] == constm1_rtx);
5455 return "dec{l}\t%k0";
5459 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5460 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5461 if (GET_CODE (operands[2]) == CONST_INT
5462 && (INTVAL (operands[2]) == 128
5463 || (INTVAL (operands[2]) < 0
5464 && INTVAL (operands[2]) != -128)))
5466 operands[2] = GEN_INT (-INTVAL (operands[2]));
5467 return "sub{l}\t{%2, %k0|%k0, %2}";
5469 return "add{l}\t{%2, %k0|%k0, %2}";
5473 (cond [(eq_attr "alternative" "1")
5474 (const_string "lea")
5475 ; Current assemblers are broken and do not allow @GOTOFF in
5476 ; ought but a memory context.
5477 (match_operand:SI 2 "pic_symbolic_operand" "")
5478 (const_string "lea")
5479 (match_operand:SI 2 "incdec_operand" "")
5480 (const_string "incdec")
5482 (const_string "alu")))
5483 (set_attr "mode" "SI")])
5485 ;; Convert lea to the lea pattern to avoid flags dependency.
5487 [(set (match_operand:DI 0 "register_operand" "")
5489 (plus:SI (match_operand:SI 1 "register_operand" "")
5490 (match_operand:SI 2 "nonmemory_operand" ""))))
5491 (clobber (reg:CC FLAGS_REG))]
5492 "TARGET_64BIT && reload_completed
5493 && true_regnum (operands[0]) != true_regnum (operands[1])"
5495 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5497 operands[1] = gen_lowpart (Pmode, operands[1]);
5498 operands[2] = gen_lowpart (Pmode, operands[2]);
5501 (define_insn "*addsi_2"
5502 [(set (reg FLAGS_REG)
5504 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5505 (match_operand:SI 2 "general_operand" "rmni,rni"))
5507 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5508 (plus:SI (match_dup 1) (match_dup 2)))]
5509 "ix86_match_ccmode (insn, CCGOCmode)
5510 && ix86_binary_operator_ok (PLUS, SImode, operands)
5511 /* Current assemblers are broken and do not allow @GOTOFF in
5512 ought but a memory context. */
5513 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5515 switch (get_attr_type (insn))
5518 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5519 if (operands[2] == const1_rtx)
5520 return "inc{l}\t%0";
5523 gcc_assert (operands[2] == constm1_rtx);
5524 return "dec{l}\t%0";
5528 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5529 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5530 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5531 if (GET_CODE (operands[2]) == CONST_INT
5532 && (INTVAL (operands[2]) == 128
5533 || (INTVAL (operands[2]) < 0
5534 && INTVAL (operands[2]) != -128)))
5536 operands[2] = GEN_INT (-INTVAL (operands[2]));
5537 return "sub{l}\t{%2, %0|%0, %2}";
5539 return "add{l}\t{%2, %0|%0, %2}";
5543 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5544 (const_string "incdec")
5545 (const_string "alu")))
5546 (set_attr "mode" "SI")])
5548 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5549 (define_insn "*addsi_2_zext"
5550 [(set (reg FLAGS_REG)
5552 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5553 (match_operand:SI 2 "general_operand" "rmni"))
5555 (set (match_operand:DI 0 "register_operand" "=r")
5556 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5557 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5558 && ix86_binary_operator_ok (PLUS, SImode, operands)
5559 /* Current assemblers are broken and do not allow @GOTOFF in
5560 ought but a memory context. */
5561 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5563 switch (get_attr_type (insn))
5566 if (operands[2] == const1_rtx)
5567 return "inc{l}\t%k0";
5570 gcc_assert (operands[2] == constm1_rtx);
5571 return "dec{l}\t%k0";
5575 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5576 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5577 if (GET_CODE (operands[2]) == CONST_INT
5578 && (INTVAL (operands[2]) == 128
5579 || (INTVAL (operands[2]) < 0
5580 && INTVAL (operands[2]) != -128)))
5582 operands[2] = GEN_INT (-INTVAL (operands[2]));
5583 return "sub{l}\t{%2, %k0|%k0, %2}";
5585 return "add{l}\t{%2, %k0|%k0, %2}";
5589 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5590 (const_string "incdec")
5591 (const_string "alu")))
5592 (set_attr "mode" "SI")])
5594 (define_insn "*addsi_3"
5595 [(set (reg FLAGS_REG)
5596 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5597 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5598 (clobber (match_scratch:SI 0 "=r"))]
5599 "ix86_match_ccmode (insn, CCZmode)
5600 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5601 /* Current assemblers are broken and do not allow @GOTOFF in
5602 ought but a memory context. */
5603 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5605 switch (get_attr_type (insn))
5608 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609 if (operands[2] == const1_rtx)
5610 return "inc{l}\t%0";
5613 gcc_assert (operands[2] == constm1_rtx);
5614 return "dec{l}\t%0";
5618 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5619 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5620 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5621 if (GET_CODE (operands[2]) == CONST_INT
5622 && (INTVAL (operands[2]) == 128
5623 || (INTVAL (operands[2]) < 0
5624 && INTVAL (operands[2]) != -128)))
5626 operands[2] = GEN_INT (-INTVAL (operands[2]));
5627 return "sub{l}\t{%2, %0|%0, %2}";
5629 return "add{l}\t{%2, %0|%0, %2}";
5633 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5634 (const_string "incdec")
5635 (const_string "alu")))
5636 (set_attr "mode" "SI")])
5638 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5639 (define_insn "*addsi_3_zext"
5640 [(set (reg FLAGS_REG)
5641 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5642 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5643 (set (match_operand:DI 0 "register_operand" "=r")
5644 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5645 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5646 && ix86_binary_operator_ok (PLUS, SImode, operands)
5647 /* Current assemblers are broken and do not allow @GOTOFF in
5648 ought but a memory context. */
5649 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5651 switch (get_attr_type (insn))
5654 if (operands[2] == const1_rtx)
5655 return "inc{l}\t%k0";
5658 gcc_assert (operands[2] == constm1_rtx);
5659 return "dec{l}\t%k0";
5663 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5664 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5665 if (GET_CODE (operands[2]) == CONST_INT
5666 && (INTVAL (operands[2]) == 128
5667 || (INTVAL (operands[2]) < 0
5668 && INTVAL (operands[2]) != -128)))
5670 operands[2] = GEN_INT (-INTVAL (operands[2]));
5671 return "sub{l}\t{%2, %k0|%k0, %2}";
5673 return "add{l}\t{%2, %k0|%k0, %2}";
5677 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5678 (const_string "incdec")
5679 (const_string "alu")))
5680 (set_attr "mode" "SI")])
5682 ; For comparisons against 1, -1 and 128, we may generate better code
5683 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5684 ; is matched then. We can't accept general immediate, because for
5685 ; case of overflows, the result is messed up.
5686 ; This pattern also don't hold of 0x80000000, since the value overflows
5688 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5689 ; only for comparisons not depending on it.
5690 (define_insn "*addsi_4"
5691 [(set (reg FLAGS_REG)
5692 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5693 (match_operand:SI 2 "const_int_operand" "n")))
5694 (clobber (match_scratch:SI 0 "=rm"))]
5695 "ix86_match_ccmode (insn, CCGCmode)
5696 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5698 switch (get_attr_type (insn))
5701 if (operands[2] == constm1_rtx)
5702 return "inc{l}\t%0";
5705 gcc_assert (operands[2] == const1_rtx);
5706 return "dec{l}\t%0";
5710 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5711 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5712 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5713 if ((INTVAL (operands[2]) == -128
5714 || (INTVAL (operands[2]) > 0
5715 && INTVAL (operands[2]) != 128)))
5716 return "sub{l}\t{%2, %0|%0, %2}";
5717 operands[2] = GEN_INT (-INTVAL (operands[2]));
5718 return "add{l}\t{%2, %0|%0, %2}";
5722 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5723 (const_string "incdec")
5724 (const_string "alu")))
5725 (set_attr "mode" "SI")])
5727 (define_insn "*addsi_5"
5728 [(set (reg FLAGS_REG)
5730 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5731 (match_operand:SI 2 "general_operand" "rmni"))
5733 (clobber (match_scratch:SI 0 "=r"))]
5734 "ix86_match_ccmode (insn, CCGOCmode)
5735 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5736 /* Current assemblers are broken and do not allow @GOTOFF in
5737 ought but a memory context. */
5738 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5740 switch (get_attr_type (insn))
5743 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5744 if (operands[2] == const1_rtx)
5745 return "inc{l}\t%0";
5748 gcc_assert (operands[2] == constm1_rtx);
5749 return "dec{l}\t%0";
5753 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5754 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5755 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5756 if (GET_CODE (operands[2]) == CONST_INT
5757 && (INTVAL (operands[2]) == 128
5758 || (INTVAL (operands[2]) < 0
5759 && INTVAL (operands[2]) != -128)))
5761 operands[2] = GEN_INT (-INTVAL (operands[2]));
5762 return "sub{l}\t{%2, %0|%0, %2}";
5764 return "add{l}\t{%2, %0|%0, %2}";
5768 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5769 (const_string "incdec")
5770 (const_string "alu")))
5771 (set_attr "mode" "SI")])
5773 (define_expand "addhi3"
5774 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5775 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5776 (match_operand:HI 2 "general_operand" "")))
5777 (clobber (reg:CC FLAGS_REG))])]
5778 "TARGET_HIMODE_MATH"
5779 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5781 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5782 ;; type optimizations enabled by define-splits. This is not important
5783 ;; for PII, and in fact harmful because of partial register stalls.
5785 (define_insn "*addhi_1_lea"
5786 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5787 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5788 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5789 (clobber (reg:CC FLAGS_REG))]
5790 "!TARGET_PARTIAL_REG_STALL
5791 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5793 switch (get_attr_type (insn))
5798 if (operands[2] == const1_rtx)
5799 return "inc{w}\t%0";
5802 gcc_assert (operands[2] == constm1_rtx);
5803 return "dec{w}\t%0";
5807 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5808 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5809 if (GET_CODE (operands[2]) == CONST_INT
5810 && (INTVAL (operands[2]) == 128
5811 || (INTVAL (operands[2]) < 0
5812 && INTVAL (operands[2]) != -128)))
5814 operands[2] = GEN_INT (-INTVAL (operands[2]));
5815 return "sub{w}\t{%2, %0|%0, %2}";
5817 return "add{w}\t{%2, %0|%0, %2}";
5821 (if_then_else (eq_attr "alternative" "2")
5822 (const_string "lea")
5823 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5824 (const_string "incdec")
5825 (const_string "alu"))))
5826 (set_attr "mode" "HI,HI,SI")])
5828 (define_insn "*addhi_1"
5829 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5830 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5831 (match_operand:HI 2 "general_operand" "ri,rm")))
5832 (clobber (reg:CC FLAGS_REG))]
5833 "TARGET_PARTIAL_REG_STALL
5834 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5836 switch (get_attr_type (insn))
5839 if (operands[2] == const1_rtx)
5840 return "inc{w}\t%0";
5843 gcc_assert (operands[2] == constm1_rtx);
5844 return "dec{w}\t%0";
5848 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5849 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5850 if (GET_CODE (operands[2]) == CONST_INT
5851 && (INTVAL (operands[2]) == 128
5852 || (INTVAL (operands[2]) < 0
5853 && INTVAL (operands[2]) != -128)))
5855 operands[2] = GEN_INT (-INTVAL (operands[2]));
5856 return "sub{w}\t{%2, %0|%0, %2}";
5858 return "add{w}\t{%2, %0|%0, %2}";
5862 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5863 (const_string "incdec")
5864 (const_string "alu")))
5865 (set_attr "mode" "HI")])
5867 (define_insn "*addhi_2"
5868 [(set (reg FLAGS_REG)
5870 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5871 (match_operand:HI 2 "general_operand" "rmni,rni"))
5873 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5874 (plus:HI (match_dup 1) (match_dup 2)))]
5875 "ix86_match_ccmode (insn, CCGOCmode)
5876 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5878 switch (get_attr_type (insn))
5881 if (operands[2] == const1_rtx)
5882 return "inc{w}\t%0";
5885 gcc_assert (operands[2] == constm1_rtx);
5886 return "dec{w}\t%0";
5890 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5891 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5892 if (GET_CODE (operands[2]) == CONST_INT
5893 && (INTVAL (operands[2]) == 128
5894 || (INTVAL (operands[2]) < 0
5895 && INTVAL (operands[2]) != -128)))
5897 operands[2] = GEN_INT (-INTVAL (operands[2]));
5898 return "sub{w}\t{%2, %0|%0, %2}";
5900 return "add{w}\t{%2, %0|%0, %2}";
5904 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5905 (const_string "incdec")
5906 (const_string "alu")))
5907 (set_attr "mode" "HI")])
5909 (define_insn "*addhi_3"
5910 [(set (reg FLAGS_REG)
5911 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5912 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5913 (clobber (match_scratch:HI 0 "=r"))]
5914 "ix86_match_ccmode (insn, CCZmode)
5915 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5917 switch (get_attr_type (insn))
5920 if (operands[2] == const1_rtx)
5921 return "inc{w}\t%0";
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return "dec{w}\t%0";
5929 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5930 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5931 if (GET_CODE (operands[2]) == CONST_INT
5932 && (INTVAL (operands[2]) == 128
5933 || (INTVAL (operands[2]) < 0
5934 && INTVAL (operands[2]) != -128)))
5936 operands[2] = GEN_INT (-INTVAL (operands[2]));
5937 return "sub{w}\t{%2, %0|%0, %2}";
5939 return "add{w}\t{%2, %0|%0, %2}";
5943 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5944 (const_string "incdec")
5945 (const_string "alu")))
5946 (set_attr "mode" "HI")])
5948 ; See comments above addsi_4 for details.
5949 (define_insn "*addhi_4"
5950 [(set (reg FLAGS_REG)
5951 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5952 (match_operand:HI 2 "const_int_operand" "n")))
5953 (clobber (match_scratch:HI 0 "=rm"))]
5954 "ix86_match_ccmode (insn, CCGCmode)
5955 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5957 switch (get_attr_type (insn))
5960 if (operands[2] == constm1_rtx)
5961 return "inc{w}\t%0";
5964 gcc_assert (operands[2] == const1_rtx);
5965 return "dec{w}\t%0";
5969 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5970 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5972 if ((INTVAL (operands[2]) == -128
5973 || (INTVAL (operands[2]) > 0
5974 && INTVAL (operands[2]) != 128)))
5975 return "sub{w}\t{%2, %0|%0, %2}";
5976 operands[2] = GEN_INT (-INTVAL (operands[2]));
5977 return "add{w}\t{%2, %0|%0, %2}";
5981 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5982 (const_string "incdec")
5983 (const_string "alu")))
5984 (set_attr "mode" "SI")])
5987 (define_insn "*addhi_5"
5988 [(set (reg FLAGS_REG)
5990 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5991 (match_operand:HI 2 "general_operand" "rmni"))
5993 (clobber (match_scratch:HI 0 "=r"))]
5994 "ix86_match_ccmode (insn, CCGOCmode)
5995 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5997 switch (get_attr_type (insn))
6000 if (operands[2] == const1_rtx)
6001 return "inc{w}\t%0";
6004 gcc_assert (operands[2] == constm1_rtx);
6005 return "dec{w}\t%0";
6009 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6011 if (GET_CODE (operands[2]) == CONST_INT
6012 && (INTVAL (operands[2]) == 128
6013 || (INTVAL (operands[2]) < 0
6014 && INTVAL (operands[2]) != -128)))
6016 operands[2] = GEN_INT (-INTVAL (operands[2]));
6017 return "sub{w}\t{%2, %0|%0, %2}";
6019 return "add{w}\t{%2, %0|%0, %2}";
6023 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6024 (const_string "incdec")
6025 (const_string "alu")))
6026 (set_attr "mode" "HI")])
6028 (define_expand "addqi3"
6029 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6030 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6031 (match_operand:QI 2 "general_operand" "")))
6032 (clobber (reg:CC FLAGS_REG))])]
6033 "TARGET_QIMODE_MATH"
6034 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6036 ;; %%% Potential partial reg stall on alternative 2. What to do?
6037 (define_insn "*addqi_1_lea"
6038 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6039 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6040 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6041 (clobber (reg:CC FLAGS_REG))]
6042 "!TARGET_PARTIAL_REG_STALL
6043 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6045 int widen = (which_alternative == 2);
6046 switch (get_attr_type (insn))
6051 if (operands[2] == const1_rtx)
6052 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6055 gcc_assert (operands[2] == constm1_rtx);
6056 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6060 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6061 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6062 if (GET_CODE (operands[2]) == CONST_INT
6063 && (INTVAL (operands[2]) == 128
6064 || (INTVAL (operands[2]) < 0
6065 && INTVAL (operands[2]) != -128)))
6067 operands[2] = GEN_INT (-INTVAL (operands[2]));
6069 return "sub{l}\t{%2, %k0|%k0, %2}";
6071 return "sub{b}\t{%2, %0|%0, %2}";
6074 return "add{l}\t{%k2, %k0|%k0, %k2}";
6076 return "add{b}\t{%2, %0|%0, %2}";
6080 (if_then_else (eq_attr "alternative" "3")
6081 (const_string "lea")
6082 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6083 (const_string "incdec")
6084 (const_string "alu"))))
6085 (set_attr "mode" "QI,QI,SI,SI")])
6087 (define_insn "*addqi_1"
6088 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6089 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6090 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6091 (clobber (reg:CC FLAGS_REG))]
6092 "TARGET_PARTIAL_REG_STALL
6093 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6095 int widen = (which_alternative == 2);
6096 switch (get_attr_type (insn))
6099 if (operands[2] == const1_rtx)
6100 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6103 gcc_assert (operands[2] == constm1_rtx);
6104 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6108 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6109 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6110 if (GET_CODE (operands[2]) == CONST_INT
6111 && (INTVAL (operands[2]) == 128
6112 || (INTVAL (operands[2]) < 0
6113 && INTVAL (operands[2]) != -128)))
6115 operands[2] = GEN_INT (-INTVAL (operands[2]));
6117 return "sub{l}\t{%2, %k0|%k0, %2}";
6119 return "sub{b}\t{%2, %0|%0, %2}";
6122 return "add{l}\t{%k2, %k0|%k0, %k2}";
6124 return "add{b}\t{%2, %0|%0, %2}";
6128 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6129 (const_string "incdec")
6130 (const_string "alu")))
6131 (set_attr "mode" "QI,QI,SI")])
6133 (define_insn "*addqi_1_slp"
6134 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6135 (plus:QI (match_dup 0)
6136 (match_operand:QI 1 "general_operand" "qn,qnm")))
6137 (clobber (reg:CC FLAGS_REG))]
6138 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6139 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6141 switch (get_attr_type (insn))
6144 if (operands[1] == const1_rtx)
6145 return "inc{b}\t%0";
6148 gcc_assert (operands[1] == constm1_rtx);
6149 return "dec{b}\t%0";
6153 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6154 if (GET_CODE (operands[1]) == CONST_INT
6155 && INTVAL (operands[1]) < 0)
6157 operands[1] = GEN_INT (-INTVAL (operands[1]));
6158 return "sub{b}\t{%1, %0|%0, %1}";
6160 return "add{b}\t{%1, %0|%0, %1}";
6164 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6165 (const_string "incdec")
6166 (const_string "alu1")))
6167 (set (attr "memory")
6168 (if_then_else (match_operand 1 "memory_operand" "")
6169 (const_string "load")
6170 (const_string "none")))
6171 (set_attr "mode" "QI")])
6173 (define_insn "*addqi_2"
6174 [(set (reg FLAGS_REG)
6176 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6177 (match_operand:QI 2 "general_operand" "qmni,qni"))
6179 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6180 (plus:QI (match_dup 1) (match_dup 2)))]
6181 "ix86_match_ccmode (insn, CCGOCmode)
6182 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6184 switch (get_attr_type (insn))
6187 if (operands[2] == const1_rtx)
6188 return "inc{b}\t%0";
6191 gcc_assert (operands[2] == constm1_rtx
6192 || (GET_CODE (operands[2]) == CONST_INT
6193 && INTVAL (operands[2]) == 255));
6194 return "dec{b}\t%0";
6198 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6199 if (GET_CODE (operands[2]) == CONST_INT
6200 && INTVAL (operands[2]) < 0)
6202 operands[2] = GEN_INT (-INTVAL (operands[2]));
6203 return "sub{b}\t{%2, %0|%0, %2}";
6205 return "add{b}\t{%2, %0|%0, %2}";
6209 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6210 (const_string "incdec")
6211 (const_string "alu")))
6212 (set_attr "mode" "QI")])
6214 (define_insn "*addqi_3"
6215 [(set (reg FLAGS_REG)
6216 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6217 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6218 (clobber (match_scratch:QI 0 "=q"))]
6219 "ix86_match_ccmode (insn, CCZmode)
6220 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6222 switch (get_attr_type (insn))
6225 if (operands[2] == const1_rtx)
6226 return "inc{b}\t%0";
6229 gcc_assert (operands[2] == constm1_rtx
6230 || (GET_CODE (operands[2]) == CONST_INT
6231 && INTVAL (operands[2]) == 255));
6232 return "dec{b}\t%0";
6236 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6237 if (GET_CODE (operands[2]) == CONST_INT
6238 && INTVAL (operands[2]) < 0)
6240 operands[2] = GEN_INT (-INTVAL (operands[2]));
6241 return "sub{b}\t{%2, %0|%0, %2}";
6243 return "add{b}\t{%2, %0|%0, %2}";
6247 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6248 (const_string "incdec")
6249 (const_string "alu")))
6250 (set_attr "mode" "QI")])
6252 ; See comments above addsi_4 for details.
6253 (define_insn "*addqi_4"
6254 [(set (reg FLAGS_REG)
6255 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6256 (match_operand:QI 2 "const_int_operand" "n")))
6257 (clobber (match_scratch:QI 0 "=qm"))]
6258 "ix86_match_ccmode (insn, CCGCmode)
6259 && (INTVAL (operands[2]) & 0xff) != 0x80"
6261 switch (get_attr_type (insn))
6264 if (operands[2] == constm1_rtx
6265 || (GET_CODE (operands[2]) == CONST_INT
6266 && INTVAL (operands[2]) == 255))
6267 return "inc{b}\t%0";
6270 gcc_assert (operands[2] == const1_rtx);
6271 return "dec{b}\t%0";
6275 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6276 if (INTVAL (operands[2]) < 0)
6278 operands[2] = GEN_INT (-INTVAL (operands[2]));
6279 return "add{b}\t{%2, %0|%0, %2}";
6281 return "sub{b}\t{%2, %0|%0, %2}";
6285 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6286 (const_string "incdec")
6287 (const_string "alu")))
6288 (set_attr "mode" "QI")])
6291 (define_insn "*addqi_5"
6292 [(set (reg FLAGS_REG)
6294 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6295 (match_operand:QI 2 "general_operand" "qmni"))
6297 (clobber (match_scratch:QI 0 "=q"))]
6298 "ix86_match_ccmode (insn, CCGOCmode)
6299 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6301 switch (get_attr_type (insn))
6304 if (operands[2] == const1_rtx)
6305 return "inc{b}\t%0";
6308 gcc_assert (operands[2] == constm1_rtx
6309 || (GET_CODE (operands[2]) == CONST_INT
6310 && INTVAL (operands[2]) == 255));
6311 return "dec{b}\t%0";
6315 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6316 if (GET_CODE (operands[2]) == CONST_INT
6317 && INTVAL (operands[2]) < 0)
6319 operands[2] = GEN_INT (-INTVAL (operands[2]));
6320 return "sub{b}\t{%2, %0|%0, %2}";
6322 return "add{b}\t{%2, %0|%0, %2}";
6326 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6327 (const_string "incdec")
6328 (const_string "alu")))
6329 (set_attr "mode" "QI")])
6332 (define_insn "addqi_ext_1"
6333 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6338 (match_operand 1 "ext_register_operand" "0")
6341 (match_operand:QI 2 "general_operand" "Qmn")))
6342 (clobber (reg:CC FLAGS_REG))]
6345 switch (get_attr_type (insn))
6348 if (operands[2] == const1_rtx)
6349 return "inc{b}\t%h0";
6352 gcc_assert (operands[2] == constm1_rtx
6353 || (GET_CODE (operands[2]) == CONST_INT
6354 && INTVAL (operands[2]) == 255));
6355 return "dec{b}\t%h0";
6359 return "add{b}\t{%2, %h0|%h0, %2}";
6363 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6364 (const_string "incdec")
6365 (const_string "alu")))
6366 (set_attr "mode" "QI")])
6368 (define_insn "*addqi_ext_1_rex64"
6369 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6374 (match_operand 1 "ext_register_operand" "0")
6377 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6378 (clobber (reg:CC FLAGS_REG))]
6381 switch (get_attr_type (insn))
6384 if (operands[2] == const1_rtx)
6385 return "inc{b}\t%h0";
6388 gcc_assert (operands[2] == constm1_rtx
6389 || (GET_CODE (operands[2]) == CONST_INT
6390 && INTVAL (operands[2]) == 255));
6391 return "dec{b}\t%h0";
6395 return "add{b}\t{%2, %h0|%h0, %2}";
6399 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6400 (const_string "incdec")
6401 (const_string "alu")))
6402 (set_attr "mode" "QI")])
6404 (define_insn "*addqi_ext_2"
6405 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6410 (match_operand 1 "ext_register_operand" "%0")
6414 (match_operand 2 "ext_register_operand" "Q")
6417 (clobber (reg:CC FLAGS_REG))]
6419 "add{b}\t{%h2, %h0|%h0, %h2}"
6420 [(set_attr "type" "alu")
6421 (set_attr "mode" "QI")])
6423 ;; The patterns that match these are at the end of this file.
6425 (define_expand "addxf3"
6426 [(set (match_operand:XF 0 "register_operand" "")
6427 (plus:XF (match_operand:XF 1 "register_operand" "")
6428 (match_operand:XF 2 "register_operand" "")))]
6432 (define_expand "adddf3"
6433 [(set (match_operand:DF 0 "register_operand" "")
6434 (plus:DF (match_operand:DF 1 "register_operand" "")
6435 (match_operand:DF 2 "nonimmediate_operand" "")))]
6436 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6439 (define_expand "addsf3"
6440 [(set (match_operand:SF 0 "register_operand" "")
6441 (plus:SF (match_operand:SF 1 "register_operand" "")
6442 (match_operand:SF 2 "nonimmediate_operand" "")))]
6443 "TARGET_80387 || TARGET_SSE_MATH"
6446 ;; Subtract instructions
6448 ;; %%% splits for subditi3
6450 (define_expand "subti3"
6451 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6452 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6453 (match_operand:TI 2 "x86_64_general_operand" "")))
6454 (clobber (reg:CC FLAGS_REG))])]
6456 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6458 (define_insn "*subti3_1"
6459 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6460 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6461 (match_operand:TI 2 "general_operand" "roiF,riF")))
6462 (clobber (reg:CC FLAGS_REG))]
6463 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6467 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6468 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6469 (match_operand:TI 2 "general_operand" "")))
6470 (clobber (reg:CC FLAGS_REG))]
6471 "TARGET_64BIT && reload_completed"
6472 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6473 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6474 (parallel [(set (match_dup 3)
6475 (minus:DI (match_dup 4)
6476 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6478 (clobber (reg:CC FLAGS_REG))])]
6479 "split_ti (operands+0, 1, operands+0, operands+3);
6480 split_ti (operands+1, 1, operands+1, operands+4);
6481 split_ti (operands+2, 1, operands+2, operands+5);")
6483 ;; %%% splits for subsidi3
6485 (define_expand "subdi3"
6486 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6487 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6488 (match_operand:DI 2 "x86_64_general_operand" "")))
6489 (clobber (reg:CC FLAGS_REG))])]
6491 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6493 (define_insn "*subdi3_1"
6494 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6495 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6496 (match_operand:DI 2 "general_operand" "roiF,riF")))
6497 (clobber (reg:CC FLAGS_REG))]
6498 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6502 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6503 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6504 (match_operand:DI 2 "general_operand" "")))
6505 (clobber (reg:CC FLAGS_REG))]
6506 "!TARGET_64BIT && reload_completed"
6507 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6508 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6509 (parallel [(set (match_dup 3)
6510 (minus:SI (match_dup 4)
6511 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6513 (clobber (reg:CC FLAGS_REG))])]
6514 "split_di (operands+0, 1, operands+0, operands+3);
6515 split_di (operands+1, 1, operands+1, operands+4);
6516 split_di (operands+2, 1, operands+2, operands+5);")
6518 (define_insn "subdi3_carry_rex64"
6519 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6520 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6521 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6522 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6523 (clobber (reg:CC FLAGS_REG))]
6524 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6525 "sbb{q}\t{%2, %0|%0, %2}"
6526 [(set_attr "type" "alu")
6527 (set_attr "pent_pair" "pu")
6528 (set_attr "mode" "DI")])
6530 (define_insn "*subdi_1_rex64"
6531 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6532 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6533 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6534 (clobber (reg:CC FLAGS_REG))]
6535 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6536 "sub{q}\t{%2, %0|%0, %2}"
6537 [(set_attr "type" "alu")
6538 (set_attr "mode" "DI")])
6540 (define_insn "*subdi_2_rex64"
6541 [(set (reg FLAGS_REG)
6543 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6544 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6546 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6547 (minus:DI (match_dup 1) (match_dup 2)))]
6548 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6549 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6550 "sub{q}\t{%2, %0|%0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "mode" "DI")])
6554 (define_insn "*subdi_3_rex63"
6555 [(set (reg FLAGS_REG)
6556 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6557 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6558 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6559 (minus:DI (match_dup 1) (match_dup 2)))]
6560 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6561 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6562 "sub{q}\t{%2, %0|%0, %2}"
6563 [(set_attr "type" "alu")
6564 (set_attr "mode" "DI")])
6566 (define_insn "subqi3_carry"
6567 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6568 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6569 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6570 (match_operand:QI 2 "general_operand" "qi,qm"))))
6571 (clobber (reg:CC FLAGS_REG))]
6572 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6573 "sbb{b}\t{%2, %0|%0, %2}"
6574 [(set_attr "type" "alu")
6575 (set_attr "pent_pair" "pu")
6576 (set_attr "mode" "QI")])
6578 (define_insn "subhi3_carry"
6579 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6580 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6581 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6582 (match_operand:HI 2 "general_operand" "ri,rm"))))
6583 (clobber (reg:CC FLAGS_REG))]
6584 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6585 "sbb{w}\t{%2, %0|%0, %2}"
6586 [(set_attr "type" "alu")
6587 (set_attr "pent_pair" "pu")
6588 (set_attr "mode" "HI")])
6590 (define_insn "subsi3_carry"
6591 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6592 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6593 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6594 (match_operand:SI 2 "general_operand" "ri,rm"))))
6595 (clobber (reg:CC FLAGS_REG))]
6596 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6597 "sbb{l}\t{%2, %0|%0, %2}"
6598 [(set_attr "type" "alu")
6599 (set_attr "pent_pair" "pu")
6600 (set_attr "mode" "SI")])
6602 (define_insn "subsi3_carry_zext"
6603 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6605 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6606 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6607 (match_operand:SI 2 "general_operand" "ri,rm")))))
6608 (clobber (reg:CC FLAGS_REG))]
6609 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6610 "sbb{l}\t{%2, %k0|%k0, %2}"
6611 [(set_attr "type" "alu")
6612 (set_attr "pent_pair" "pu")
6613 (set_attr "mode" "SI")])
6615 (define_expand "subsi3"
6616 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6617 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6618 (match_operand:SI 2 "general_operand" "")))
6619 (clobber (reg:CC FLAGS_REG))])]
6621 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6623 (define_insn "*subsi_1"
6624 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6625 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6626 (match_operand:SI 2 "general_operand" "ri,rm")))
6627 (clobber (reg:CC FLAGS_REG))]
6628 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6629 "sub{l}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "mode" "SI")])
6633 (define_insn "*subsi_1_zext"
6634 [(set (match_operand:DI 0 "register_operand" "=r")
6636 (minus:SI (match_operand:SI 1 "register_operand" "0")
6637 (match_operand:SI 2 "general_operand" "rim"))))
6638 (clobber (reg:CC FLAGS_REG))]
6639 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6640 "sub{l}\t{%2, %k0|%k0, %2}"
6641 [(set_attr "type" "alu")
6642 (set_attr "mode" "SI")])
6644 (define_insn "*subsi_2"
6645 [(set (reg FLAGS_REG)
6647 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6648 (match_operand:SI 2 "general_operand" "ri,rm"))
6650 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6651 (minus:SI (match_dup 1) (match_dup 2)))]
6652 "ix86_match_ccmode (insn, CCGOCmode)
6653 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6654 "sub{l}\t{%2, %0|%0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "mode" "SI")])
6658 (define_insn "*subsi_2_zext"
6659 [(set (reg FLAGS_REG)
6661 (minus:SI (match_operand:SI 1 "register_operand" "0")
6662 (match_operand:SI 2 "general_operand" "rim"))
6664 (set (match_operand:DI 0 "register_operand" "=r")
6666 (minus:SI (match_dup 1)
6668 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6669 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6670 "sub{l}\t{%2, %k0|%k0, %2}"
6671 [(set_attr "type" "alu")
6672 (set_attr "mode" "SI")])
6674 (define_insn "*subsi_3"
6675 [(set (reg FLAGS_REG)
6676 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6677 (match_operand:SI 2 "general_operand" "ri,rm")))
6678 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6679 (minus:SI (match_dup 1) (match_dup 2)))]
6680 "ix86_match_ccmode (insn, CCmode)
6681 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6682 "sub{l}\t{%2, %0|%0, %2}"
6683 [(set_attr "type" "alu")
6684 (set_attr "mode" "SI")])
6686 (define_insn "*subsi_3_zext"
6687 [(set (reg FLAGS_REG)
6688 (compare (match_operand:SI 1 "register_operand" "0")
6689 (match_operand:SI 2 "general_operand" "rim")))
6690 (set (match_operand:DI 0 "register_operand" "=r")
6692 (minus:SI (match_dup 1)
6694 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6695 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6696 "sub{q}\t{%2, %0|%0, %2}"
6697 [(set_attr "type" "alu")
6698 (set_attr "mode" "DI")])
6700 (define_expand "subhi3"
6701 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6702 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6703 (match_operand:HI 2 "general_operand" "")))
6704 (clobber (reg:CC FLAGS_REG))])]
6705 "TARGET_HIMODE_MATH"
6706 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6708 (define_insn "*subhi_1"
6709 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6710 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6711 (match_operand:HI 2 "general_operand" "ri,rm")))
6712 (clobber (reg:CC FLAGS_REG))]
6713 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6714 "sub{w}\t{%2, %0|%0, %2}"
6715 [(set_attr "type" "alu")
6716 (set_attr "mode" "HI")])
6718 (define_insn "*subhi_2"
6719 [(set (reg FLAGS_REG)
6721 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6722 (match_operand:HI 2 "general_operand" "ri,rm"))
6724 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6725 (minus:HI (match_dup 1) (match_dup 2)))]
6726 "ix86_match_ccmode (insn, CCGOCmode)
6727 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6728 "sub{w}\t{%2, %0|%0, %2}"
6729 [(set_attr "type" "alu")
6730 (set_attr "mode" "HI")])
6732 (define_insn "*subhi_3"
6733 [(set (reg FLAGS_REG)
6734 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6735 (match_operand:HI 2 "general_operand" "ri,rm")))
6736 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6737 (minus:HI (match_dup 1) (match_dup 2)))]
6738 "ix86_match_ccmode (insn, CCmode)
6739 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6740 "sub{w}\t{%2, %0|%0, %2}"
6741 [(set_attr "type" "alu")
6742 (set_attr "mode" "HI")])
6744 (define_expand "subqi3"
6745 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6746 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6747 (match_operand:QI 2 "general_operand" "")))
6748 (clobber (reg:CC FLAGS_REG))])]
6749 "TARGET_QIMODE_MATH"
6750 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6752 (define_insn "*subqi_1"
6753 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6754 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6755 (match_operand:QI 2 "general_operand" "qn,qmn")))
6756 (clobber (reg:CC FLAGS_REG))]
6757 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6758 "sub{b}\t{%2, %0|%0, %2}"
6759 [(set_attr "type" "alu")
6760 (set_attr "mode" "QI")])
6762 (define_insn "*subqi_1_slp"
6763 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6764 (minus:QI (match_dup 0)
6765 (match_operand:QI 1 "general_operand" "qn,qmn")))
6766 (clobber (reg:CC FLAGS_REG))]
6767 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6768 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6769 "sub{b}\t{%1, %0|%0, %1}"
6770 [(set_attr "type" "alu1")
6771 (set_attr "mode" "QI")])
6773 (define_insn "*subqi_2"
6774 [(set (reg FLAGS_REG)
6776 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6777 (match_operand:QI 2 "general_operand" "qi,qm"))
6779 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6780 (minus:HI (match_dup 1) (match_dup 2)))]
6781 "ix86_match_ccmode (insn, CCGOCmode)
6782 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6783 "sub{b}\t{%2, %0|%0, %2}"
6784 [(set_attr "type" "alu")
6785 (set_attr "mode" "QI")])
6787 (define_insn "*subqi_3"
6788 [(set (reg FLAGS_REG)
6789 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6790 (match_operand:QI 2 "general_operand" "qi,qm")))
6791 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6792 (minus:HI (match_dup 1) (match_dup 2)))]
6793 "ix86_match_ccmode (insn, CCmode)
6794 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6795 "sub{b}\t{%2, %0|%0, %2}"
6796 [(set_attr "type" "alu")
6797 (set_attr "mode" "QI")])
6799 ;; The patterns that match these are at the end of this file.
6801 (define_expand "subxf3"
6802 [(set (match_operand:XF 0 "register_operand" "")
6803 (minus:XF (match_operand:XF 1 "register_operand" "")
6804 (match_operand:XF 2 "register_operand" "")))]
6808 (define_expand "subdf3"
6809 [(set (match_operand:DF 0 "register_operand" "")
6810 (minus:DF (match_operand:DF 1 "register_operand" "")
6811 (match_operand:DF 2 "nonimmediate_operand" "")))]
6812 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6815 (define_expand "subsf3"
6816 [(set (match_operand:SF 0 "register_operand" "")
6817 (minus:SF (match_operand:SF 1 "register_operand" "")
6818 (match_operand:SF 2 "nonimmediate_operand" "")))]
6819 "TARGET_80387 || TARGET_SSE_MATH"
6822 ;; Multiply instructions
6824 (define_expand "muldi3"
6825 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6826 (mult:DI (match_operand:DI 1 "register_operand" "")
6827 (match_operand:DI 2 "x86_64_general_operand" "")))
6828 (clobber (reg:CC FLAGS_REG))])]
6832 (define_insn "*muldi3_1_rex64"
6833 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6834 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6835 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6836 (clobber (reg:CC FLAGS_REG))]
6838 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6840 imul{q}\t{%2, %1, %0|%0, %1, %2}
6841 imul{q}\t{%2, %1, %0|%0, %1, %2}
6842 imul{q}\t{%2, %0|%0, %2}"
6843 [(set_attr "type" "imul")
6844 (set_attr "prefix_0f" "0,0,1")
6845 (set (attr "athlon_decode")
6846 (cond [(eq_attr "cpu" "athlon")
6847 (const_string "vector")
6848 (eq_attr "alternative" "1")
6849 (const_string "vector")
6850 (and (eq_attr "alternative" "2")
6851 (match_operand 1 "memory_operand" ""))
6852 (const_string "vector")]
6853 (const_string "direct")))
6854 (set_attr "mode" "DI")])
6856 (define_expand "mulsi3"
6857 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6858 (mult:SI (match_operand:SI 1 "register_operand" "")
6859 (match_operand:SI 2 "general_operand" "")))
6860 (clobber (reg:CC FLAGS_REG))])]
6864 (define_insn "*mulsi3_1"
6865 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6866 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6867 (match_operand:SI 2 "general_operand" "K,i,mr")))
6868 (clobber (reg:CC FLAGS_REG))]
6869 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6871 imul{l}\t{%2, %1, %0|%0, %1, %2}
6872 imul{l}\t{%2, %1, %0|%0, %1, %2}
6873 imul{l}\t{%2, %0|%0, %2}"
6874 [(set_attr "type" "imul")
6875 (set_attr "prefix_0f" "0,0,1")
6876 (set (attr "athlon_decode")
6877 (cond [(eq_attr "cpu" "athlon")
6878 (const_string "vector")
6879 (eq_attr "alternative" "1")
6880 (const_string "vector")
6881 (and (eq_attr "alternative" "2")
6882 (match_operand 1 "memory_operand" ""))
6883 (const_string "vector")]
6884 (const_string "direct")))
6885 (set_attr "mode" "SI")])
6887 (define_insn "*mulsi3_1_zext"
6888 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6890 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6891 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6892 (clobber (reg:CC FLAGS_REG))]
6894 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6896 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6897 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6898 imul{l}\t{%2, %k0|%k0, %2}"
6899 [(set_attr "type" "imul")
6900 (set_attr "prefix_0f" "0,0,1")
6901 (set (attr "athlon_decode")
6902 (cond [(eq_attr "cpu" "athlon")
6903 (const_string "vector")
6904 (eq_attr "alternative" "1")
6905 (const_string "vector")
6906 (and (eq_attr "alternative" "2")
6907 (match_operand 1 "memory_operand" ""))
6908 (const_string "vector")]
6909 (const_string "direct")))
6910 (set_attr "mode" "SI")])
6912 (define_expand "mulhi3"
6913 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6914 (mult:HI (match_operand:HI 1 "register_operand" "")
6915 (match_operand:HI 2 "general_operand" "")))
6916 (clobber (reg:CC FLAGS_REG))])]
6917 "TARGET_HIMODE_MATH"
6920 (define_insn "*mulhi3_1"
6921 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6922 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6923 (match_operand:HI 2 "general_operand" "K,i,mr")))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6927 imul{w}\t{%2, %1, %0|%0, %1, %2}
6928 imul{w}\t{%2, %1, %0|%0, %1, %2}
6929 imul{w}\t{%2, %0|%0, %2}"
6930 [(set_attr "type" "imul")
6931 (set_attr "prefix_0f" "0,0,1")
6932 (set (attr "athlon_decode")
6933 (cond [(eq_attr "cpu" "athlon")
6934 (const_string "vector")
6935 (eq_attr "alternative" "1,2")
6936 (const_string "vector")]
6937 (const_string "direct")))
6938 (set_attr "mode" "HI")])
6940 (define_expand "mulqi3"
6941 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6942 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6943 (match_operand:QI 2 "register_operand" "")))
6944 (clobber (reg:CC FLAGS_REG))])]
6945 "TARGET_QIMODE_MATH"
6948 (define_insn "*mulqi3_1"
6949 [(set (match_operand:QI 0 "register_operand" "=a")
6950 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6951 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6952 (clobber (reg:CC FLAGS_REG))]
6954 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6956 [(set_attr "type" "imul")
6957 (set_attr "length_immediate" "0")
6958 (set (attr "athlon_decode")
6959 (if_then_else (eq_attr "cpu" "athlon")
6960 (const_string "vector")
6961 (const_string "direct")))
6962 (set_attr "mode" "QI")])
6964 (define_expand "umulqihi3"
6965 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6966 (mult:HI (zero_extend:HI
6967 (match_operand:QI 1 "nonimmediate_operand" ""))
6969 (match_operand:QI 2 "register_operand" ""))))
6970 (clobber (reg:CC FLAGS_REG))])]
6971 "TARGET_QIMODE_MATH"
6974 (define_insn "*umulqihi3_1"
6975 [(set (match_operand:HI 0 "register_operand" "=a")
6976 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6977 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6978 (clobber (reg:CC FLAGS_REG))]
6980 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6982 [(set_attr "type" "imul")
6983 (set_attr "length_immediate" "0")
6984 (set (attr "athlon_decode")
6985 (if_then_else (eq_attr "cpu" "athlon")
6986 (const_string "vector")
6987 (const_string "direct")))
6988 (set_attr "mode" "QI")])
6990 (define_expand "mulqihi3"
6991 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6992 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6993 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6994 (clobber (reg:CC FLAGS_REG))])]
6995 "TARGET_QIMODE_MATH"
6998 (define_insn "*mulqihi3_insn"
6999 [(set (match_operand:HI 0 "register_operand" "=a")
7000 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7001 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7002 (clobber (reg:CC FLAGS_REG))]
7004 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7006 [(set_attr "type" "imul")
7007 (set_attr "length_immediate" "0")
7008 (set (attr "athlon_decode")
7009 (if_then_else (eq_attr "cpu" "athlon")
7010 (const_string "vector")
7011 (const_string "direct")))
7012 (set_attr "mode" "QI")])
7014 (define_expand "umulditi3"
7015 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7016 (mult:TI (zero_extend:TI
7017 (match_operand:DI 1 "nonimmediate_operand" ""))
7019 (match_operand:DI 2 "register_operand" ""))))
7020 (clobber (reg:CC FLAGS_REG))])]
7024 (define_insn "*umulditi3_insn"
7025 [(set (match_operand:TI 0 "register_operand" "=A")
7026 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7027 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7028 (clobber (reg:CC FLAGS_REG))]
7030 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7032 [(set_attr "type" "imul")
7033 (set_attr "length_immediate" "0")
7034 (set (attr "athlon_decode")
7035 (if_then_else (eq_attr "cpu" "athlon")
7036 (const_string "vector")
7037 (const_string "double")))
7038 (set_attr "mode" "DI")])
7040 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7041 (define_expand "umulsidi3"
7042 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7043 (mult:DI (zero_extend:DI
7044 (match_operand:SI 1 "nonimmediate_operand" ""))
7046 (match_operand:SI 2 "register_operand" ""))))
7047 (clobber (reg:CC FLAGS_REG))])]
7051 (define_insn "*umulsidi3_insn"
7052 [(set (match_operand:DI 0 "register_operand" "=A")
7053 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7054 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7055 (clobber (reg:CC FLAGS_REG))]
7057 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7059 [(set_attr "type" "imul")
7060 (set_attr "length_immediate" "0")
7061 (set (attr "athlon_decode")
7062 (if_then_else (eq_attr "cpu" "athlon")
7063 (const_string "vector")
7064 (const_string "double")))
7065 (set_attr "mode" "SI")])
7067 (define_expand "mulditi3"
7068 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7069 (mult:TI (sign_extend:TI
7070 (match_operand:DI 1 "nonimmediate_operand" ""))
7072 (match_operand:DI 2 "register_operand" ""))))
7073 (clobber (reg:CC FLAGS_REG))])]
7077 (define_insn "*mulditi3_insn"
7078 [(set (match_operand:TI 0 "register_operand" "=A")
7079 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7080 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7081 (clobber (reg:CC FLAGS_REG))]
7083 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7085 [(set_attr "type" "imul")
7086 (set_attr "length_immediate" "0")
7087 (set (attr "athlon_decode")
7088 (if_then_else (eq_attr "cpu" "athlon")
7089 (const_string "vector")
7090 (const_string "double")))
7091 (set_attr "mode" "DI")])
7093 (define_expand "mulsidi3"
7094 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7095 (mult:DI (sign_extend:DI
7096 (match_operand:SI 1 "nonimmediate_operand" ""))
7098 (match_operand:SI 2 "register_operand" ""))))
7099 (clobber (reg:CC FLAGS_REG))])]
7103 (define_insn "*mulsidi3_insn"
7104 [(set (match_operand:DI 0 "register_operand" "=A")
7105 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7106 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7107 (clobber (reg:CC FLAGS_REG))]
7109 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7111 [(set_attr "type" "imul")
7112 (set_attr "length_immediate" "0")
7113 (set (attr "athlon_decode")
7114 (if_then_else (eq_attr "cpu" "athlon")
7115 (const_string "vector")
7116 (const_string "double")))
7117 (set_attr "mode" "SI")])
7119 (define_expand "umuldi3_highpart"
7120 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7123 (mult:TI (zero_extend:TI
7124 (match_operand:DI 1 "nonimmediate_operand" ""))
7126 (match_operand:DI 2 "register_operand" "")))
7128 (clobber (match_scratch:DI 3 ""))
7129 (clobber (reg:CC FLAGS_REG))])]
7133 (define_insn "*umuldi3_highpart_rex64"
7134 [(set (match_operand:DI 0 "register_operand" "=d")
7137 (mult:TI (zero_extend:TI
7138 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7140 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7142 (clobber (match_scratch:DI 3 "=1"))
7143 (clobber (reg:CC FLAGS_REG))]
7145 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7147 [(set_attr "type" "imul")
7148 (set_attr "length_immediate" "0")
7149 (set (attr "athlon_decode")
7150 (if_then_else (eq_attr "cpu" "athlon")
7151 (const_string "vector")
7152 (const_string "double")))
7153 (set_attr "mode" "DI")])
7155 (define_expand "umulsi3_highpart"
7156 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7159 (mult:DI (zero_extend:DI
7160 (match_operand:SI 1 "nonimmediate_operand" ""))
7162 (match_operand:SI 2 "register_operand" "")))
7164 (clobber (match_scratch:SI 3 ""))
7165 (clobber (reg:CC FLAGS_REG))])]
7169 (define_insn "*umulsi3_highpart_insn"
7170 [(set (match_operand:SI 0 "register_operand" "=d")
7173 (mult:DI (zero_extend:DI
7174 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7176 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7178 (clobber (match_scratch:SI 3 "=1"))
7179 (clobber (reg:CC FLAGS_REG))]
7180 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7182 [(set_attr "type" "imul")
7183 (set_attr "length_immediate" "0")
7184 (set (attr "athlon_decode")
7185 (if_then_else (eq_attr "cpu" "athlon")
7186 (const_string "vector")
7187 (const_string "double")))
7188 (set_attr "mode" "SI")])
7190 (define_insn "*umulsi3_highpart_zext"
7191 [(set (match_operand:DI 0 "register_operand" "=d")
7192 (zero_extend:DI (truncate:SI
7194 (mult:DI (zero_extend:DI
7195 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7197 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7199 (clobber (match_scratch:SI 3 "=1"))
7200 (clobber (reg:CC FLAGS_REG))]
7202 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7204 [(set_attr "type" "imul")
7205 (set_attr "length_immediate" "0")
7206 (set (attr "athlon_decode")
7207 (if_then_else (eq_attr "cpu" "athlon")
7208 (const_string "vector")
7209 (const_string "double")))
7210 (set_attr "mode" "SI")])
7212 (define_expand "smuldi3_highpart"
7213 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7216 (mult:TI (sign_extend:TI
7217 (match_operand:DI 1 "nonimmediate_operand" ""))
7219 (match_operand:DI 2 "register_operand" "")))
7221 (clobber (match_scratch:DI 3 ""))
7222 (clobber (reg:CC FLAGS_REG))])]
7226 (define_insn "*smuldi3_highpart_rex64"
7227 [(set (match_operand:DI 0 "register_operand" "=d")
7230 (mult:TI (sign_extend:TI
7231 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7233 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7235 (clobber (match_scratch:DI 3 "=1"))
7236 (clobber (reg:CC FLAGS_REG))]
7238 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7240 [(set_attr "type" "imul")
7241 (set (attr "athlon_decode")
7242 (if_then_else (eq_attr "cpu" "athlon")
7243 (const_string "vector")
7244 (const_string "double")))
7245 (set_attr "mode" "DI")])
7247 (define_expand "smulsi3_highpart"
7248 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7251 (mult:DI (sign_extend:DI
7252 (match_operand:SI 1 "nonimmediate_operand" ""))
7254 (match_operand:SI 2 "register_operand" "")))
7256 (clobber (match_scratch:SI 3 ""))
7257 (clobber (reg:CC FLAGS_REG))])]
7261 (define_insn "*smulsi3_highpart_insn"
7262 [(set (match_operand:SI 0 "register_operand" "=d")
7265 (mult:DI (sign_extend:DI
7266 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7268 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7270 (clobber (match_scratch:SI 3 "=1"))
7271 (clobber (reg:CC FLAGS_REG))]
7272 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7274 [(set_attr "type" "imul")
7275 (set (attr "athlon_decode")
7276 (if_then_else (eq_attr "cpu" "athlon")
7277 (const_string "vector")
7278 (const_string "double")))
7279 (set_attr "mode" "SI")])
7281 (define_insn "*smulsi3_highpart_zext"
7282 [(set (match_operand:DI 0 "register_operand" "=d")
7283 (zero_extend:DI (truncate:SI
7285 (mult:DI (sign_extend:DI
7286 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7288 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7290 (clobber (match_scratch:SI 3 "=1"))
7291 (clobber (reg:CC FLAGS_REG))]
7293 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7295 [(set_attr "type" "imul")
7296 (set (attr "athlon_decode")
7297 (if_then_else (eq_attr "cpu" "athlon")
7298 (const_string "vector")
7299 (const_string "double")))
7300 (set_attr "mode" "SI")])
7302 ;; The patterns that match these are at the end of this file.
7304 (define_expand "mulxf3"
7305 [(set (match_operand:XF 0 "register_operand" "")
7306 (mult:XF (match_operand:XF 1 "register_operand" "")
7307 (match_operand:XF 2 "register_operand" "")))]
7311 (define_expand "muldf3"
7312 [(set (match_operand:DF 0 "register_operand" "")
7313 (mult:DF (match_operand:DF 1 "register_operand" "")
7314 (match_operand:DF 2 "nonimmediate_operand" "")))]
7315 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7318 (define_expand "mulsf3"
7319 [(set (match_operand:SF 0 "register_operand" "")
7320 (mult:SF (match_operand:SF 1 "register_operand" "")
7321 (match_operand:SF 2 "nonimmediate_operand" "")))]
7322 "TARGET_80387 || TARGET_SSE_MATH"
7325 ;; Divide instructions
7327 (define_insn "divqi3"
7328 [(set (match_operand:QI 0 "register_operand" "=a")
7329 (div: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 (define_insn "udivqi3"
7338 [(set (match_operand:QI 0 "register_operand" "=a")
7339 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7340 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7341 (clobber (reg:CC FLAGS_REG))]
7342 "TARGET_QIMODE_MATH"
7344 [(set_attr "type" "idiv")
7345 (set_attr "mode" "QI")])
7347 ;; The patterns that match these are at the end of this file.
7349 (define_expand "divxf3"
7350 [(set (match_operand:XF 0 "register_operand" "")
7351 (div:XF (match_operand:XF 1 "register_operand" "")
7352 (match_operand:XF 2 "register_operand" "")))]
7356 (define_expand "divdf3"
7357 [(set (match_operand:DF 0 "register_operand" "")
7358 (div:DF (match_operand:DF 1 "register_operand" "")
7359 (match_operand:DF 2 "nonimmediate_operand" "")))]
7360 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7363 (define_expand "divsf3"
7364 [(set (match_operand:SF 0 "register_operand" "")
7365 (div:SF (match_operand:SF 1 "register_operand" "")
7366 (match_operand:SF 2 "nonimmediate_operand" "")))]
7367 "TARGET_80387 || TARGET_SSE_MATH"
7370 ;; Remainder instructions.
7372 (define_expand "divmoddi4"
7373 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7374 (div:DI (match_operand:DI 1 "register_operand" "")
7375 (match_operand:DI 2 "nonimmediate_operand" "")))
7376 (set (match_operand:DI 3 "register_operand" "")
7377 (mod:DI (match_dup 1) (match_dup 2)))
7378 (clobber (reg:CC FLAGS_REG))])]
7382 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7383 ;; Penalize eax case slightly because it results in worse scheduling
7385 (define_insn "*divmoddi4_nocltd_rex64"
7386 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7387 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7388 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7389 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7390 (mod:DI (match_dup 2) (match_dup 3)))
7391 (clobber (reg:CC FLAGS_REG))]
7392 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7394 [(set_attr "type" "multi")])
7396 (define_insn "*divmoddi4_cltd_rex64"
7397 [(set (match_operand:DI 0 "register_operand" "=a")
7398 (div:DI (match_operand:DI 2 "register_operand" "a")
7399 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7400 (set (match_operand:DI 1 "register_operand" "=&d")
7401 (mod:DI (match_dup 2) (match_dup 3)))
7402 (clobber (reg:CC FLAGS_REG))]
7403 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7405 [(set_attr "type" "multi")])
7407 (define_insn "*divmoddi_noext_rex64"
7408 [(set (match_operand:DI 0 "register_operand" "=a")
7409 (div:DI (match_operand:DI 1 "register_operand" "0")
7410 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7411 (set (match_operand:DI 3 "register_operand" "=d")
7412 (mod:DI (match_dup 1) (match_dup 2)))
7413 (use (match_operand:DI 4 "register_operand" "3"))
7414 (clobber (reg:CC FLAGS_REG))]
7417 [(set_attr "type" "idiv")
7418 (set_attr "mode" "DI")])
7421 [(set (match_operand:DI 0 "register_operand" "")
7422 (div:DI (match_operand:DI 1 "register_operand" "")
7423 (match_operand:DI 2 "nonimmediate_operand" "")))
7424 (set (match_operand:DI 3 "register_operand" "")
7425 (mod:DI (match_dup 1) (match_dup 2)))
7426 (clobber (reg:CC FLAGS_REG))]
7427 "TARGET_64BIT && reload_completed"
7428 [(parallel [(set (match_dup 3)
7429 (ashiftrt:DI (match_dup 4) (const_int 63)))
7430 (clobber (reg:CC FLAGS_REG))])
7431 (parallel [(set (match_dup 0)
7432 (div:DI (reg:DI 0) (match_dup 2)))
7434 (mod:DI (reg:DI 0) (match_dup 2)))
7436 (clobber (reg:CC FLAGS_REG))])]
7438 /* Avoid use of cltd in favor of a mov+shift. */
7439 if (!TARGET_USE_CLTD && !optimize_size)
7441 if (true_regnum (operands[1]))
7442 emit_move_insn (operands[0], operands[1]);
7444 emit_move_insn (operands[3], operands[1]);
7445 operands[4] = operands[3];
7449 gcc_assert (!true_regnum (operands[1]));
7450 operands[4] = operands[1];
7455 (define_expand "divmodsi4"
7456 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7457 (div:SI (match_operand:SI 1 "register_operand" "")
7458 (match_operand:SI 2 "nonimmediate_operand" "")))
7459 (set (match_operand:SI 3 "register_operand" "")
7460 (mod:SI (match_dup 1) (match_dup 2)))
7461 (clobber (reg:CC FLAGS_REG))])]
7465 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7466 ;; Penalize eax case slightly because it results in worse scheduling
7468 (define_insn "*divmodsi4_nocltd"
7469 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7470 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7471 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7472 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7473 (mod:SI (match_dup 2) (match_dup 3)))
7474 (clobber (reg:CC FLAGS_REG))]
7475 "!optimize_size && !TARGET_USE_CLTD"
7477 [(set_attr "type" "multi")])
7479 (define_insn "*divmodsi4_cltd"
7480 [(set (match_operand:SI 0 "register_operand" "=a")
7481 (div:SI (match_operand:SI 2 "register_operand" "a")
7482 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7483 (set (match_operand:SI 1 "register_operand" "=&d")
7484 (mod:SI (match_dup 2) (match_dup 3)))
7485 (clobber (reg:CC FLAGS_REG))]
7486 "optimize_size || TARGET_USE_CLTD"
7488 [(set_attr "type" "multi")])
7490 (define_insn "*divmodsi_noext"
7491 [(set (match_operand:SI 0 "register_operand" "=a")
7492 (div:SI (match_operand:SI 1 "register_operand" "0")
7493 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7494 (set (match_operand:SI 3 "register_operand" "=d")
7495 (mod:SI (match_dup 1) (match_dup 2)))
7496 (use (match_operand:SI 4 "register_operand" "3"))
7497 (clobber (reg:CC FLAGS_REG))]
7500 [(set_attr "type" "idiv")
7501 (set_attr "mode" "SI")])
7504 [(set (match_operand:SI 0 "register_operand" "")
7505 (div:SI (match_operand:SI 1 "register_operand" "")
7506 (match_operand:SI 2 "nonimmediate_operand" "")))
7507 (set (match_operand:SI 3 "register_operand" "")
7508 (mod:SI (match_dup 1) (match_dup 2)))
7509 (clobber (reg:CC FLAGS_REG))]
7511 [(parallel [(set (match_dup 3)
7512 (ashiftrt:SI (match_dup 4) (const_int 31)))
7513 (clobber (reg:CC FLAGS_REG))])
7514 (parallel [(set (match_dup 0)
7515 (div:SI (reg:SI 0) (match_dup 2)))
7517 (mod:SI (reg:SI 0) (match_dup 2)))
7519 (clobber (reg:CC FLAGS_REG))])]
7521 /* Avoid use of cltd in favor of a mov+shift. */
7522 if (!TARGET_USE_CLTD && !optimize_size)
7524 if (true_regnum (operands[1]))
7525 emit_move_insn (operands[0], operands[1]);
7527 emit_move_insn (operands[3], operands[1]);
7528 operands[4] = operands[3];
7532 gcc_assert (!true_regnum (operands[1]));
7533 operands[4] = operands[1];
7537 (define_insn "divmodhi4"
7538 [(set (match_operand:HI 0 "register_operand" "=a")
7539 (div:HI (match_operand:HI 1 "register_operand" "0")
7540 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7541 (set (match_operand:HI 3 "register_operand" "=&d")
7542 (mod:HI (match_dup 1) (match_dup 2)))
7543 (clobber (reg:CC FLAGS_REG))]
7544 "TARGET_HIMODE_MATH"
7546 [(set_attr "type" "multi")
7547 (set_attr "length_immediate" "0")
7548 (set_attr "mode" "SI")])
7550 (define_insn "udivmoddi4"
7551 [(set (match_operand:DI 0 "register_operand" "=a")
7552 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7553 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7554 (set (match_operand:DI 3 "register_operand" "=&d")
7555 (umod:DI (match_dup 1) (match_dup 2)))
7556 (clobber (reg:CC FLAGS_REG))]
7558 "xor{q}\t%3, %3\;div{q}\t%2"
7559 [(set_attr "type" "multi")
7560 (set_attr "length_immediate" "0")
7561 (set_attr "mode" "DI")])
7563 (define_insn "*udivmoddi4_noext"
7564 [(set (match_operand:DI 0 "register_operand" "=a")
7565 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7566 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7567 (set (match_operand:DI 3 "register_operand" "=d")
7568 (umod:DI (match_dup 1) (match_dup 2)))
7570 (clobber (reg:CC FLAGS_REG))]
7573 [(set_attr "type" "idiv")
7574 (set_attr "mode" "DI")])
7577 [(set (match_operand:DI 0 "register_operand" "")
7578 (udiv:DI (match_operand:DI 1 "register_operand" "")
7579 (match_operand:DI 2 "nonimmediate_operand" "")))
7580 (set (match_operand:DI 3 "register_operand" "")
7581 (umod:DI (match_dup 1) (match_dup 2)))
7582 (clobber (reg:CC FLAGS_REG))]
7583 "TARGET_64BIT && reload_completed"
7584 [(set (match_dup 3) (const_int 0))
7585 (parallel [(set (match_dup 0)
7586 (udiv:DI (match_dup 1) (match_dup 2)))
7588 (umod:DI (match_dup 1) (match_dup 2)))
7590 (clobber (reg:CC FLAGS_REG))])]
7593 (define_insn "udivmodsi4"
7594 [(set (match_operand:SI 0 "register_operand" "=a")
7595 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7596 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7597 (set (match_operand:SI 3 "register_operand" "=&d")
7598 (umod:SI (match_dup 1) (match_dup 2)))
7599 (clobber (reg:CC FLAGS_REG))]
7601 "xor{l}\t%3, %3\;div{l}\t%2"
7602 [(set_attr "type" "multi")
7603 (set_attr "length_immediate" "0")
7604 (set_attr "mode" "SI")])
7606 (define_insn "*udivmodsi4_noext"
7607 [(set (match_operand:SI 0 "register_operand" "=a")
7608 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7609 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7610 (set (match_operand:SI 3 "register_operand" "=d")
7611 (umod:SI (match_dup 1) (match_dup 2)))
7613 (clobber (reg:CC FLAGS_REG))]
7616 [(set_attr "type" "idiv")
7617 (set_attr "mode" "SI")])
7620 [(set (match_operand:SI 0 "register_operand" "")
7621 (udiv:SI (match_operand:SI 1 "register_operand" "")
7622 (match_operand:SI 2 "nonimmediate_operand" "")))
7623 (set (match_operand:SI 3 "register_operand" "")
7624 (umod:SI (match_dup 1) (match_dup 2)))
7625 (clobber (reg:CC FLAGS_REG))]
7627 [(set (match_dup 3) (const_int 0))
7628 (parallel [(set (match_dup 0)
7629 (udiv:SI (match_dup 1) (match_dup 2)))
7631 (umod:SI (match_dup 1) (match_dup 2)))
7633 (clobber (reg:CC FLAGS_REG))])]
7636 (define_expand "udivmodhi4"
7637 [(set (match_dup 4) (const_int 0))
7638 (parallel [(set (match_operand:HI 0 "register_operand" "")
7639 (udiv:HI (match_operand:HI 1 "register_operand" "")
7640 (match_operand:HI 2 "nonimmediate_operand" "")))
7641 (set (match_operand:HI 3 "register_operand" "")
7642 (umod:HI (match_dup 1) (match_dup 2)))
7644 (clobber (reg:CC FLAGS_REG))])]
7645 "TARGET_HIMODE_MATH"
7646 "operands[4] = gen_reg_rtx (HImode);")
7648 (define_insn "*udivmodhi_noext"
7649 [(set (match_operand:HI 0 "register_operand" "=a")
7650 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7651 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7652 (set (match_operand:HI 3 "register_operand" "=d")
7653 (umod:HI (match_dup 1) (match_dup 2)))
7654 (use (match_operand:HI 4 "register_operand" "3"))
7655 (clobber (reg:CC FLAGS_REG))]
7658 [(set_attr "type" "idiv")
7659 (set_attr "mode" "HI")])
7661 ;; We cannot use div/idiv for double division, because it causes
7662 ;; "division by zero" on the overflow and that's not what we expect
7663 ;; from truncate. Because true (non truncating) double division is
7664 ;; never generated, we can't create this insn anyway.
7667 ; [(set (match_operand:SI 0 "register_operand" "=a")
7669 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7671 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7672 ; (set (match_operand:SI 3 "register_operand" "=d")
7674 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7675 ; (clobber (reg:CC FLAGS_REG))]
7677 ; "div{l}\t{%2, %0|%0, %2}"
7678 ; [(set_attr "type" "idiv")])
7680 ;;- Logical AND instructions
7682 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7683 ;; Note that this excludes ah.
7685 (define_insn "*testdi_1_rex64"
7686 [(set (reg FLAGS_REG)
7688 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7689 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7691 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7692 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7694 test{l}\t{%k1, %k0|%k0, %k1}
7695 test{l}\t{%k1, %k0|%k0, %k1}
7696 test{q}\t{%1, %0|%0, %1}
7697 test{q}\t{%1, %0|%0, %1}
7698 test{q}\t{%1, %0|%0, %1}"
7699 [(set_attr "type" "test")
7700 (set_attr "modrm" "0,1,0,1,1")
7701 (set_attr "mode" "SI,SI,DI,DI,DI")
7702 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7704 (define_insn "testsi_1"
7705 [(set (reg FLAGS_REG)
7707 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7708 (match_operand:SI 1 "general_operand" "in,in,rin"))
7710 "ix86_match_ccmode (insn, CCNOmode)
7711 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7712 "test{l}\t{%1, %0|%0, %1}"
7713 [(set_attr "type" "test")
7714 (set_attr "modrm" "0,1,1")
7715 (set_attr "mode" "SI")
7716 (set_attr "pent_pair" "uv,np,uv")])
7718 (define_expand "testsi_ccno_1"
7719 [(set (reg:CCNO FLAGS_REG)
7721 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7722 (match_operand:SI 1 "nonmemory_operand" ""))
7727 (define_insn "*testhi_1"
7728 [(set (reg FLAGS_REG)
7729 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7730 (match_operand:HI 1 "general_operand" "n,n,rn"))
7732 "ix86_match_ccmode (insn, CCNOmode)
7733 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7734 "test{w}\t{%1, %0|%0, %1}"
7735 [(set_attr "type" "test")
7736 (set_attr "modrm" "0,1,1")
7737 (set_attr "mode" "HI")
7738 (set_attr "pent_pair" "uv,np,uv")])
7740 (define_expand "testqi_ccz_1"
7741 [(set (reg:CCZ FLAGS_REG)
7742 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7743 (match_operand:QI 1 "nonmemory_operand" ""))
7748 (define_insn "*testqi_1_maybe_si"
7749 [(set (reg FLAGS_REG)
7752 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7753 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7755 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7756 && ix86_match_ccmode (insn,
7757 GET_CODE (operands[1]) == CONST_INT
7758 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7760 if (which_alternative == 3)
7762 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7763 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7764 return "test{l}\t{%1, %k0|%k0, %1}";
7766 return "test{b}\t{%1, %0|%0, %1}";
7768 [(set_attr "type" "test")
7769 (set_attr "modrm" "0,1,1,1")
7770 (set_attr "mode" "QI,QI,QI,SI")
7771 (set_attr "pent_pair" "uv,np,uv,np")])
7773 (define_insn "*testqi_1"
7774 [(set (reg FLAGS_REG)
7777 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7778 (match_operand:QI 1 "general_operand" "n,n,qn"))
7780 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7781 && ix86_match_ccmode (insn, CCNOmode)"
7782 "test{b}\t{%1, %0|%0, %1}"
7783 [(set_attr "type" "test")
7784 (set_attr "modrm" "0,1,1")
7785 (set_attr "mode" "QI")
7786 (set_attr "pent_pair" "uv,np,uv")])
7788 (define_expand "testqi_ext_ccno_0"
7789 [(set (reg:CCNO FLAGS_REG)
7793 (match_operand 0 "ext_register_operand" "")
7796 (match_operand 1 "const_int_operand" ""))
7801 (define_insn "*testqi_ext_0"
7802 [(set (reg FLAGS_REG)
7806 (match_operand 0 "ext_register_operand" "Q")
7809 (match_operand 1 "const_int_operand" "n"))
7811 "ix86_match_ccmode (insn, CCNOmode)"
7812 "test{b}\t{%1, %h0|%h0, %1}"
7813 [(set_attr "type" "test")
7814 (set_attr "mode" "QI")
7815 (set_attr "length_immediate" "1")
7816 (set_attr "pent_pair" "np")])
7818 (define_insn "*testqi_ext_1"
7819 [(set (reg FLAGS_REG)
7823 (match_operand 0 "ext_register_operand" "Q")
7827 (match_operand:QI 1 "general_operand" "Qm")))
7829 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7831 "test{b}\t{%1, %h0|%h0, %1}"
7832 [(set_attr "type" "test")
7833 (set_attr "mode" "QI")])
7835 (define_insn "*testqi_ext_1_rex64"
7836 [(set (reg FLAGS_REG)
7840 (match_operand 0 "ext_register_operand" "Q")
7844 (match_operand:QI 1 "register_operand" "Q")))
7846 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7847 "test{b}\t{%1, %h0|%h0, %1}"
7848 [(set_attr "type" "test")
7849 (set_attr "mode" "QI")])
7851 (define_insn "*testqi_ext_2"
7852 [(set (reg FLAGS_REG)
7856 (match_operand 0 "ext_register_operand" "Q")
7860 (match_operand 1 "ext_register_operand" "Q")
7864 "ix86_match_ccmode (insn, CCNOmode)"
7865 "test{b}\t{%h1, %h0|%h0, %h1}"
7866 [(set_attr "type" "test")
7867 (set_attr "mode" "QI")])
7869 ;; Combine likes to form bit extractions for some tests. Humor it.
7870 (define_insn "*testqi_ext_3"
7871 [(set (reg FLAGS_REG)
7872 (compare (zero_extract:SI
7873 (match_operand 0 "nonimmediate_operand" "rm")
7874 (match_operand:SI 1 "const_int_operand" "")
7875 (match_operand:SI 2 "const_int_operand" ""))
7877 "ix86_match_ccmode (insn, CCNOmode)
7878 && (GET_MODE (operands[0]) == SImode
7879 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7880 || GET_MODE (operands[0]) == HImode
7881 || GET_MODE (operands[0]) == QImode)"
7884 (define_insn "*testqi_ext_3_rex64"
7885 [(set (reg FLAGS_REG)
7886 (compare (zero_extract:DI
7887 (match_operand 0 "nonimmediate_operand" "rm")
7888 (match_operand:DI 1 "const_int_operand" "")
7889 (match_operand:DI 2 "const_int_operand" ""))
7892 && ix86_match_ccmode (insn, CCNOmode)
7893 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7894 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7895 /* Ensure that resulting mask is zero or sign extended operand. */
7896 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7897 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7898 && INTVAL (operands[1]) > 32))
7899 && (GET_MODE (operands[0]) == SImode
7900 || GET_MODE (operands[0]) == DImode
7901 || GET_MODE (operands[0]) == HImode
7902 || GET_MODE (operands[0]) == QImode)"
7906 [(set (match_operand 0 "flags_reg_operand" "")
7907 (match_operator 1 "compare_operator"
7909 (match_operand 2 "nonimmediate_operand" "")
7910 (match_operand 3 "const_int_operand" "")
7911 (match_operand 4 "const_int_operand" ""))
7913 "ix86_match_ccmode (insn, CCNOmode)"
7914 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7916 rtx val = operands[2];
7917 HOST_WIDE_INT len = INTVAL (operands[3]);
7918 HOST_WIDE_INT pos = INTVAL (operands[4]);
7920 enum machine_mode mode, submode;
7922 mode = GET_MODE (val);
7923 if (GET_CODE (val) == MEM)
7925 /* ??? Combine likes to put non-volatile mem extractions in QImode
7926 no matter the size of the test. So find a mode that works. */
7927 if (! MEM_VOLATILE_P (val))
7929 mode = smallest_mode_for_size (pos + len, MODE_INT);
7930 val = adjust_address (val, mode, 0);
7933 else if (GET_CODE (val) == SUBREG
7934 && (submode = GET_MODE (SUBREG_REG (val)),
7935 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7936 && pos + len <= GET_MODE_BITSIZE (submode))
7938 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7940 val = SUBREG_REG (val);
7942 else if (mode == HImode && pos + len <= 8)
7944 /* Small HImode tests can be converted to QImode. */
7946 val = gen_lowpart (QImode, val);
7949 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7950 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7952 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7955 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7956 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7957 ;; this is relatively important trick.
7958 ;; Do the conversion only post-reload to avoid limiting of the register class
7961 [(set (match_operand 0 "flags_reg_operand" "")
7962 (match_operator 1 "compare_operator"
7963 [(and (match_operand 2 "register_operand" "")
7964 (match_operand 3 "const_int_operand" ""))
7967 && QI_REG_P (operands[2])
7968 && GET_MODE (operands[2]) != QImode
7969 && ((ix86_match_ccmode (insn, CCZmode)
7970 && !(INTVAL (operands[3]) & ~(255 << 8)))
7971 || (ix86_match_ccmode (insn, CCNOmode)
7972 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7975 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7978 "operands[2] = gen_lowpart (SImode, operands[2]);
7979 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7982 [(set (match_operand 0 "flags_reg_operand" "")
7983 (match_operator 1 "compare_operator"
7984 [(and (match_operand 2 "nonimmediate_operand" "")
7985 (match_operand 3 "const_int_operand" ""))
7988 && GET_MODE (operands[2]) != QImode
7989 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7990 && ((ix86_match_ccmode (insn, CCZmode)
7991 && !(INTVAL (operands[3]) & ~255))
7992 || (ix86_match_ccmode (insn, CCNOmode)
7993 && !(INTVAL (operands[3]) & ~127)))"
7995 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7997 "operands[2] = gen_lowpart (QImode, operands[2]);
7998 operands[3] = gen_lowpart (QImode, operands[3]);")
8001 ;; %%% This used to optimize known byte-wide and operations to memory,
8002 ;; and sometimes to QImode registers. If this is considered useful,
8003 ;; it should be done with splitters.
8005 (define_expand "anddi3"
8006 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8007 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8008 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8009 (clobber (reg:CC FLAGS_REG))]
8011 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8013 (define_insn "*anddi_1_rex64"
8014 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8015 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8016 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8017 (clobber (reg:CC FLAGS_REG))]
8018 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8020 switch (get_attr_type (insn))
8024 enum machine_mode mode;
8026 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8027 if (INTVAL (operands[2]) == 0xff)
8031 gcc_assert (INTVAL (operands[2]) == 0xffff);
8035 operands[1] = gen_lowpart (mode, operands[1]);
8037 return "movz{bq|x}\t{%1,%0|%0, %1}";
8039 return "movz{wq|x}\t{%1,%0|%0, %1}";
8043 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8044 if (get_attr_mode (insn) == MODE_SI)
8045 return "and{l}\t{%k2, %k0|%k0, %k2}";
8047 return "and{q}\t{%2, %0|%0, %2}";
8050 [(set_attr "type" "alu,alu,alu,imovx")
8051 (set_attr "length_immediate" "*,*,*,0")
8052 (set_attr "mode" "SI,DI,DI,DI")])
8054 (define_insn "*anddi_2"
8055 [(set (reg FLAGS_REG)
8056 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8057 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8059 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8060 (and:DI (match_dup 1) (match_dup 2)))]
8061 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8062 && ix86_binary_operator_ok (AND, DImode, operands)"
8064 and{l}\t{%k2, %k0|%k0, %k2}
8065 and{q}\t{%2, %0|%0, %2}
8066 and{q}\t{%2, %0|%0, %2}"
8067 [(set_attr "type" "alu")
8068 (set_attr "mode" "SI,DI,DI")])
8070 (define_expand "andsi3"
8071 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8072 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8073 (match_operand:SI 2 "general_operand" "")))
8074 (clobber (reg:CC FLAGS_REG))]
8076 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8078 (define_insn "*andsi_1"
8079 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8080 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8081 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8082 (clobber (reg:CC FLAGS_REG))]
8083 "ix86_binary_operator_ok (AND, SImode, operands)"
8085 switch (get_attr_type (insn))
8089 enum machine_mode mode;
8091 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8092 if (INTVAL (operands[2]) == 0xff)
8096 gcc_assert (INTVAL (operands[2]) == 0xffff);
8100 operands[1] = gen_lowpart (mode, operands[1]);
8102 return "movz{bl|x}\t{%1,%0|%0, %1}";
8104 return "movz{wl|x}\t{%1,%0|%0, %1}";
8108 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8109 return "and{l}\t{%2, %0|%0, %2}";
8112 [(set_attr "type" "alu,alu,imovx")
8113 (set_attr "length_immediate" "*,*,0")
8114 (set_attr "mode" "SI")])
8117 [(set (match_operand 0 "register_operand" "")
8119 (const_int -65536)))
8120 (clobber (reg:CC FLAGS_REG))]
8121 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8122 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8123 "operands[1] = gen_lowpart (HImode, operands[0]);")
8126 [(set (match_operand 0 "ext_register_operand" "")
8129 (clobber (reg:CC FLAGS_REG))]
8130 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8131 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8132 "operands[1] = gen_lowpart (QImode, operands[0]);")
8135 [(set (match_operand 0 "ext_register_operand" "")
8137 (const_int -65281)))
8138 (clobber (reg:CC FLAGS_REG))]
8139 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8140 [(parallel [(set (zero_extract:SI (match_dup 0)
8144 (zero_extract:SI (match_dup 0)
8147 (zero_extract:SI (match_dup 0)
8150 (clobber (reg:CC FLAGS_REG))])]
8151 "operands[0] = gen_lowpart (SImode, operands[0]);")
8153 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8154 (define_insn "*andsi_1_zext"
8155 [(set (match_operand:DI 0 "register_operand" "=r")
8157 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8158 (match_operand:SI 2 "general_operand" "rim"))))
8159 (clobber (reg:CC FLAGS_REG))]
8160 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8161 "and{l}\t{%2, %k0|%k0, %2}"
8162 [(set_attr "type" "alu")
8163 (set_attr "mode" "SI")])
8165 (define_insn "*andsi_2"
8166 [(set (reg FLAGS_REG)
8167 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8168 (match_operand:SI 2 "general_operand" "rim,ri"))
8170 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8171 (and:SI (match_dup 1) (match_dup 2)))]
8172 "ix86_match_ccmode (insn, CCNOmode)
8173 && ix86_binary_operator_ok (AND, SImode, operands)"
8174 "and{l}\t{%2, %0|%0, %2}"
8175 [(set_attr "type" "alu")
8176 (set_attr "mode" "SI")])
8178 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8179 (define_insn "*andsi_2_zext"
8180 [(set (reg FLAGS_REG)
8181 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8182 (match_operand:SI 2 "general_operand" "rim"))
8184 (set (match_operand:DI 0 "register_operand" "=r")
8185 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8186 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8187 && ix86_binary_operator_ok (AND, SImode, operands)"
8188 "and{l}\t{%2, %k0|%k0, %2}"
8189 [(set_attr "type" "alu")
8190 (set_attr "mode" "SI")])
8192 (define_expand "andhi3"
8193 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8194 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8195 (match_operand:HI 2 "general_operand" "")))
8196 (clobber (reg:CC FLAGS_REG))]
8197 "TARGET_HIMODE_MATH"
8198 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8200 (define_insn "*andhi_1"
8201 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8202 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8203 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8204 (clobber (reg:CC FLAGS_REG))]
8205 "ix86_binary_operator_ok (AND, HImode, operands)"
8207 switch (get_attr_type (insn))
8210 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8211 gcc_assert (INTVAL (operands[2]) == 0xff);
8212 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8215 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8217 return "and{w}\t{%2, %0|%0, %2}";
8220 [(set_attr "type" "alu,alu,imovx")
8221 (set_attr "length_immediate" "*,*,0")
8222 (set_attr "mode" "HI,HI,SI")])
8224 (define_insn "*andhi_2"
8225 [(set (reg FLAGS_REG)
8226 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8227 (match_operand:HI 2 "general_operand" "rim,ri"))
8229 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8230 (and:HI (match_dup 1) (match_dup 2)))]
8231 "ix86_match_ccmode (insn, CCNOmode)
8232 && ix86_binary_operator_ok (AND, HImode, operands)"
8233 "and{w}\t{%2, %0|%0, %2}"
8234 [(set_attr "type" "alu")
8235 (set_attr "mode" "HI")])
8237 (define_expand "andqi3"
8238 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8239 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8240 (match_operand:QI 2 "general_operand" "")))
8241 (clobber (reg:CC FLAGS_REG))]
8242 "TARGET_QIMODE_MATH"
8243 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8245 ;; %%% Potential partial reg stall on alternative 2. What to do?
8246 (define_insn "*andqi_1"
8247 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8248 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8249 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8250 (clobber (reg:CC FLAGS_REG))]
8251 "ix86_binary_operator_ok (AND, QImode, operands)"
8253 and{b}\t{%2, %0|%0, %2}
8254 and{b}\t{%2, %0|%0, %2}
8255 and{l}\t{%k2, %k0|%k0, %k2}"
8256 [(set_attr "type" "alu")
8257 (set_attr "mode" "QI,QI,SI")])
8259 (define_insn "*andqi_1_slp"
8260 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8261 (and:QI (match_dup 0)
8262 (match_operand:QI 1 "general_operand" "qi,qmi")))
8263 (clobber (reg:CC FLAGS_REG))]
8264 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8265 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8266 "and{b}\t{%1, %0|%0, %1}"
8267 [(set_attr "type" "alu1")
8268 (set_attr "mode" "QI")])
8270 (define_insn "*andqi_2_maybe_si"
8271 [(set (reg FLAGS_REG)
8273 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8274 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8276 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8277 (and:QI (match_dup 1) (match_dup 2)))]
8278 "ix86_binary_operator_ok (AND, QImode, operands)
8279 && ix86_match_ccmode (insn,
8280 GET_CODE (operands[2]) == CONST_INT
8281 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8283 if (which_alternative == 2)
8285 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8286 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8287 return "and{l}\t{%2, %k0|%k0, %2}";
8289 return "and{b}\t{%2, %0|%0, %2}";
8291 [(set_attr "type" "alu")
8292 (set_attr "mode" "QI,QI,SI")])
8294 (define_insn "*andqi_2"
8295 [(set (reg FLAGS_REG)
8297 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8298 (match_operand:QI 2 "general_operand" "qim,qi"))
8300 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8301 (and:QI (match_dup 1) (match_dup 2)))]
8302 "ix86_match_ccmode (insn, CCNOmode)
8303 && ix86_binary_operator_ok (AND, QImode, operands)"
8304 "and{b}\t{%2, %0|%0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "QI")])
8308 (define_insn "*andqi_2_slp"
8309 [(set (reg FLAGS_REG)
8311 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8312 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8314 (set (strict_low_part (match_dup 0))
8315 (and:QI (match_dup 0) (match_dup 1)))]
8316 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8317 && ix86_match_ccmode (insn, CCNOmode)
8318 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8319 "and{b}\t{%1, %0|%0, %1}"
8320 [(set_attr "type" "alu1")
8321 (set_attr "mode" "QI")])
8323 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8324 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8325 ;; for a QImode operand, which of course failed.
8327 (define_insn "andqi_ext_0"
8328 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8333 (match_operand 1 "ext_register_operand" "0")
8336 (match_operand 2 "const_int_operand" "n")))
8337 (clobber (reg:CC FLAGS_REG))]
8339 "and{b}\t{%2, %h0|%h0, %2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "length_immediate" "1")
8342 (set_attr "mode" "QI")])
8344 ;; Generated by peephole translating test to and. This shows up
8345 ;; often in fp comparisons.
8347 (define_insn "*andqi_ext_0_cc"
8348 [(set (reg FLAGS_REG)
8352 (match_operand 1 "ext_register_operand" "0")
8355 (match_operand 2 "const_int_operand" "n"))
8357 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366 "ix86_match_ccmode (insn, CCNOmode)"
8367 "and{b}\t{%2, %h0|%h0, %2}"
8368 [(set_attr "type" "alu")
8369 (set_attr "length_immediate" "1")
8370 (set_attr "mode" "QI")])
8372 (define_insn "*andqi_ext_1"
8373 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8378 (match_operand 1 "ext_register_operand" "0")
8382 (match_operand:QI 2 "general_operand" "Qm"))))
8383 (clobber (reg:CC FLAGS_REG))]
8385 "and{b}\t{%2, %h0|%h0, %2}"
8386 [(set_attr "type" "alu")
8387 (set_attr "length_immediate" "0")
8388 (set_attr "mode" "QI")])
8390 (define_insn "*andqi_ext_1_rex64"
8391 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8396 (match_operand 1 "ext_register_operand" "0")
8400 (match_operand 2 "ext_register_operand" "Q"))))
8401 (clobber (reg:CC FLAGS_REG))]
8403 "and{b}\t{%2, %h0|%h0, %2}"
8404 [(set_attr "type" "alu")
8405 (set_attr "length_immediate" "0")
8406 (set_attr "mode" "QI")])
8408 (define_insn "*andqi_ext_2"
8409 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8414 (match_operand 1 "ext_register_operand" "%0")
8418 (match_operand 2 "ext_register_operand" "Q")
8421 (clobber (reg:CC FLAGS_REG))]
8423 "and{b}\t{%h2, %h0|%h0, %h2}"
8424 [(set_attr "type" "alu")
8425 (set_attr "length_immediate" "0")
8426 (set_attr "mode" "QI")])
8428 ;; Convert wide AND instructions with immediate operand to shorter QImode
8429 ;; equivalents when possible.
8430 ;; Don't do the splitting with memory operands, since it introduces risk
8431 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8432 ;; for size, but that can (should?) be handled by generic code instead.
8434 [(set (match_operand 0 "register_operand" "")
8435 (and (match_operand 1 "register_operand" "")
8436 (match_operand 2 "const_int_operand" "")))
8437 (clobber (reg:CC FLAGS_REG))]
8439 && QI_REG_P (operands[0])
8440 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8441 && !(~INTVAL (operands[2]) & ~(255 << 8))
8442 && GET_MODE (operands[0]) != QImode"
8443 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8444 (and:SI (zero_extract:SI (match_dup 1)
8445 (const_int 8) (const_int 8))
8447 (clobber (reg:CC FLAGS_REG))])]
8448 "operands[0] = gen_lowpart (SImode, operands[0]);
8449 operands[1] = gen_lowpart (SImode, operands[1]);
8450 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8452 ;; Since AND can be encoded with sign extended immediate, this is only
8453 ;; profitable when 7th bit is not set.
8455 [(set (match_operand 0 "register_operand" "")
8456 (and (match_operand 1 "general_operand" "")
8457 (match_operand 2 "const_int_operand" "")))
8458 (clobber (reg:CC FLAGS_REG))]
8460 && ANY_QI_REG_P (operands[0])
8461 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8462 && !(~INTVAL (operands[2]) & ~255)
8463 && !(INTVAL (operands[2]) & 128)
8464 && GET_MODE (operands[0]) != QImode"
8465 [(parallel [(set (strict_low_part (match_dup 0))
8466 (and:QI (match_dup 1)
8468 (clobber (reg:CC FLAGS_REG))])]
8469 "operands[0] = gen_lowpart (QImode, operands[0]);
8470 operands[1] = gen_lowpart (QImode, operands[1]);
8471 operands[2] = gen_lowpart (QImode, operands[2]);")
8473 ;; Logical inclusive OR instructions
8475 ;; %%% This used to optimize known byte-wide and operations to memory.
8476 ;; If this is considered useful, it should be done with splitters.
8478 (define_expand "iordi3"
8479 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8480 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8481 (match_operand:DI 2 "x86_64_general_operand" "")))
8482 (clobber (reg:CC FLAGS_REG))]
8484 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8486 (define_insn "*iordi_1_rex64"
8487 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8488 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8489 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8490 (clobber (reg:CC FLAGS_REG))]
8492 && ix86_binary_operator_ok (IOR, DImode, operands)"
8493 "or{q}\t{%2, %0|%0, %2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "mode" "DI")])
8497 (define_insn "*iordi_2_rex64"
8498 [(set (reg FLAGS_REG)
8499 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8500 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8502 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8503 (ior:DI (match_dup 1) (match_dup 2)))]
8505 && ix86_match_ccmode (insn, CCNOmode)
8506 && ix86_binary_operator_ok (IOR, DImode, operands)"
8507 "or{q}\t{%2, %0|%0, %2}"
8508 [(set_attr "type" "alu")
8509 (set_attr "mode" "DI")])
8511 (define_insn "*iordi_3_rex64"
8512 [(set (reg FLAGS_REG)
8513 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8514 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8516 (clobber (match_scratch:DI 0 "=r"))]
8518 && ix86_match_ccmode (insn, CCNOmode)
8519 && ix86_binary_operator_ok (IOR, DImode, operands)"
8520 "or{q}\t{%2, %0|%0, %2}"
8521 [(set_attr "type" "alu")
8522 (set_attr "mode" "DI")])
8525 (define_expand "iorsi3"
8526 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8527 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8528 (match_operand:SI 2 "general_operand" "")))
8529 (clobber (reg:CC FLAGS_REG))]
8531 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8533 (define_insn "*iorsi_1"
8534 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8535 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8536 (match_operand:SI 2 "general_operand" "ri,rmi")))
8537 (clobber (reg:CC FLAGS_REG))]
8538 "ix86_binary_operator_ok (IOR, SImode, operands)"
8539 "or{l}\t{%2, %0|%0, %2}"
8540 [(set_attr "type" "alu")
8541 (set_attr "mode" "SI")])
8543 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8544 (define_insn "*iorsi_1_zext"
8545 [(set (match_operand:DI 0 "register_operand" "=rm")
8547 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8548 (match_operand:SI 2 "general_operand" "rim"))))
8549 (clobber (reg:CC FLAGS_REG))]
8550 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8551 "or{l}\t{%2, %k0|%k0, %2}"
8552 [(set_attr "type" "alu")
8553 (set_attr "mode" "SI")])
8555 (define_insn "*iorsi_1_zext_imm"
8556 [(set (match_operand:DI 0 "register_operand" "=rm")
8557 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8558 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8559 (clobber (reg:CC FLAGS_REG))]
8561 "or{l}\t{%2, %k0|%k0, %2}"
8562 [(set_attr "type" "alu")
8563 (set_attr "mode" "SI")])
8565 (define_insn "*iorsi_2"
8566 [(set (reg FLAGS_REG)
8567 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8568 (match_operand:SI 2 "general_operand" "rim,ri"))
8570 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8571 (ior:SI (match_dup 1) (match_dup 2)))]
8572 "ix86_match_ccmode (insn, CCNOmode)
8573 && ix86_binary_operator_ok (IOR, SImode, operands)"
8574 "or{l}\t{%2, %0|%0, %2}"
8575 [(set_attr "type" "alu")
8576 (set_attr "mode" "SI")])
8578 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8579 ;; ??? Special case for immediate operand is missing - it is tricky.
8580 (define_insn "*iorsi_2_zext"
8581 [(set (reg FLAGS_REG)
8582 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8583 (match_operand:SI 2 "general_operand" "rim"))
8585 (set (match_operand:DI 0 "register_operand" "=r")
8586 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8587 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8588 && ix86_binary_operator_ok (IOR, SImode, operands)"
8589 "or{l}\t{%2, %k0|%k0, %2}"
8590 [(set_attr "type" "alu")
8591 (set_attr "mode" "SI")])
8593 (define_insn "*iorsi_2_zext_imm"
8594 [(set (reg FLAGS_REG)
8595 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8596 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8598 (set (match_operand:DI 0 "register_operand" "=r")
8599 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8600 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8601 && ix86_binary_operator_ok (IOR, SImode, operands)"
8602 "or{l}\t{%2, %k0|%k0, %2}"
8603 [(set_attr "type" "alu")
8604 (set_attr "mode" "SI")])
8606 (define_insn "*iorsi_3"
8607 [(set (reg FLAGS_REG)
8608 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8609 (match_operand:SI 2 "general_operand" "rim"))
8611 (clobber (match_scratch:SI 0 "=r"))]
8612 "ix86_match_ccmode (insn, CCNOmode)
8613 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8614 "or{l}\t{%2, %0|%0, %2}"
8615 [(set_attr "type" "alu")
8616 (set_attr "mode" "SI")])
8618 (define_expand "iorhi3"
8619 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8620 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8621 (match_operand:HI 2 "general_operand" "")))
8622 (clobber (reg:CC FLAGS_REG))]
8623 "TARGET_HIMODE_MATH"
8624 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8626 (define_insn "*iorhi_1"
8627 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8628 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8629 (match_operand:HI 2 "general_operand" "rmi,ri")))
8630 (clobber (reg:CC FLAGS_REG))]
8631 "ix86_binary_operator_ok (IOR, HImode, operands)"
8632 "or{w}\t{%2, %0|%0, %2}"
8633 [(set_attr "type" "alu")
8634 (set_attr "mode" "HI")])
8636 (define_insn "*iorhi_2"
8637 [(set (reg FLAGS_REG)
8638 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8639 (match_operand:HI 2 "general_operand" "rim,ri"))
8641 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8642 (ior:HI (match_dup 1) (match_dup 2)))]
8643 "ix86_match_ccmode (insn, CCNOmode)
8644 && ix86_binary_operator_ok (IOR, HImode, operands)"
8645 "or{w}\t{%2, %0|%0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "mode" "HI")])
8649 (define_insn "*iorhi_3"
8650 [(set (reg FLAGS_REG)
8651 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8652 (match_operand:HI 2 "general_operand" "rim"))
8654 (clobber (match_scratch:HI 0 "=r"))]
8655 "ix86_match_ccmode (insn, CCNOmode)
8656 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8657 "or{w}\t{%2, %0|%0, %2}"
8658 [(set_attr "type" "alu")
8659 (set_attr "mode" "HI")])
8661 (define_expand "iorqi3"
8662 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8663 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8664 (match_operand:QI 2 "general_operand" "")))
8665 (clobber (reg:CC FLAGS_REG))]
8666 "TARGET_QIMODE_MATH"
8667 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8669 ;; %%% Potential partial reg stall on alternative 2. What to do?
8670 (define_insn "*iorqi_1"
8671 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8672 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8673 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8674 (clobber (reg:CC FLAGS_REG))]
8675 "ix86_binary_operator_ok (IOR, QImode, operands)"
8677 or{b}\t{%2, %0|%0, %2}
8678 or{b}\t{%2, %0|%0, %2}
8679 or{l}\t{%k2, %k0|%k0, %k2}"
8680 [(set_attr "type" "alu")
8681 (set_attr "mode" "QI,QI,SI")])
8683 (define_insn "*iorqi_1_slp"
8684 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8685 (ior:QI (match_dup 0)
8686 (match_operand:QI 1 "general_operand" "qmi,qi")))
8687 (clobber (reg:CC FLAGS_REG))]
8688 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8689 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8690 "or{b}\t{%1, %0|%0, %1}"
8691 [(set_attr "type" "alu1")
8692 (set_attr "mode" "QI")])
8694 (define_insn "*iorqi_2"
8695 [(set (reg FLAGS_REG)
8696 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8697 (match_operand:QI 2 "general_operand" "qim,qi"))
8699 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8700 (ior:QI (match_dup 1) (match_dup 2)))]
8701 "ix86_match_ccmode (insn, CCNOmode)
8702 && ix86_binary_operator_ok (IOR, QImode, operands)"
8703 "or{b}\t{%2, %0|%0, %2}"
8704 [(set_attr "type" "alu")
8705 (set_attr "mode" "QI")])
8707 (define_insn "*iorqi_2_slp"
8708 [(set (reg FLAGS_REG)
8709 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8710 (match_operand:QI 1 "general_operand" "qim,qi"))
8712 (set (strict_low_part (match_dup 0))
8713 (ior:QI (match_dup 0) (match_dup 1)))]
8714 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8715 && ix86_match_ccmode (insn, CCNOmode)
8716 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8717 "or{b}\t{%1, %0|%0, %1}"
8718 [(set_attr "type" "alu1")
8719 (set_attr "mode" "QI")])
8721 (define_insn "*iorqi_3"
8722 [(set (reg FLAGS_REG)
8723 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8724 (match_operand:QI 2 "general_operand" "qim"))
8726 (clobber (match_scratch:QI 0 "=q"))]
8727 "ix86_match_ccmode (insn, CCNOmode)
8728 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8729 "or{b}\t{%2, %0|%0, %2}"
8730 [(set_attr "type" "alu")
8731 (set_attr "mode" "QI")])
8733 (define_insn "iorqi_ext_0"
8734 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8739 (match_operand 1 "ext_register_operand" "0")
8742 (match_operand 2 "const_int_operand" "n")))
8743 (clobber (reg:CC FLAGS_REG))]
8744 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8745 "or{b}\t{%2, %h0|%h0, %2}"
8746 [(set_attr "type" "alu")
8747 (set_attr "length_immediate" "1")
8748 (set_attr "mode" "QI")])
8750 (define_insn "*iorqi_ext_1"
8751 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8756 (match_operand 1 "ext_register_operand" "0")
8760 (match_operand:QI 2 "general_operand" "Qm"))))
8761 (clobber (reg:CC FLAGS_REG))]
8763 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8764 "or{b}\t{%2, %h0|%h0, %2}"
8765 [(set_attr "type" "alu")
8766 (set_attr "length_immediate" "0")
8767 (set_attr "mode" "QI")])
8769 (define_insn "*iorqi_ext_1_rex64"
8770 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8775 (match_operand 1 "ext_register_operand" "0")
8779 (match_operand 2 "ext_register_operand" "Q"))))
8780 (clobber (reg:CC FLAGS_REG))]
8782 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8783 "or{b}\t{%2, %h0|%h0, %2}"
8784 [(set_attr "type" "alu")
8785 (set_attr "length_immediate" "0")
8786 (set_attr "mode" "QI")])
8788 (define_insn "*iorqi_ext_2"
8789 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8793 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8796 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8799 (clobber (reg:CC FLAGS_REG))]
8800 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8801 "ior{b}\t{%h2, %h0|%h0, %h2}"
8802 [(set_attr "type" "alu")
8803 (set_attr "length_immediate" "0")
8804 (set_attr "mode" "QI")])
8807 [(set (match_operand 0 "register_operand" "")
8808 (ior (match_operand 1 "register_operand" "")
8809 (match_operand 2 "const_int_operand" "")))
8810 (clobber (reg:CC FLAGS_REG))]
8812 && QI_REG_P (operands[0])
8813 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8814 && !(INTVAL (operands[2]) & ~(255 << 8))
8815 && GET_MODE (operands[0]) != QImode"
8816 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8817 (ior:SI (zero_extract:SI (match_dup 1)
8818 (const_int 8) (const_int 8))
8820 (clobber (reg:CC FLAGS_REG))])]
8821 "operands[0] = gen_lowpart (SImode, operands[0]);
8822 operands[1] = gen_lowpart (SImode, operands[1]);
8823 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8825 ;; Since OR can be encoded with sign extended immediate, this is only
8826 ;; profitable when 7th bit is set.
8828 [(set (match_operand 0 "register_operand" "")
8829 (ior (match_operand 1 "general_operand" "")
8830 (match_operand 2 "const_int_operand" "")))
8831 (clobber (reg:CC FLAGS_REG))]
8833 && ANY_QI_REG_P (operands[0])
8834 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8835 && !(INTVAL (operands[2]) & ~255)
8836 && (INTVAL (operands[2]) & 128)
8837 && GET_MODE (operands[0]) != QImode"
8838 [(parallel [(set (strict_low_part (match_dup 0))
8839 (ior:QI (match_dup 1)
8841 (clobber (reg:CC FLAGS_REG))])]
8842 "operands[0] = gen_lowpart (QImode, operands[0]);
8843 operands[1] = gen_lowpart (QImode, operands[1]);
8844 operands[2] = gen_lowpart (QImode, operands[2]);")
8846 ;; Logical XOR instructions
8848 ;; %%% This used to optimize known byte-wide and operations to memory.
8849 ;; If this is considered useful, it should be done with splitters.
8851 (define_expand "xordi3"
8852 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8853 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8854 (match_operand:DI 2 "x86_64_general_operand" "")))
8855 (clobber (reg:CC FLAGS_REG))]
8857 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8859 (define_insn "*xordi_1_rex64"
8860 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8861 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8862 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8863 (clobber (reg:CC FLAGS_REG))]
8865 && ix86_binary_operator_ok (XOR, DImode, operands)"
8867 xor{q}\t{%2, %0|%0, %2}
8868 xor{q}\t{%2, %0|%0, %2}"
8869 [(set_attr "type" "alu")
8870 (set_attr "mode" "DI,DI")])
8872 (define_insn "*xordi_2_rex64"
8873 [(set (reg FLAGS_REG)
8874 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8875 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8877 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8878 (xor:DI (match_dup 1) (match_dup 2)))]
8880 && ix86_match_ccmode (insn, CCNOmode)
8881 && ix86_binary_operator_ok (XOR, DImode, operands)"
8883 xor{q}\t{%2, %0|%0, %2}
8884 xor{q}\t{%2, %0|%0, %2}"
8885 [(set_attr "type" "alu")
8886 (set_attr "mode" "DI,DI")])
8888 (define_insn "*xordi_3_rex64"
8889 [(set (reg FLAGS_REG)
8890 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8891 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8893 (clobber (match_scratch:DI 0 "=r"))]
8895 && ix86_match_ccmode (insn, CCNOmode)
8896 && ix86_binary_operator_ok (XOR, DImode, operands)"
8897 "xor{q}\t{%2, %0|%0, %2}"
8898 [(set_attr "type" "alu")
8899 (set_attr "mode" "DI")])
8901 (define_expand "xorsi3"
8902 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8903 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8904 (match_operand:SI 2 "general_operand" "")))
8905 (clobber (reg:CC FLAGS_REG))]
8907 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8909 (define_insn "*xorsi_1"
8910 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8911 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8912 (match_operand:SI 2 "general_operand" "ri,rm")))
8913 (clobber (reg:CC FLAGS_REG))]
8914 "ix86_binary_operator_ok (XOR, SImode, operands)"
8915 "xor{l}\t{%2, %0|%0, %2}"
8916 [(set_attr "type" "alu")
8917 (set_attr "mode" "SI")])
8919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8920 ;; Add speccase for immediates
8921 (define_insn "*xorsi_1_zext"
8922 [(set (match_operand:DI 0 "register_operand" "=r")
8924 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8925 (match_operand:SI 2 "general_operand" "rim"))))
8926 (clobber (reg:CC FLAGS_REG))]
8927 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8928 "xor{l}\t{%2, %k0|%k0, %2}"
8929 [(set_attr "type" "alu")
8930 (set_attr "mode" "SI")])
8932 (define_insn "*xorsi_1_zext_imm"
8933 [(set (match_operand:DI 0 "register_operand" "=r")
8934 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8935 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8936 (clobber (reg:CC FLAGS_REG))]
8937 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8938 "xor{l}\t{%2, %k0|%k0, %2}"
8939 [(set_attr "type" "alu")
8940 (set_attr "mode" "SI")])
8942 (define_insn "*xorsi_2"
8943 [(set (reg FLAGS_REG)
8944 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8945 (match_operand:SI 2 "general_operand" "rim,ri"))
8947 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8948 (xor:SI (match_dup 1) (match_dup 2)))]
8949 "ix86_match_ccmode (insn, CCNOmode)
8950 && ix86_binary_operator_ok (XOR, SImode, operands)"
8951 "xor{l}\t{%2, %0|%0, %2}"
8952 [(set_attr "type" "alu")
8953 (set_attr "mode" "SI")])
8955 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8956 ;; ??? Special case for immediate operand is missing - it is tricky.
8957 (define_insn "*xorsi_2_zext"
8958 [(set (reg FLAGS_REG)
8959 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8960 (match_operand:SI 2 "general_operand" "rim"))
8962 (set (match_operand:DI 0 "register_operand" "=r")
8963 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8964 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8965 && ix86_binary_operator_ok (XOR, SImode, operands)"
8966 "xor{l}\t{%2, %k0|%k0, %2}"
8967 [(set_attr "type" "alu")
8968 (set_attr "mode" "SI")])
8970 (define_insn "*xorsi_2_zext_imm"
8971 [(set (reg FLAGS_REG)
8972 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8973 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8975 (set (match_operand:DI 0 "register_operand" "=r")
8976 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8977 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8978 && ix86_binary_operator_ok (XOR, SImode, operands)"
8979 "xor{l}\t{%2, %k0|%k0, %2}"
8980 [(set_attr "type" "alu")
8981 (set_attr "mode" "SI")])
8983 (define_insn "*xorsi_3"
8984 [(set (reg FLAGS_REG)
8985 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8986 (match_operand:SI 2 "general_operand" "rim"))
8988 (clobber (match_scratch:SI 0 "=r"))]
8989 "ix86_match_ccmode (insn, CCNOmode)
8990 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8991 "xor{l}\t{%2, %0|%0, %2}"
8992 [(set_attr "type" "alu")
8993 (set_attr "mode" "SI")])
8995 (define_expand "xorhi3"
8996 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8997 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8998 (match_operand:HI 2 "general_operand" "")))
8999 (clobber (reg:CC FLAGS_REG))]
9000 "TARGET_HIMODE_MATH"
9001 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9003 (define_insn "*xorhi_1"
9004 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9005 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9006 (match_operand:HI 2 "general_operand" "rmi,ri")))
9007 (clobber (reg:CC FLAGS_REG))]
9008 "ix86_binary_operator_ok (XOR, HImode, operands)"
9009 "xor{w}\t{%2, %0|%0, %2}"
9010 [(set_attr "type" "alu")
9011 (set_attr "mode" "HI")])
9013 (define_insn "*xorhi_2"
9014 [(set (reg FLAGS_REG)
9015 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9016 (match_operand:HI 2 "general_operand" "rim,ri"))
9018 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9019 (xor:HI (match_dup 1) (match_dup 2)))]
9020 "ix86_match_ccmode (insn, CCNOmode)
9021 && ix86_binary_operator_ok (XOR, HImode, operands)"
9022 "xor{w}\t{%2, %0|%0, %2}"
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "HI")])
9026 (define_insn "*xorhi_3"
9027 [(set (reg FLAGS_REG)
9028 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9029 (match_operand:HI 2 "general_operand" "rim"))
9031 (clobber (match_scratch:HI 0 "=r"))]
9032 "ix86_match_ccmode (insn, CCNOmode)
9033 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9034 "xor{w}\t{%2, %0|%0, %2}"
9035 [(set_attr "type" "alu")
9036 (set_attr "mode" "HI")])
9038 (define_expand "xorqi3"
9039 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9040 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9041 (match_operand:QI 2 "general_operand" "")))
9042 (clobber (reg:CC FLAGS_REG))]
9043 "TARGET_QIMODE_MATH"
9044 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9046 ;; %%% Potential partial reg stall on alternative 2. What to do?
9047 (define_insn "*xorqi_1"
9048 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9049 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9050 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9051 (clobber (reg:CC FLAGS_REG))]
9052 "ix86_binary_operator_ok (XOR, QImode, operands)"
9054 xor{b}\t{%2, %0|%0, %2}
9055 xor{b}\t{%2, %0|%0, %2}
9056 xor{l}\t{%k2, %k0|%k0, %k2}"
9057 [(set_attr "type" "alu")
9058 (set_attr "mode" "QI,QI,SI")])
9060 (define_insn "*xorqi_1_slp"
9061 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9062 (xor:QI (match_dup 0)
9063 (match_operand:QI 1 "general_operand" "qi,qmi")))
9064 (clobber (reg:CC FLAGS_REG))]
9065 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9066 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9067 "xor{b}\t{%1, %0|%0, %1}"
9068 [(set_attr "type" "alu1")
9069 (set_attr "mode" "QI")])
9071 (define_insn "xorqi_ext_0"
9072 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9077 (match_operand 1 "ext_register_operand" "0")
9080 (match_operand 2 "const_int_operand" "n")))
9081 (clobber (reg:CC FLAGS_REG))]
9082 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9083 "xor{b}\t{%2, %h0|%h0, %2}"
9084 [(set_attr "type" "alu")
9085 (set_attr "length_immediate" "1")
9086 (set_attr "mode" "QI")])
9088 (define_insn "*xorqi_ext_1"
9089 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9094 (match_operand 1 "ext_register_operand" "0")
9098 (match_operand:QI 2 "general_operand" "Qm"))))
9099 (clobber (reg:CC FLAGS_REG))]
9101 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9102 "xor{b}\t{%2, %h0|%h0, %2}"
9103 [(set_attr "type" "alu")
9104 (set_attr "length_immediate" "0")
9105 (set_attr "mode" "QI")])
9107 (define_insn "*xorqi_ext_1_rex64"
9108 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9113 (match_operand 1 "ext_register_operand" "0")
9117 (match_operand 2 "ext_register_operand" "Q"))))
9118 (clobber (reg:CC FLAGS_REG))]
9120 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9121 "xor{b}\t{%2, %h0|%h0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "length_immediate" "0")
9124 (set_attr "mode" "QI")])
9126 (define_insn "*xorqi_ext_2"
9127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9131 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9134 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9137 (clobber (reg:CC FLAGS_REG))]
9138 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9139 "xor{b}\t{%h2, %h0|%h0, %h2}"
9140 [(set_attr "type" "alu")
9141 (set_attr "length_immediate" "0")
9142 (set_attr "mode" "QI")])
9144 (define_insn "*xorqi_cc_1"
9145 [(set (reg FLAGS_REG)
9147 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9148 (match_operand:QI 2 "general_operand" "qim,qi"))
9150 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9151 (xor:QI (match_dup 1) (match_dup 2)))]
9152 "ix86_match_ccmode (insn, CCNOmode)
9153 && ix86_binary_operator_ok (XOR, QImode, operands)"
9154 "xor{b}\t{%2, %0|%0, %2}"
9155 [(set_attr "type" "alu")
9156 (set_attr "mode" "QI")])
9158 (define_insn "*xorqi_2_slp"
9159 [(set (reg FLAGS_REG)
9160 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9161 (match_operand:QI 1 "general_operand" "qim,qi"))
9163 (set (strict_low_part (match_dup 0))
9164 (xor:QI (match_dup 0) (match_dup 1)))]
9165 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9166 && ix86_match_ccmode (insn, CCNOmode)
9167 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9168 "xor{b}\t{%1, %0|%0, %1}"
9169 [(set_attr "type" "alu1")
9170 (set_attr "mode" "QI")])
9172 (define_insn "*xorqi_cc_2"
9173 [(set (reg FLAGS_REG)
9175 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9176 (match_operand:QI 2 "general_operand" "qim"))
9178 (clobber (match_scratch:QI 0 "=q"))]
9179 "ix86_match_ccmode (insn, CCNOmode)
9180 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9181 "xor{b}\t{%2, %0|%0, %2}"
9182 [(set_attr "type" "alu")
9183 (set_attr "mode" "QI")])
9185 (define_insn "*xorqi_cc_ext_1"
9186 [(set (reg FLAGS_REG)
9190 (match_operand 1 "ext_register_operand" "0")
9193 (match_operand:QI 2 "general_operand" "qmn"))
9195 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9199 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9201 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9202 "xor{b}\t{%2, %h0|%h0, %2}"
9203 [(set_attr "type" "alu")
9204 (set_attr "mode" "QI")])
9206 (define_insn "*xorqi_cc_ext_1_rex64"
9207 [(set (reg FLAGS_REG)
9211 (match_operand 1 "ext_register_operand" "0")
9214 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9216 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9220 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9222 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9223 "xor{b}\t{%2, %h0|%h0, %2}"
9224 [(set_attr "type" "alu")
9225 (set_attr "mode" "QI")])
9227 (define_expand "xorqi_cc_ext_1"
9229 (set (reg:CCNO FLAGS_REG)
9233 (match_operand 1 "ext_register_operand" "")
9236 (match_operand:QI 2 "general_operand" ""))
9238 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9242 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9248 [(set (match_operand 0 "register_operand" "")
9249 (xor (match_operand 1 "register_operand" "")
9250 (match_operand 2 "const_int_operand" "")))
9251 (clobber (reg:CC FLAGS_REG))]
9253 && QI_REG_P (operands[0])
9254 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9255 && !(INTVAL (operands[2]) & ~(255 << 8))
9256 && GET_MODE (operands[0]) != QImode"
9257 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9258 (xor:SI (zero_extract:SI (match_dup 1)
9259 (const_int 8) (const_int 8))
9261 (clobber (reg:CC FLAGS_REG))])]
9262 "operands[0] = gen_lowpart (SImode, operands[0]);
9263 operands[1] = gen_lowpart (SImode, operands[1]);
9264 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9266 ;; Since XOR can be encoded with sign extended immediate, this is only
9267 ;; profitable when 7th bit is set.
9269 [(set (match_operand 0 "register_operand" "")
9270 (xor (match_operand 1 "general_operand" "")
9271 (match_operand 2 "const_int_operand" "")))
9272 (clobber (reg:CC FLAGS_REG))]
9274 && ANY_QI_REG_P (operands[0])
9275 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9276 && !(INTVAL (operands[2]) & ~255)
9277 && (INTVAL (operands[2]) & 128)
9278 && GET_MODE (operands[0]) != QImode"
9279 [(parallel [(set (strict_low_part (match_dup 0))
9280 (xor:QI (match_dup 1)
9282 (clobber (reg:CC FLAGS_REG))])]
9283 "operands[0] = gen_lowpart (QImode, operands[0]);
9284 operands[1] = gen_lowpart (QImode, operands[1]);
9285 operands[2] = gen_lowpart (QImode, operands[2]);")
9287 ;; Negation instructions
9289 (define_expand "negti2"
9290 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9291 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9292 (clobber (reg:CC FLAGS_REG))])]
9294 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9296 (define_insn "*negti2_1"
9297 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9298 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9299 (clobber (reg:CC FLAGS_REG))]
9301 && ix86_unary_operator_ok (NEG, TImode, operands)"
9305 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9306 (neg:TI (match_operand:TI 1 "general_operand" "")))
9307 (clobber (reg:CC FLAGS_REG))]
9308 "TARGET_64BIT && reload_completed"
9310 [(set (reg:CCZ FLAGS_REG)
9311 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9312 (set (match_dup 0) (neg:DI (match_dup 2)))])
9315 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9318 (clobber (reg:CC FLAGS_REG))])
9321 (neg:DI (match_dup 1)))
9322 (clobber (reg:CC FLAGS_REG))])]
9323 "split_ti (operands+1, 1, operands+2, operands+3);
9324 split_ti (operands+0, 1, operands+0, operands+1);")
9326 (define_expand "negdi2"
9327 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9328 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9329 (clobber (reg:CC FLAGS_REG))])]
9331 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9333 (define_insn "*negdi2_1"
9334 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9335 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9336 (clobber (reg:CC FLAGS_REG))]
9338 && ix86_unary_operator_ok (NEG, DImode, operands)"
9342 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9343 (neg:DI (match_operand:DI 1 "general_operand" "")))
9344 (clobber (reg:CC FLAGS_REG))]
9345 "!TARGET_64BIT && reload_completed"
9347 [(set (reg:CCZ FLAGS_REG)
9348 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9349 (set (match_dup 0) (neg:SI (match_dup 2)))])
9352 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9355 (clobber (reg:CC FLAGS_REG))])
9358 (neg:SI (match_dup 1)))
9359 (clobber (reg:CC FLAGS_REG))])]
9360 "split_di (operands+1, 1, operands+2, operands+3);
9361 split_di (operands+0, 1, operands+0, operands+1);")
9363 (define_insn "*negdi2_1_rex64"
9364 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9365 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9366 (clobber (reg:CC FLAGS_REG))]
9367 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9369 [(set_attr "type" "negnot")
9370 (set_attr "mode" "DI")])
9372 ;; The problem with neg is that it does not perform (compare x 0),
9373 ;; it really performs (compare 0 x), which leaves us with the zero
9374 ;; flag being the only useful item.
9376 (define_insn "*negdi2_cmpz_rex64"
9377 [(set (reg:CCZ FLAGS_REG)
9378 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9380 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9381 (neg:DI (match_dup 1)))]
9382 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9384 [(set_attr "type" "negnot")
9385 (set_attr "mode" "DI")])
9388 (define_expand "negsi2"
9389 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9390 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9391 (clobber (reg:CC FLAGS_REG))])]
9393 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9395 (define_insn "*negsi2_1"
9396 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9397 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9398 (clobber (reg:CC FLAGS_REG))]
9399 "ix86_unary_operator_ok (NEG, SImode, operands)"
9401 [(set_attr "type" "negnot")
9402 (set_attr "mode" "SI")])
9404 ;; Combine is quite creative about this pattern.
9405 (define_insn "*negsi2_1_zext"
9406 [(set (match_operand:DI 0 "register_operand" "=r")
9407 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9410 (clobber (reg:CC FLAGS_REG))]
9411 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9413 [(set_attr "type" "negnot")
9414 (set_attr "mode" "SI")])
9416 ;; The problem with neg is that it does not perform (compare x 0),
9417 ;; it really performs (compare 0 x), which leaves us with the zero
9418 ;; flag being the only useful item.
9420 (define_insn "*negsi2_cmpz"
9421 [(set (reg:CCZ FLAGS_REG)
9422 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9424 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9425 (neg:SI (match_dup 1)))]
9426 "ix86_unary_operator_ok (NEG, SImode, operands)"
9428 [(set_attr "type" "negnot")
9429 (set_attr "mode" "SI")])
9431 (define_insn "*negsi2_cmpz_zext"
9432 [(set (reg:CCZ FLAGS_REG)
9433 (compare:CCZ (lshiftrt:DI
9435 (match_operand:DI 1 "register_operand" "0")
9439 (set (match_operand:DI 0 "register_operand" "=r")
9440 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9443 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9445 [(set_attr "type" "negnot")
9446 (set_attr "mode" "SI")])
9448 (define_expand "neghi2"
9449 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9450 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9451 (clobber (reg:CC FLAGS_REG))])]
9452 "TARGET_HIMODE_MATH"
9453 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9455 (define_insn "*neghi2_1"
9456 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9457 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9458 (clobber (reg:CC FLAGS_REG))]
9459 "ix86_unary_operator_ok (NEG, HImode, operands)"
9461 [(set_attr "type" "negnot")
9462 (set_attr "mode" "HI")])
9464 (define_insn "*neghi2_cmpz"
9465 [(set (reg:CCZ FLAGS_REG)
9466 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9468 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9469 (neg:HI (match_dup 1)))]
9470 "ix86_unary_operator_ok (NEG, HImode, operands)"
9472 [(set_attr "type" "negnot")
9473 (set_attr "mode" "HI")])
9475 (define_expand "negqi2"
9476 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9477 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9478 (clobber (reg:CC FLAGS_REG))])]
9479 "TARGET_QIMODE_MATH"
9480 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9482 (define_insn "*negqi2_1"
9483 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9484 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9485 (clobber (reg:CC FLAGS_REG))]
9486 "ix86_unary_operator_ok (NEG, QImode, operands)"
9488 [(set_attr "type" "negnot")
9489 (set_attr "mode" "QI")])
9491 (define_insn "*negqi2_cmpz"
9492 [(set (reg:CCZ FLAGS_REG)
9493 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9495 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9496 (neg:QI (match_dup 1)))]
9497 "ix86_unary_operator_ok (NEG, QImode, operands)"
9499 [(set_attr "type" "negnot")
9500 (set_attr "mode" "QI")])
9502 ;; Changing of sign for FP values is doable using integer unit too.
9504 (define_expand "negsf2"
9505 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9506 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9507 "TARGET_80387 || TARGET_SSE_MATH"
9508 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9510 (define_expand "abssf2"
9511 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9512 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9513 "TARGET_80387 || TARGET_SSE_MATH"
9514 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9516 (define_insn "*absnegsf2_mixed"
9517 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9518 (match_operator:SF 3 "absneg_operator"
9519 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9520 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9521 (clobber (reg:CC FLAGS_REG))]
9522 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9523 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9526 (define_insn "*absnegsf2_sse"
9527 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9528 (match_operator:SF 3 "absneg_operator"
9529 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9530 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9531 (clobber (reg:CC FLAGS_REG))]
9533 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9536 (define_insn "*absnegsf2_i387"
9537 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9538 (match_operator:SF 3 "absneg_operator"
9539 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9540 (use (match_operand 2 "" ""))
9541 (clobber (reg:CC FLAGS_REG))]
9542 "TARGET_80387 && !TARGET_SSE_MATH
9543 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9546 (define_expand "copysignsf3"
9547 [(match_operand:SF 0 "register_operand" "")
9548 (match_operand:SF 1 "nonmemory_operand" "")
9549 (match_operand:SF 2 "register_operand" "")]
9552 ix86_expand_copysign (operands);
9556 (define_insn_and_split "copysignsf3_const"
9557 [(set (match_operand:SF 0 "register_operand" "=x")
9559 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9560 (match_operand:SF 2 "register_operand" "0")
9561 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9565 "&& reload_completed"
9568 ix86_split_copysign_const (operands);
9572 (define_insn "copysignsf3_var"
9573 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9575 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9576 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9577 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9578 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9580 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9585 [(set (match_operand:SF 0 "register_operand" "")
9587 [(match_operand:SF 2 "register_operand" "")
9588 (match_operand:SF 3 "register_operand" "")
9589 (match_operand:V4SF 4 "" "")
9590 (match_operand:V4SF 5 "" "")]
9592 (clobber (match_scratch:V4SF 1 ""))]
9593 "TARGET_SSE_MATH && reload_completed"
9596 ix86_split_copysign_var (operands);
9600 (define_expand "negdf2"
9601 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9602 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9603 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9604 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9606 (define_expand "absdf2"
9607 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9608 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9609 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9610 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9612 (define_insn "*absnegdf2_mixed"
9613 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9614 (match_operator:DF 3 "absneg_operator"
9615 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9616 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9617 (clobber (reg:CC FLAGS_REG))]
9618 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9619 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9622 (define_insn "*absnegdf2_sse"
9623 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9624 (match_operator:DF 3 "absneg_operator"
9625 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9626 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9627 (clobber (reg:CC FLAGS_REG))]
9628 "TARGET_SSE2 && TARGET_SSE_MATH
9629 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9632 (define_insn "*absnegdf2_i387"
9633 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9634 (match_operator:DF 3 "absneg_operator"
9635 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9636 (use (match_operand 2 "" ""))
9637 (clobber (reg:CC FLAGS_REG))]
9638 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9639 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9642 (define_expand "copysigndf3"
9643 [(match_operand:DF 0 "register_operand" "")
9644 (match_operand:DF 1 "nonmemory_operand" "")
9645 (match_operand:DF 2 "register_operand" "")]
9646 "TARGET_SSE2 && TARGET_SSE_MATH"
9648 ix86_expand_copysign (operands);
9652 (define_insn_and_split "copysigndf3_const"
9653 [(set (match_operand:DF 0 "register_operand" "=x")
9655 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9656 (match_operand:DF 2 "register_operand" "0")
9657 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9659 "TARGET_SSE2 && TARGET_SSE_MATH"
9661 "&& reload_completed"
9664 ix86_split_copysign_const (operands);
9668 (define_insn "copysigndf3_var"
9669 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9671 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9672 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9673 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9674 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9676 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9677 "TARGET_SSE2 && TARGET_SSE_MATH"
9681 [(set (match_operand:DF 0 "register_operand" "")
9683 [(match_operand:DF 2 "register_operand" "")
9684 (match_operand:DF 3 "register_operand" "")
9685 (match_operand:V2DF 4 "" "")
9686 (match_operand:V2DF 5 "" "")]
9688 (clobber (match_scratch:V2DF 1 ""))]
9689 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9692 ix86_split_copysign_var (operands);
9696 (define_expand "negxf2"
9697 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9698 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9700 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9702 (define_expand "absxf2"
9703 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9704 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9706 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9708 (define_insn "*absnegxf2_i387"
9709 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9710 (match_operator:XF 3 "absneg_operator"
9711 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9712 (use (match_operand 2 "" ""))
9713 (clobber (reg:CC FLAGS_REG))]
9715 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9718 ;; Splitters for fp abs and neg.
9721 [(set (match_operand 0 "fp_register_operand" "")
9722 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9723 (use (match_operand 2 "" ""))
9724 (clobber (reg:CC FLAGS_REG))]
9726 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9729 [(set (match_operand 0 "register_operand" "")
9730 (match_operator 3 "absneg_operator"
9731 [(match_operand 1 "register_operand" "")]))
9732 (use (match_operand 2 "nonimmediate_operand" ""))
9733 (clobber (reg:CC FLAGS_REG))]
9734 "reload_completed && SSE_REG_P (operands[0])"
9735 [(set (match_dup 0) (match_dup 3))]
9737 enum machine_mode mode = GET_MODE (operands[0]);
9738 enum machine_mode vmode = GET_MODE (operands[2]);
9741 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9742 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9743 if (operands_match_p (operands[0], operands[2]))
9746 operands[1] = operands[2];
9749 if (GET_CODE (operands[3]) == ABS)
9750 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9752 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9757 [(set (match_operand:SF 0 "register_operand" "")
9758 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9759 (use (match_operand:V4SF 2 "" ""))
9760 (clobber (reg:CC FLAGS_REG))]
9762 [(parallel [(set (match_dup 0) (match_dup 1))
9763 (clobber (reg:CC FLAGS_REG))])]
9766 operands[0] = gen_lowpart (SImode, operands[0]);
9767 if (GET_CODE (operands[1]) == ABS)
9769 tmp = gen_int_mode (0x7fffffff, SImode);
9770 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9774 tmp = gen_int_mode (0x80000000, SImode);
9775 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9781 [(set (match_operand:DF 0 "register_operand" "")
9782 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9783 (use (match_operand 2 "" ""))
9784 (clobber (reg:CC FLAGS_REG))]
9786 [(parallel [(set (match_dup 0) (match_dup 1))
9787 (clobber (reg:CC FLAGS_REG))])]
9792 tmp = gen_lowpart (DImode, operands[0]);
9793 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9796 if (GET_CODE (operands[1]) == ABS)
9799 tmp = gen_rtx_NOT (DImode, tmp);
9803 operands[0] = gen_highpart (SImode, operands[0]);
9804 if (GET_CODE (operands[1]) == ABS)
9806 tmp = gen_int_mode (0x7fffffff, SImode);
9807 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9811 tmp = gen_int_mode (0x80000000, SImode);
9812 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9819 [(set (match_operand:XF 0 "register_operand" "")
9820 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9821 (use (match_operand 2 "" ""))
9822 (clobber (reg:CC FLAGS_REG))]
9824 [(parallel [(set (match_dup 0) (match_dup 1))
9825 (clobber (reg:CC FLAGS_REG))])]
9828 operands[0] = gen_rtx_REG (SImode,
9829 true_regnum (operands[0])
9830 + (TARGET_64BIT ? 1 : 2));
9831 if (GET_CODE (operands[1]) == ABS)
9833 tmp = GEN_INT (0x7fff);
9834 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9838 tmp = GEN_INT (0x8000);
9839 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9845 [(set (match_operand 0 "memory_operand" "")
9846 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9847 (use (match_operand 2 "" ""))
9848 (clobber (reg:CC FLAGS_REG))]
9850 [(parallel [(set (match_dup 0) (match_dup 1))
9851 (clobber (reg:CC FLAGS_REG))])]
9853 enum machine_mode mode = GET_MODE (operands[0]);
9854 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9857 operands[0] = adjust_address (operands[0], QImode, size - 1);
9858 if (GET_CODE (operands[1]) == ABS)
9860 tmp = gen_int_mode (0x7f, QImode);
9861 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9865 tmp = gen_int_mode (0x80, QImode);
9866 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9871 ;; Conditionalize these after reload. If they match before reload, we
9872 ;; lose the clobber and ability to use integer instructions.
9874 (define_insn "*negsf2_1"
9875 [(set (match_operand:SF 0 "register_operand" "=f")
9876 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9877 "TARGET_80387 && reload_completed"
9879 [(set_attr "type" "fsgn")
9880 (set_attr "mode" "SF")])
9882 (define_insn "*negdf2_1"
9883 [(set (match_operand:DF 0 "register_operand" "=f")
9884 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9885 "TARGET_80387 && reload_completed"
9887 [(set_attr "type" "fsgn")
9888 (set_attr "mode" "DF")])
9890 (define_insn "*negxf2_1"
9891 [(set (match_operand:XF 0 "register_operand" "=f")
9892 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9893 "TARGET_80387 && reload_completed"
9895 [(set_attr "type" "fsgn")
9896 (set_attr "mode" "XF")])
9898 (define_insn "*abssf2_1"
9899 [(set (match_operand:SF 0 "register_operand" "=f")
9900 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9901 "TARGET_80387 && reload_completed"
9903 [(set_attr "type" "fsgn")
9904 (set_attr "mode" "SF")])
9906 (define_insn "*absdf2_1"
9907 [(set (match_operand:DF 0 "register_operand" "=f")
9908 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9909 "TARGET_80387 && reload_completed"
9911 [(set_attr "type" "fsgn")
9912 (set_attr "mode" "DF")])
9914 (define_insn "*absxf2_1"
9915 [(set (match_operand:XF 0 "register_operand" "=f")
9916 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9917 "TARGET_80387 && reload_completed"
9919 [(set_attr "type" "fsgn")
9920 (set_attr "mode" "DF")])
9922 (define_insn "*negextendsfdf2"
9923 [(set (match_operand:DF 0 "register_operand" "=f")
9924 (neg:DF (float_extend:DF
9925 (match_operand:SF 1 "register_operand" "0"))))]
9926 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9928 [(set_attr "type" "fsgn")
9929 (set_attr "mode" "DF")])
9931 (define_insn "*negextenddfxf2"
9932 [(set (match_operand:XF 0 "register_operand" "=f")
9933 (neg:XF (float_extend:XF
9934 (match_operand:DF 1 "register_operand" "0"))))]
9937 [(set_attr "type" "fsgn")
9938 (set_attr "mode" "XF")])
9940 (define_insn "*negextendsfxf2"
9941 [(set (match_operand:XF 0 "register_operand" "=f")
9942 (neg:XF (float_extend:XF
9943 (match_operand:SF 1 "register_operand" "0"))))]
9946 [(set_attr "type" "fsgn")
9947 (set_attr "mode" "XF")])
9949 (define_insn "*absextendsfdf2"
9950 [(set (match_operand:DF 0 "register_operand" "=f")
9951 (abs:DF (float_extend:DF
9952 (match_operand:SF 1 "register_operand" "0"))))]
9953 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9955 [(set_attr "type" "fsgn")
9956 (set_attr "mode" "DF")])
9958 (define_insn "*absextenddfxf2"
9959 [(set (match_operand:XF 0 "register_operand" "=f")
9960 (abs:XF (float_extend:XF
9961 (match_operand:DF 1 "register_operand" "0"))))]
9964 [(set_attr "type" "fsgn")
9965 (set_attr "mode" "XF")])
9967 (define_insn "*absextendsfxf2"
9968 [(set (match_operand:XF 0 "register_operand" "=f")
9969 (abs:XF (float_extend:XF
9970 (match_operand:SF 1 "register_operand" "0"))))]
9973 [(set_attr "type" "fsgn")
9974 (set_attr "mode" "XF")])
9976 ;; One complement instructions
9978 (define_expand "one_cmpldi2"
9979 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9980 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9982 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9984 (define_insn "*one_cmpldi2_1_rex64"
9985 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9986 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9987 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9989 [(set_attr "type" "negnot")
9990 (set_attr "mode" "DI")])
9992 (define_insn "*one_cmpldi2_2_rex64"
9993 [(set (reg FLAGS_REG)
9994 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9996 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9997 (not:DI (match_dup 1)))]
9998 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9999 && ix86_unary_operator_ok (NOT, DImode, operands)"
10001 [(set_attr "type" "alu1")
10002 (set_attr "mode" "DI")])
10005 [(set (match_operand 0 "flags_reg_operand" "")
10006 (match_operator 2 "compare_operator"
10007 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10009 (set (match_operand:DI 1 "nonimmediate_operand" "")
10010 (not:DI (match_dup 3)))]
10011 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10012 [(parallel [(set (match_dup 0)
10014 [(xor:DI (match_dup 3) (const_int -1))
10017 (xor:DI (match_dup 3) (const_int -1)))])]
10020 (define_expand "one_cmplsi2"
10021 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10022 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10024 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10026 (define_insn "*one_cmplsi2_1"
10027 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10028 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10029 "ix86_unary_operator_ok (NOT, SImode, operands)"
10031 [(set_attr "type" "negnot")
10032 (set_attr "mode" "SI")])
10034 ;; ??? Currently never generated - xor is used instead.
10035 (define_insn "*one_cmplsi2_1_zext"
10036 [(set (match_operand:DI 0 "register_operand" "=r")
10037 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10038 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10040 [(set_attr "type" "negnot")
10041 (set_attr "mode" "SI")])
10043 (define_insn "*one_cmplsi2_2"
10044 [(set (reg FLAGS_REG)
10045 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10047 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10048 (not:SI (match_dup 1)))]
10049 "ix86_match_ccmode (insn, CCNOmode)
10050 && ix86_unary_operator_ok (NOT, SImode, operands)"
10052 [(set_attr "type" "alu1")
10053 (set_attr "mode" "SI")])
10056 [(set (match_operand 0 "flags_reg_operand" "")
10057 (match_operator 2 "compare_operator"
10058 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10060 (set (match_operand:SI 1 "nonimmediate_operand" "")
10061 (not:SI (match_dup 3)))]
10062 "ix86_match_ccmode (insn, CCNOmode)"
10063 [(parallel [(set (match_dup 0)
10064 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10067 (xor:SI (match_dup 3) (const_int -1)))])]
10070 ;; ??? Currently never generated - xor is used instead.
10071 (define_insn "*one_cmplsi2_2_zext"
10072 [(set (reg FLAGS_REG)
10073 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10075 (set (match_operand:DI 0 "register_operand" "=r")
10076 (zero_extend:DI (not:SI (match_dup 1))))]
10077 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10078 && ix86_unary_operator_ok (NOT, SImode, operands)"
10080 [(set_attr "type" "alu1")
10081 (set_attr "mode" "SI")])
10084 [(set (match_operand 0 "flags_reg_operand" "")
10085 (match_operator 2 "compare_operator"
10086 [(not:SI (match_operand:SI 3 "register_operand" ""))
10088 (set (match_operand:DI 1 "register_operand" "")
10089 (zero_extend:DI (not:SI (match_dup 3))))]
10090 "ix86_match_ccmode (insn, CCNOmode)"
10091 [(parallel [(set (match_dup 0)
10092 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10095 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10098 (define_expand "one_cmplhi2"
10099 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10100 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10101 "TARGET_HIMODE_MATH"
10102 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10104 (define_insn "*one_cmplhi2_1"
10105 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10106 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10107 "ix86_unary_operator_ok (NOT, HImode, operands)"
10109 [(set_attr "type" "negnot")
10110 (set_attr "mode" "HI")])
10112 (define_insn "*one_cmplhi2_2"
10113 [(set (reg FLAGS_REG)
10114 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10116 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10117 (not:HI (match_dup 1)))]
10118 "ix86_match_ccmode (insn, CCNOmode)
10119 && ix86_unary_operator_ok (NEG, HImode, operands)"
10121 [(set_attr "type" "alu1")
10122 (set_attr "mode" "HI")])
10125 [(set (match_operand 0 "flags_reg_operand" "")
10126 (match_operator 2 "compare_operator"
10127 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10129 (set (match_operand:HI 1 "nonimmediate_operand" "")
10130 (not:HI (match_dup 3)))]
10131 "ix86_match_ccmode (insn, CCNOmode)"
10132 [(parallel [(set (match_dup 0)
10133 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10136 (xor:HI (match_dup 3) (const_int -1)))])]
10139 ;; %%% Potential partial reg stall on alternative 1. What to do?
10140 (define_expand "one_cmplqi2"
10141 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10142 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10143 "TARGET_QIMODE_MATH"
10144 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10146 (define_insn "*one_cmplqi2_1"
10147 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10148 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10149 "ix86_unary_operator_ok (NOT, QImode, operands)"
10153 [(set_attr "type" "negnot")
10154 (set_attr "mode" "QI,SI")])
10156 (define_insn "*one_cmplqi2_2"
10157 [(set (reg FLAGS_REG)
10158 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10160 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10161 (not:QI (match_dup 1)))]
10162 "ix86_match_ccmode (insn, CCNOmode)
10163 && ix86_unary_operator_ok (NOT, QImode, operands)"
10165 [(set_attr "type" "alu1")
10166 (set_attr "mode" "QI")])
10169 [(set (match_operand 0 "flags_reg_operand" "")
10170 (match_operator 2 "compare_operator"
10171 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10173 (set (match_operand:QI 1 "nonimmediate_operand" "")
10174 (not:QI (match_dup 3)))]
10175 "ix86_match_ccmode (insn, CCNOmode)"
10176 [(parallel [(set (match_dup 0)
10177 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10180 (xor:QI (match_dup 3) (const_int -1)))])]
10183 ;; Arithmetic shift instructions
10185 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10186 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10187 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10188 ;; from the assembler input.
10190 ;; This instruction shifts the target reg/mem as usual, but instead of
10191 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10192 ;; is a left shift double, bits are taken from the high order bits of
10193 ;; reg, else if the insn is a shift right double, bits are taken from the
10194 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10195 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10197 ;; Since sh[lr]d does not change the `reg' operand, that is done
10198 ;; separately, making all shifts emit pairs of shift double and normal
10199 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10200 ;; support a 63 bit shift, each shift where the count is in a reg expands
10201 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10203 ;; If the shift count is a constant, we need never emit more than one
10204 ;; shift pair, instead using moves and sign extension for counts greater
10207 (define_expand "ashlti3"
10208 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10209 (ashift:TI (match_operand:TI 1 "register_operand" "")
10210 (match_operand:QI 2 "nonmemory_operand" "")))
10211 (clobber (reg:CC FLAGS_REG))])]
10214 if (! immediate_operand (operands[2], QImode))
10216 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10219 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10223 (define_insn "ashlti3_1"
10224 [(set (match_operand:TI 0 "register_operand" "=r")
10225 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10226 (match_operand:QI 2 "register_operand" "c")))
10227 (clobber (match_scratch:DI 3 "=&r"))
10228 (clobber (reg:CC FLAGS_REG))]
10231 [(set_attr "type" "multi")])
10233 (define_insn "*ashlti3_2"
10234 [(set (match_operand:TI 0 "register_operand" "=r")
10235 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10236 (match_operand:QI 2 "immediate_operand" "O")))
10237 (clobber (reg:CC FLAGS_REG))]
10240 [(set_attr "type" "multi")])
10243 [(set (match_operand:TI 0 "register_operand" "")
10244 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10245 (match_operand:QI 2 "register_operand" "")))
10246 (clobber (match_scratch:DI 3 ""))
10247 (clobber (reg:CC FLAGS_REG))]
10248 "TARGET_64BIT && reload_completed"
10250 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10253 [(set (match_operand:TI 0 "register_operand" "")
10254 (ashift:TI (match_operand:TI 1 "register_operand" "")
10255 (match_operand:QI 2 "immediate_operand" "")))
10256 (clobber (reg:CC FLAGS_REG))]
10257 "TARGET_64BIT && reload_completed"
10259 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10261 (define_insn "x86_64_shld"
10262 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10263 (ior:DI (ashift:DI (match_dup 0)
10264 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10265 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10266 (minus:QI (const_int 64) (match_dup 2)))))
10267 (clobber (reg:CC FLAGS_REG))]
10270 shld{q}\t{%2, %1, %0|%0, %1, %2}
10271 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10272 [(set_attr "type" "ishift")
10273 (set_attr "prefix_0f" "1")
10274 (set_attr "mode" "DI")
10275 (set_attr "athlon_decode" "vector")])
10277 (define_expand "x86_64_shift_adj"
10278 [(set (reg:CCZ FLAGS_REG)
10279 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10282 (set (match_operand:DI 0 "register_operand" "")
10283 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10284 (match_operand:DI 1 "register_operand" "")
10287 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10288 (match_operand:DI 3 "register_operand" "r")
10293 (define_expand "ashldi3"
10294 [(set (match_operand:DI 0 "shiftdi_operand" "")
10295 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10296 (match_operand:QI 2 "nonmemory_operand" "")))]
10298 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10300 (define_insn "*ashldi3_1_rex64"
10301 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10302 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10303 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10304 (clobber (reg:CC FLAGS_REG))]
10305 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10307 switch (get_attr_type (insn))
10310 gcc_assert (operands[2] == const1_rtx);
10311 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10312 return "add{q}\t{%0, %0|%0, %0}";
10315 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10316 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10317 operands[1] = gen_rtx_MULT (DImode, operands[1],
10318 GEN_INT (1 << INTVAL (operands[2])));
10319 return "lea{q}\t{%a1, %0|%0, %a1}";
10322 if (REG_P (operands[2]))
10323 return "sal{q}\t{%b2, %0|%0, %b2}";
10324 else if (operands[2] == const1_rtx
10325 && (TARGET_SHIFT1 || optimize_size))
10326 return "sal{q}\t%0";
10328 return "sal{q}\t{%2, %0|%0, %2}";
10331 [(set (attr "type")
10332 (cond [(eq_attr "alternative" "1")
10333 (const_string "lea")
10334 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10336 (match_operand 0 "register_operand" ""))
10337 (match_operand 2 "const1_operand" ""))
10338 (const_string "alu")
10340 (const_string "ishift")))
10341 (set_attr "mode" "DI")])
10343 ;; Convert lea to the lea pattern to avoid flags dependency.
10345 [(set (match_operand:DI 0 "register_operand" "")
10346 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10347 (match_operand:QI 2 "immediate_operand" "")))
10348 (clobber (reg:CC FLAGS_REG))]
10349 "TARGET_64BIT && reload_completed
10350 && true_regnum (operands[0]) != true_regnum (operands[1])"
10351 [(set (match_dup 0)
10352 (mult:DI (match_dup 1)
10354 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10356 ;; This pattern can't accept a variable shift count, since shifts by
10357 ;; zero don't affect the flags. We assume that shifts by constant
10358 ;; zero are optimized away.
10359 (define_insn "*ashldi3_cmp_rex64"
10360 [(set (reg FLAGS_REG)
10362 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10363 (match_operand:QI 2 "immediate_operand" "e"))
10365 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10366 (ashift:DI (match_dup 1) (match_dup 2)))]
10367 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10368 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10370 switch (get_attr_type (insn))
10373 gcc_assert (operands[2] == const1_rtx);
10374 return "add{q}\t{%0, %0|%0, %0}";
10377 if (REG_P (operands[2]))
10378 return "sal{q}\t{%b2, %0|%0, %b2}";
10379 else if (operands[2] == const1_rtx
10380 && (TARGET_SHIFT1 || optimize_size))
10381 return "sal{q}\t%0";
10383 return "sal{q}\t{%2, %0|%0, %2}";
10386 [(set (attr "type")
10387 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10389 (match_operand 0 "register_operand" ""))
10390 (match_operand 2 "const1_operand" ""))
10391 (const_string "alu")
10393 (const_string "ishift")))
10394 (set_attr "mode" "DI")])
10396 (define_insn "*ashldi3_1"
10397 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10398 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10399 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10400 (clobber (reg:CC FLAGS_REG))]
10403 [(set_attr "type" "multi")])
10405 ;; By default we don't ask for a scratch register, because when DImode
10406 ;; values are manipulated, registers are already at a premium. But if
10407 ;; we have one handy, we won't turn it away.
10409 [(match_scratch:SI 3 "r")
10410 (parallel [(set (match_operand:DI 0 "register_operand" "")
10411 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10412 (match_operand:QI 2 "nonmemory_operand" "")))
10413 (clobber (reg:CC FLAGS_REG))])
10415 "!TARGET_64BIT && TARGET_CMOVE"
10417 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10420 [(set (match_operand:DI 0 "register_operand" "")
10421 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10422 (match_operand:QI 2 "nonmemory_operand" "")))
10423 (clobber (reg:CC FLAGS_REG))]
10424 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10425 ? flow2_completed : reload_completed)"
10427 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10429 (define_insn "x86_shld_1"
10430 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10431 (ior:SI (ashift:SI (match_dup 0)
10432 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10433 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10434 (minus:QI (const_int 32) (match_dup 2)))))
10435 (clobber (reg:CC FLAGS_REG))]
10438 shld{l}\t{%2, %1, %0|%0, %1, %2}
10439 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10440 [(set_attr "type" "ishift")
10441 (set_attr "prefix_0f" "1")
10442 (set_attr "mode" "SI")
10443 (set_attr "pent_pair" "np")
10444 (set_attr "athlon_decode" "vector")])
10446 (define_expand "x86_shift_adj_1"
10447 [(set (reg:CCZ FLAGS_REG)
10448 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10451 (set (match_operand:SI 0 "register_operand" "")
10452 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10453 (match_operand:SI 1 "register_operand" "")
10456 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10457 (match_operand:SI 3 "register_operand" "r")
10462 (define_expand "x86_shift_adj_2"
10463 [(use (match_operand:SI 0 "register_operand" ""))
10464 (use (match_operand:SI 1 "register_operand" ""))
10465 (use (match_operand:QI 2 "register_operand" ""))]
10468 rtx label = gen_label_rtx ();
10471 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10473 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10474 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10475 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10476 gen_rtx_LABEL_REF (VOIDmode, label),
10478 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10479 JUMP_LABEL (tmp) = label;
10481 emit_move_insn (operands[0], operands[1]);
10482 ix86_expand_clear (operands[1]);
10484 emit_label (label);
10485 LABEL_NUSES (label) = 1;
10490 (define_expand "ashlsi3"
10491 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10492 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10493 (match_operand:QI 2 "nonmemory_operand" "")))
10494 (clobber (reg:CC FLAGS_REG))]
10496 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10498 (define_insn "*ashlsi3_1"
10499 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10500 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10501 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10502 (clobber (reg:CC FLAGS_REG))]
10503 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10505 switch (get_attr_type (insn))
10508 gcc_assert (operands[2] == const1_rtx);
10509 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10510 return "add{l}\t{%0, %0|%0, %0}";
10516 if (REG_P (operands[2]))
10517 return "sal{l}\t{%b2, %0|%0, %b2}";
10518 else if (operands[2] == const1_rtx
10519 && (TARGET_SHIFT1 || optimize_size))
10520 return "sal{l}\t%0";
10522 return "sal{l}\t{%2, %0|%0, %2}";
10525 [(set (attr "type")
10526 (cond [(eq_attr "alternative" "1")
10527 (const_string "lea")
10528 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10530 (match_operand 0 "register_operand" ""))
10531 (match_operand 2 "const1_operand" ""))
10532 (const_string "alu")
10534 (const_string "ishift")))
10535 (set_attr "mode" "SI")])
10537 ;; Convert lea to the lea pattern to avoid flags dependency.
10539 [(set (match_operand 0 "register_operand" "")
10540 (ashift (match_operand 1 "index_register_operand" "")
10541 (match_operand:QI 2 "const_int_operand" "")))
10542 (clobber (reg:CC FLAGS_REG))]
10544 && true_regnum (operands[0]) != true_regnum (operands[1])
10545 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10549 enum machine_mode mode = GET_MODE (operands[0]);
10551 if (GET_MODE_SIZE (mode) < 4)
10552 operands[0] = gen_lowpart (SImode, operands[0]);
10554 operands[1] = gen_lowpart (Pmode, operands[1]);
10555 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10557 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10558 if (Pmode != SImode)
10559 pat = gen_rtx_SUBREG (SImode, pat, 0);
10560 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10564 ;; Rare case of shifting RSP is handled by generating move and shift
10566 [(set (match_operand 0 "register_operand" "")
10567 (ashift (match_operand 1 "register_operand" "")
10568 (match_operand:QI 2 "const_int_operand" "")))
10569 (clobber (reg:CC FLAGS_REG))]
10571 && true_regnum (operands[0]) != true_regnum (operands[1])"
10575 emit_move_insn (operands[1], operands[0]);
10576 pat = gen_rtx_SET (VOIDmode, operands[0],
10577 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10578 operands[0], operands[2]));
10579 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10580 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10584 (define_insn "*ashlsi3_1_zext"
10585 [(set (match_operand:DI 0 "register_operand" "=r,r")
10586 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10587 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10588 (clobber (reg:CC FLAGS_REG))]
10589 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10591 switch (get_attr_type (insn))
10594 gcc_assert (operands[2] == const1_rtx);
10595 return "add{l}\t{%k0, %k0|%k0, %k0}";
10601 if (REG_P (operands[2]))
10602 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10603 else if (operands[2] == const1_rtx
10604 && (TARGET_SHIFT1 || optimize_size))
10605 return "sal{l}\t%k0";
10607 return "sal{l}\t{%2, %k0|%k0, %2}";
10610 [(set (attr "type")
10611 (cond [(eq_attr "alternative" "1")
10612 (const_string "lea")
10613 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10615 (match_operand 2 "const1_operand" ""))
10616 (const_string "alu")
10618 (const_string "ishift")))
10619 (set_attr "mode" "SI")])
10621 ;; Convert lea to the lea pattern to avoid flags dependency.
10623 [(set (match_operand:DI 0 "register_operand" "")
10624 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10625 (match_operand:QI 2 "const_int_operand" ""))))
10626 (clobber (reg:CC FLAGS_REG))]
10627 "TARGET_64BIT && reload_completed
10628 && true_regnum (operands[0]) != true_regnum (operands[1])"
10629 [(set (match_dup 0) (zero_extend:DI
10630 (subreg:SI (mult:SI (match_dup 1)
10631 (match_dup 2)) 0)))]
10633 operands[1] = gen_lowpart (Pmode, operands[1]);
10634 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10637 ;; This pattern can't accept a variable shift count, since shifts by
10638 ;; zero don't affect the flags. We assume that shifts by constant
10639 ;; zero are optimized away.
10640 (define_insn "*ashlsi3_cmp"
10641 [(set (reg FLAGS_REG)
10643 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10644 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10646 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10647 (ashift:SI (match_dup 1) (match_dup 2)))]
10648 "ix86_match_ccmode (insn, CCGOCmode)
10649 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10651 switch (get_attr_type (insn))
10654 gcc_assert (operands[2] == const1_rtx);
10655 return "add{l}\t{%0, %0|%0, %0}";
10658 if (REG_P (operands[2]))
10659 return "sal{l}\t{%b2, %0|%0, %b2}";
10660 else if (operands[2] == const1_rtx
10661 && (TARGET_SHIFT1 || optimize_size))
10662 return "sal{l}\t%0";
10664 return "sal{l}\t{%2, %0|%0, %2}";
10667 [(set (attr "type")
10668 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10670 (match_operand 0 "register_operand" ""))
10671 (match_operand 2 "const1_operand" ""))
10672 (const_string "alu")
10674 (const_string "ishift")))
10675 (set_attr "mode" "SI")])
10677 (define_insn "*ashlsi3_cmp_zext"
10678 [(set (reg FLAGS_REG)
10680 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10681 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10683 (set (match_operand:DI 0 "register_operand" "=r")
10684 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10685 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10686 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10688 switch (get_attr_type (insn))
10691 gcc_assert (operands[2] == const1_rtx);
10692 return "add{l}\t{%k0, %k0|%k0, %k0}";
10695 if (REG_P (operands[2]))
10696 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10697 else if (operands[2] == const1_rtx
10698 && (TARGET_SHIFT1 || optimize_size))
10699 return "sal{l}\t%k0";
10701 return "sal{l}\t{%2, %k0|%k0, %2}";
10704 [(set (attr "type")
10705 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10707 (match_operand 2 "const1_operand" ""))
10708 (const_string "alu")
10710 (const_string "ishift")))
10711 (set_attr "mode" "SI")])
10713 (define_expand "ashlhi3"
10714 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10715 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10716 (match_operand:QI 2 "nonmemory_operand" "")))
10717 (clobber (reg:CC FLAGS_REG))]
10718 "TARGET_HIMODE_MATH"
10719 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10721 (define_insn "*ashlhi3_1_lea"
10722 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10723 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10724 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10725 (clobber (reg:CC FLAGS_REG))]
10726 "!TARGET_PARTIAL_REG_STALL
10727 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10729 switch (get_attr_type (insn))
10734 gcc_assert (operands[2] == const1_rtx);
10735 return "add{w}\t{%0, %0|%0, %0}";
10738 if (REG_P (operands[2]))
10739 return "sal{w}\t{%b2, %0|%0, %b2}";
10740 else if (operands[2] == const1_rtx
10741 && (TARGET_SHIFT1 || optimize_size))
10742 return "sal{w}\t%0";
10744 return "sal{w}\t{%2, %0|%0, %2}";
10747 [(set (attr "type")
10748 (cond [(eq_attr "alternative" "1")
10749 (const_string "lea")
10750 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10752 (match_operand 0 "register_operand" ""))
10753 (match_operand 2 "const1_operand" ""))
10754 (const_string "alu")
10756 (const_string "ishift")))
10757 (set_attr "mode" "HI,SI")])
10759 (define_insn "*ashlhi3_1"
10760 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10761 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10762 (match_operand:QI 2 "nonmemory_operand" "cI")))
10763 (clobber (reg:CC FLAGS_REG))]
10764 "TARGET_PARTIAL_REG_STALL
10765 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10767 switch (get_attr_type (insn))
10770 gcc_assert (operands[2] == const1_rtx);
10771 return "add{w}\t{%0, %0|%0, %0}";
10774 if (REG_P (operands[2]))
10775 return "sal{w}\t{%b2, %0|%0, %b2}";
10776 else if (operands[2] == const1_rtx
10777 && (TARGET_SHIFT1 || optimize_size))
10778 return "sal{w}\t%0";
10780 return "sal{w}\t{%2, %0|%0, %2}";
10783 [(set (attr "type")
10784 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10786 (match_operand 0 "register_operand" ""))
10787 (match_operand 2 "const1_operand" ""))
10788 (const_string "alu")
10790 (const_string "ishift")))
10791 (set_attr "mode" "HI")])
10793 ;; This pattern can't accept a variable shift count, since shifts by
10794 ;; zero don't affect the flags. We assume that shifts by constant
10795 ;; zero are optimized away.
10796 (define_insn "*ashlhi3_cmp"
10797 [(set (reg FLAGS_REG)
10799 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10800 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10802 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10803 (ashift:HI (match_dup 1) (match_dup 2)))]
10804 "ix86_match_ccmode (insn, CCGOCmode)
10805 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10807 switch (get_attr_type (insn))
10810 gcc_assert (operands[2] == const1_rtx);
10811 return "add{w}\t{%0, %0|%0, %0}";
10814 if (REG_P (operands[2]))
10815 return "sal{w}\t{%b2, %0|%0, %b2}";
10816 else if (operands[2] == const1_rtx
10817 && (TARGET_SHIFT1 || optimize_size))
10818 return "sal{w}\t%0";
10820 return "sal{w}\t{%2, %0|%0, %2}";
10823 [(set (attr "type")
10824 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10826 (match_operand 0 "register_operand" ""))
10827 (match_operand 2 "const1_operand" ""))
10828 (const_string "alu")
10830 (const_string "ishift")))
10831 (set_attr "mode" "HI")])
10833 (define_expand "ashlqi3"
10834 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10835 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10836 (match_operand:QI 2 "nonmemory_operand" "")))
10837 (clobber (reg:CC FLAGS_REG))]
10838 "TARGET_QIMODE_MATH"
10839 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10841 ;; %%% Potential partial reg stall on alternative 2. What to do?
10843 (define_insn "*ashlqi3_1_lea"
10844 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10845 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10846 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10847 (clobber (reg:CC FLAGS_REG))]
10848 "!TARGET_PARTIAL_REG_STALL
10849 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10851 switch (get_attr_type (insn))
10856 gcc_assert (operands[2] == const1_rtx);
10857 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10858 return "add{l}\t{%k0, %k0|%k0, %k0}";
10860 return "add{b}\t{%0, %0|%0, %0}";
10863 if (REG_P (operands[2]))
10865 if (get_attr_mode (insn) == MODE_SI)
10866 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10868 return "sal{b}\t{%b2, %0|%0, %b2}";
10870 else if (operands[2] == const1_rtx
10871 && (TARGET_SHIFT1 || optimize_size))
10873 if (get_attr_mode (insn) == MODE_SI)
10874 return "sal{l}\t%0";
10876 return "sal{b}\t%0";
10880 if (get_attr_mode (insn) == MODE_SI)
10881 return "sal{l}\t{%2, %k0|%k0, %2}";
10883 return "sal{b}\t{%2, %0|%0, %2}";
10887 [(set (attr "type")
10888 (cond [(eq_attr "alternative" "2")
10889 (const_string "lea")
10890 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10892 (match_operand 0 "register_operand" ""))
10893 (match_operand 2 "const1_operand" ""))
10894 (const_string "alu")
10896 (const_string "ishift")))
10897 (set_attr "mode" "QI,SI,SI")])
10899 (define_insn "*ashlqi3_1"
10900 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10901 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10902 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10903 (clobber (reg:CC FLAGS_REG))]
10904 "TARGET_PARTIAL_REG_STALL
10905 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10907 switch (get_attr_type (insn))
10910 gcc_assert (operands[2] == const1_rtx);
10911 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10912 return "add{l}\t{%k0, %k0|%k0, %k0}";
10914 return "add{b}\t{%0, %0|%0, %0}";
10917 if (REG_P (operands[2]))
10919 if (get_attr_mode (insn) == MODE_SI)
10920 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10922 return "sal{b}\t{%b2, %0|%0, %b2}";
10924 else if (operands[2] == const1_rtx
10925 && (TARGET_SHIFT1 || optimize_size))
10927 if (get_attr_mode (insn) == MODE_SI)
10928 return "sal{l}\t%0";
10930 return "sal{b}\t%0";
10934 if (get_attr_mode (insn) == MODE_SI)
10935 return "sal{l}\t{%2, %k0|%k0, %2}";
10937 return "sal{b}\t{%2, %0|%0, %2}";
10941 [(set (attr "type")
10942 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10944 (match_operand 0 "register_operand" ""))
10945 (match_operand 2 "const1_operand" ""))
10946 (const_string "alu")
10948 (const_string "ishift")))
10949 (set_attr "mode" "QI,SI")])
10951 ;; This pattern can't accept a variable shift count, since shifts by
10952 ;; zero don't affect the flags. We assume that shifts by constant
10953 ;; zero are optimized away.
10954 (define_insn "*ashlqi3_cmp"
10955 [(set (reg FLAGS_REG)
10957 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10958 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10960 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10961 (ashift:QI (match_dup 1) (match_dup 2)))]
10962 "ix86_match_ccmode (insn, CCGOCmode)
10963 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10965 switch (get_attr_type (insn))
10968 gcc_assert (operands[2] == const1_rtx);
10969 return "add{b}\t{%0, %0|%0, %0}";
10972 if (REG_P (operands[2]))
10973 return "sal{b}\t{%b2, %0|%0, %b2}";
10974 else if (operands[2] == const1_rtx
10975 && (TARGET_SHIFT1 || optimize_size))
10976 return "sal{b}\t%0";
10978 return "sal{b}\t{%2, %0|%0, %2}";
10981 [(set (attr "type")
10982 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10984 (match_operand 0 "register_operand" ""))
10985 (match_operand 2 "const1_operand" ""))
10986 (const_string "alu")
10988 (const_string "ishift")))
10989 (set_attr "mode" "QI")])
10991 ;; See comment above `ashldi3' about how this works.
10993 (define_expand "ashrti3"
10994 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10995 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10996 (match_operand:QI 2 "nonmemory_operand" "")))
10997 (clobber (reg:CC FLAGS_REG))])]
11000 if (! immediate_operand (operands[2], QImode))
11002 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11005 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11009 (define_insn "ashrti3_1"
11010 [(set (match_operand:TI 0 "register_operand" "=r")
11011 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11012 (match_operand:QI 2 "register_operand" "c")))
11013 (clobber (match_scratch:DI 3 "=&r"))
11014 (clobber (reg:CC FLAGS_REG))]
11017 [(set_attr "type" "multi")])
11019 (define_insn "*ashrti3_2"
11020 [(set (match_operand:TI 0 "register_operand" "=r")
11021 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11022 (match_operand:QI 2 "immediate_operand" "O")))
11023 (clobber (reg:CC FLAGS_REG))]
11026 [(set_attr "type" "multi")])
11029 [(set (match_operand:TI 0 "register_operand" "")
11030 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11031 (match_operand:QI 2 "register_operand" "")))
11032 (clobber (match_scratch:DI 3 ""))
11033 (clobber (reg:CC FLAGS_REG))]
11034 "TARGET_64BIT && reload_completed"
11036 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11039 [(set (match_operand:TI 0 "register_operand" "")
11040 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11041 (match_operand:QI 2 "immediate_operand" "")))
11042 (clobber (reg:CC FLAGS_REG))]
11043 "TARGET_64BIT && reload_completed"
11045 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11047 (define_insn "x86_64_shrd"
11048 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11049 (ior:DI (ashiftrt:DI (match_dup 0)
11050 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11051 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11052 (minus:QI (const_int 64) (match_dup 2)))))
11053 (clobber (reg:CC FLAGS_REG))]
11056 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11057 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11058 [(set_attr "type" "ishift")
11059 (set_attr "prefix_0f" "1")
11060 (set_attr "mode" "DI")
11061 (set_attr "athlon_decode" "vector")])
11063 (define_expand "ashrdi3"
11064 [(set (match_operand:DI 0 "shiftdi_operand" "")
11065 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11066 (match_operand:QI 2 "nonmemory_operand" "")))]
11068 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11070 (define_insn "*ashrdi3_63_rex64"
11071 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11072 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11073 (match_operand:DI 2 "const_int_operand" "i,i")))
11074 (clobber (reg:CC FLAGS_REG))]
11075 "TARGET_64BIT && INTVAL (operands[2]) == 63
11076 && (TARGET_USE_CLTD || optimize_size)
11077 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11080 sar{q}\t{%2, %0|%0, %2}"
11081 [(set_attr "type" "imovx,ishift")
11082 (set_attr "prefix_0f" "0,*")
11083 (set_attr "length_immediate" "0,*")
11084 (set_attr "modrm" "0,1")
11085 (set_attr "mode" "DI")])
11087 (define_insn "*ashrdi3_1_one_bit_rex64"
11088 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11089 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11090 (match_operand:QI 2 "const1_operand" "")))
11091 (clobber (reg:CC FLAGS_REG))]
11092 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11093 && (TARGET_SHIFT1 || optimize_size)"
11095 [(set_attr "type" "ishift")
11096 (set (attr "length")
11097 (if_then_else (match_operand:DI 0 "register_operand" "")
11099 (const_string "*")))])
11101 (define_insn "*ashrdi3_1_rex64"
11102 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11103 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11104 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11105 (clobber (reg:CC FLAGS_REG))]
11106 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11108 sar{q}\t{%2, %0|%0, %2}
11109 sar{q}\t{%b2, %0|%0, %b2}"
11110 [(set_attr "type" "ishift")
11111 (set_attr "mode" "DI")])
11113 ;; This pattern can't accept a variable shift count, since shifts by
11114 ;; zero don't affect the flags. We assume that shifts by constant
11115 ;; zero are optimized away.
11116 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11117 [(set (reg FLAGS_REG)
11119 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11120 (match_operand:QI 2 "const1_operand" ""))
11122 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11123 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11124 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11125 && (TARGET_SHIFT1 || optimize_size)
11126 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11128 [(set_attr "type" "ishift")
11129 (set (attr "length")
11130 (if_then_else (match_operand:DI 0 "register_operand" "")
11132 (const_string "*")))])
11134 ;; This pattern can't accept a variable shift count, since shifts by
11135 ;; zero don't affect the flags. We assume that shifts by constant
11136 ;; zero are optimized away.
11137 (define_insn "*ashrdi3_cmp_rex64"
11138 [(set (reg FLAGS_REG)
11140 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11141 (match_operand:QI 2 "const_int_operand" "n"))
11143 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11144 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11145 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11146 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11147 "sar{q}\t{%2, %0|%0, %2}"
11148 [(set_attr "type" "ishift")
11149 (set_attr "mode" "DI")])
11151 (define_insn "*ashrdi3_1"
11152 [(set (match_operand:DI 0 "register_operand" "=r")
11153 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11154 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11155 (clobber (reg:CC FLAGS_REG))]
11158 [(set_attr "type" "multi")])
11160 ;; By default we don't ask for a scratch register, because when DImode
11161 ;; values are manipulated, registers are already at a premium. But if
11162 ;; we have one handy, we won't turn it away.
11164 [(match_scratch:SI 3 "r")
11165 (parallel [(set (match_operand:DI 0 "register_operand" "")
11166 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11167 (match_operand:QI 2 "nonmemory_operand" "")))
11168 (clobber (reg:CC FLAGS_REG))])
11170 "!TARGET_64BIT && TARGET_CMOVE"
11172 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11175 [(set (match_operand:DI 0 "register_operand" "")
11176 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11177 (match_operand:QI 2 "nonmemory_operand" "")))
11178 (clobber (reg:CC FLAGS_REG))]
11179 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11180 ? flow2_completed : reload_completed)"
11182 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11184 (define_insn "x86_shrd_1"
11185 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11186 (ior:SI (ashiftrt:SI (match_dup 0)
11187 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11188 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11189 (minus:QI (const_int 32) (match_dup 2)))))
11190 (clobber (reg:CC FLAGS_REG))]
11193 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11194 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11195 [(set_attr "type" "ishift")
11196 (set_attr "prefix_0f" "1")
11197 (set_attr "pent_pair" "np")
11198 (set_attr "mode" "SI")])
11200 (define_expand "x86_shift_adj_3"
11201 [(use (match_operand:SI 0 "register_operand" ""))
11202 (use (match_operand:SI 1 "register_operand" ""))
11203 (use (match_operand:QI 2 "register_operand" ""))]
11206 rtx label = gen_label_rtx ();
11209 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11211 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11212 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11213 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11214 gen_rtx_LABEL_REF (VOIDmode, label),
11216 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11217 JUMP_LABEL (tmp) = label;
11219 emit_move_insn (operands[0], operands[1]);
11220 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11222 emit_label (label);
11223 LABEL_NUSES (label) = 1;
11228 (define_insn "ashrsi3_31"
11229 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11230 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11231 (match_operand:SI 2 "const_int_operand" "i,i")))
11232 (clobber (reg:CC FLAGS_REG))]
11233 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11234 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11237 sar{l}\t{%2, %0|%0, %2}"
11238 [(set_attr "type" "imovx,ishift")
11239 (set_attr "prefix_0f" "0,*")
11240 (set_attr "length_immediate" "0,*")
11241 (set_attr "modrm" "0,1")
11242 (set_attr "mode" "SI")])
11244 (define_insn "*ashrsi3_31_zext"
11245 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11246 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11247 (match_operand:SI 2 "const_int_operand" "i,i"))))
11248 (clobber (reg:CC FLAGS_REG))]
11249 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11250 && INTVAL (operands[2]) == 31
11251 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11254 sar{l}\t{%2, %k0|%k0, %2}"
11255 [(set_attr "type" "imovx,ishift")
11256 (set_attr "prefix_0f" "0,*")
11257 (set_attr "length_immediate" "0,*")
11258 (set_attr "modrm" "0,1")
11259 (set_attr "mode" "SI")])
11261 (define_expand "ashrsi3"
11262 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11263 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11264 (match_operand:QI 2 "nonmemory_operand" "")))
11265 (clobber (reg:CC FLAGS_REG))]
11267 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11269 (define_insn "*ashrsi3_1_one_bit"
11270 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11271 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11272 (match_operand:QI 2 "const1_operand" "")))
11273 (clobber (reg:CC FLAGS_REG))]
11274 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11275 && (TARGET_SHIFT1 || optimize_size)"
11277 [(set_attr "type" "ishift")
11278 (set (attr "length")
11279 (if_then_else (match_operand:SI 0 "register_operand" "")
11281 (const_string "*")))])
11283 (define_insn "*ashrsi3_1_one_bit_zext"
11284 [(set (match_operand:DI 0 "register_operand" "=r")
11285 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11286 (match_operand:QI 2 "const1_operand" ""))))
11287 (clobber (reg:CC FLAGS_REG))]
11288 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11289 && (TARGET_SHIFT1 || optimize_size)"
11291 [(set_attr "type" "ishift")
11292 (set_attr "length" "2")])
11294 (define_insn "*ashrsi3_1"
11295 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11296 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11297 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11298 (clobber (reg:CC FLAGS_REG))]
11299 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11301 sar{l}\t{%2, %0|%0, %2}
11302 sar{l}\t{%b2, %0|%0, %b2}"
11303 [(set_attr "type" "ishift")
11304 (set_attr "mode" "SI")])
11306 (define_insn "*ashrsi3_1_zext"
11307 [(set (match_operand:DI 0 "register_operand" "=r,r")
11308 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11309 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11310 (clobber (reg:CC FLAGS_REG))]
11311 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11313 sar{l}\t{%2, %k0|%k0, %2}
11314 sar{l}\t{%b2, %k0|%k0, %b2}"
11315 [(set_attr "type" "ishift")
11316 (set_attr "mode" "SI")])
11318 ;; This pattern can't accept a variable shift count, since shifts by
11319 ;; zero don't affect the flags. We assume that shifts by constant
11320 ;; zero are optimized away.
11321 (define_insn "*ashrsi3_one_bit_cmp"
11322 [(set (reg FLAGS_REG)
11324 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11325 (match_operand:QI 2 "const1_operand" ""))
11327 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11328 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11329 "ix86_match_ccmode (insn, CCGOCmode)
11330 && (TARGET_SHIFT1 || optimize_size)
11331 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11333 [(set_attr "type" "ishift")
11334 (set (attr "length")
11335 (if_then_else (match_operand:SI 0 "register_operand" "")
11337 (const_string "*")))])
11339 (define_insn "*ashrsi3_one_bit_cmp_zext"
11340 [(set (reg FLAGS_REG)
11342 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11343 (match_operand:QI 2 "const1_operand" ""))
11345 (set (match_operand:DI 0 "register_operand" "=r")
11346 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11347 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11348 && (TARGET_SHIFT1 || optimize_size)
11349 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11351 [(set_attr "type" "ishift")
11352 (set_attr "length" "2")])
11354 ;; This pattern can't accept a variable shift count, since shifts by
11355 ;; zero don't affect the flags. We assume that shifts by constant
11356 ;; zero are optimized away.
11357 (define_insn "*ashrsi3_cmp"
11358 [(set (reg FLAGS_REG)
11360 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11361 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11363 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11364 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11365 "ix86_match_ccmode (insn, CCGOCmode)
11366 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11367 "sar{l}\t{%2, %0|%0, %2}"
11368 [(set_attr "type" "ishift")
11369 (set_attr "mode" "SI")])
11371 (define_insn "*ashrsi3_cmp_zext"
11372 [(set (reg FLAGS_REG)
11374 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11375 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11377 (set (match_operand:DI 0 "register_operand" "=r")
11378 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11379 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11380 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11381 "sar{l}\t{%2, %k0|%k0, %2}"
11382 [(set_attr "type" "ishift")
11383 (set_attr "mode" "SI")])
11385 (define_expand "ashrhi3"
11386 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11387 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11388 (match_operand:QI 2 "nonmemory_operand" "")))
11389 (clobber (reg:CC FLAGS_REG))]
11390 "TARGET_HIMODE_MATH"
11391 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11393 (define_insn "*ashrhi3_1_one_bit"
11394 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11395 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11396 (match_operand:QI 2 "const1_operand" "")))
11397 (clobber (reg:CC FLAGS_REG))]
11398 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11399 && (TARGET_SHIFT1 || optimize_size)"
11401 [(set_attr "type" "ishift")
11402 (set (attr "length")
11403 (if_then_else (match_operand 0 "register_operand" "")
11405 (const_string "*")))])
11407 (define_insn "*ashrhi3_1"
11408 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11409 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11410 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11411 (clobber (reg:CC FLAGS_REG))]
11412 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11414 sar{w}\t{%2, %0|%0, %2}
11415 sar{w}\t{%b2, %0|%0, %b2}"
11416 [(set_attr "type" "ishift")
11417 (set_attr "mode" "HI")])
11419 ;; This pattern can't accept a variable shift count, since shifts by
11420 ;; zero don't affect the flags. We assume that shifts by constant
11421 ;; zero are optimized away.
11422 (define_insn "*ashrhi3_one_bit_cmp"
11423 [(set (reg FLAGS_REG)
11425 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11426 (match_operand:QI 2 "const1_operand" ""))
11428 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11429 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11430 "ix86_match_ccmode (insn, CCGOCmode)
11431 && (TARGET_SHIFT1 || optimize_size)
11432 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11434 [(set_attr "type" "ishift")
11435 (set (attr "length")
11436 (if_then_else (match_operand 0 "register_operand" "")
11438 (const_string "*")))])
11440 ;; This pattern can't accept a variable shift count, since shifts by
11441 ;; zero don't affect the flags. We assume that shifts by constant
11442 ;; zero are optimized away.
11443 (define_insn "*ashrhi3_cmp"
11444 [(set (reg FLAGS_REG)
11446 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11447 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11449 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11450 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11451 "ix86_match_ccmode (insn, CCGOCmode)
11452 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11453 "sar{w}\t{%2, %0|%0, %2}"
11454 [(set_attr "type" "ishift")
11455 (set_attr "mode" "HI")])
11457 (define_expand "ashrqi3"
11458 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11459 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11460 (match_operand:QI 2 "nonmemory_operand" "")))
11461 (clobber (reg:CC FLAGS_REG))]
11462 "TARGET_QIMODE_MATH"
11463 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11465 (define_insn "*ashrqi3_1_one_bit"
11466 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11467 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11468 (match_operand:QI 2 "const1_operand" "")))
11469 (clobber (reg:CC FLAGS_REG))]
11470 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11471 && (TARGET_SHIFT1 || optimize_size)"
11473 [(set_attr "type" "ishift")
11474 (set (attr "length")
11475 (if_then_else (match_operand 0 "register_operand" "")
11477 (const_string "*")))])
11479 (define_insn "*ashrqi3_1_one_bit_slp"
11480 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11481 (ashiftrt:QI (match_dup 0)
11482 (match_operand:QI 1 "const1_operand" "")))
11483 (clobber (reg:CC FLAGS_REG))]
11484 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11485 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11486 && (TARGET_SHIFT1 || optimize_size)"
11488 [(set_attr "type" "ishift1")
11489 (set (attr "length")
11490 (if_then_else (match_operand 0 "register_operand" "")
11492 (const_string "*")))])
11494 (define_insn "*ashrqi3_1"
11495 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11496 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11497 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11498 (clobber (reg:CC FLAGS_REG))]
11499 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11501 sar{b}\t{%2, %0|%0, %2}
11502 sar{b}\t{%b2, %0|%0, %b2}"
11503 [(set_attr "type" "ishift")
11504 (set_attr "mode" "QI")])
11506 (define_insn "*ashrqi3_1_slp"
11507 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11508 (ashiftrt:QI (match_dup 0)
11509 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11510 (clobber (reg:CC FLAGS_REG))]
11511 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11512 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11514 sar{b}\t{%1, %0|%0, %1}
11515 sar{b}\t{%b1, %0|%0, %b1}"
11516 [(set_attr "type" "ishift1")
11517 (set_attr "mode" "QI")])
11519 ;; This pattern can't accept a variable shift count, since shifts by
11520 ;; zero don't affect the flags. We assume that shifts by constant
11521 ;; zero are optimized away.
11522 (define_insn "*ashrqi3_one_bit_cmp"
11523 [(set (reg FLAGS_REG)
11525 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11526 (match_operand:QI 2 "const1_operand" "I"))
11528 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11529 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11530 "ix86_match_ccmode (insn, CCGOCmode)
11531 && (TARGET_SHIFT1 || optimize_size)
11532 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11534 [(set_attr "type" "ishift")
11535 (set (attr "length")
11536 (if_then_else (match_operand 0 "register_operand" "")
11538 (const_string "*")))])
11540 ;; This pattern can't accept a variable shift count, since shifts by
11541 ;; zero don't affect the flags. We assume that shifts by constant
11542 ;; zero are optimized away.
11543 (define_insn "*ashrqi3_cmp"
11544 [(set (reg FLAGS_REG)
11546 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11547 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11549 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11550 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11551 "ix86_match_ccmode (insn, CCGOCmode)
11552 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11553 "sar{b}\t{%2, %0|%0, %2}"
11554 [(set_attr "type" "ishift")
11555 (set_attr "mode" "QI")])
11557 ;; Logical shift instructions
11559 ;; See comment above `ashldi3' about how this works.
11561 (define_expand "lshrti3"
11562 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11563 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11564 (match_operand:QI 2 "nonmemory_operand" "")))
11565 (clobber (reg:CC FLAGS_REG))])]
11568 if (! immediate_operand (operands[2], QImode))
11570 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11573 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11577 (define_insn "lshrti3_1"
11578 [(set (match_operand:TI 0 "register_operand" "=r")
11579 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11580 (match_operand:QI 2 "register_operand" "c")))
11581 (clobber (match_scratch:DI 3 "=&r"))
11582 (clobber (reg:CC FLAGS_REG))]
11585 [(set_attr "type" "multi")])
11587 (define_insn "*lshrti3_2"
11588 [(set (match_operand:TI 0 "register_operand" "=r")
11589 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11590 (match_operand:QI 2 "immediate_operand" "O")))
11591 (clobber (reg:CC FLAGS_REG))]
11594 [(set_attr "type" "multi")])
11597 [(set (match_operand:TI 0 "register_operand" "")
11598 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11599 (match_operand:QI 2 "register_operand" "")))
11600 (clobber (match_scratch:DI 3 ""))
11601 (clobber (reg:CC FLAGS_REG))]
11602 "TARGET_64BIT && reload_completed"
11604 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11607 [(set (match_operand:TI 0 "register_operand" "")
11608 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11609 (match_operand:QI 2 "immediate_operand" "")))
11610 (clobber (reg:CC FLAGS_REG))]
11611 "TARGET_64BIT && reload_completed"
11613 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11615 (define_expand "lshrdi3"
11616 [(set (match_operand:DI 0 "shiftdi_operand" "")
11617 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11618 (match_operand:QI 2 "nonmemory_operand" "")))]
11620 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11622 (define_insn "*lshrdi3_1_one_bit_rex64"
11623 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11624 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11625 (match_operand:QI 2 "const1_operand" "")))
11626 (clobber (reg:CC FLAGS_REG))]
11627 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11628 && (TARGET_SHIFT1 || optimize_size)"
11630 [(set_attr "type" "ishift")
11631 (set (attr "length")
11632 (if_then_else (match_operand:DI 0 "register_operand" "")
11634 (const_string "*")))])
11636 (define_insn "*lshrdi3_1_rex64"
11637 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11638 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11639 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11640 (clobber (reg:CC FLAGS_REG))]
11641 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11643 shr{q}\t{%2, %0|%0, %2}
11644 shr{q}\t{%b2, %0|%0, %b2}"
11645 [(set_attr "type" "ishift")
11646 (set_attr "mode" "DI")])
11648 ;; This pattern can't accept a variable shift count, since shifts by
11649 ;; zero don't affect the flags. We assume that shifts by constant
11650 ;; zero are optimized away.
11651 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11652 [(set (reg FLAGS_REG)
11654 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11655 (match_operand:QI 2 "const1_operand" ""))
11657 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11658 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11659 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11660 && (TARGET_SHIFT1 || optimize_size)
11661 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11663 [(set_attr "type" "ishift")
11664 (set (attr "length")
11665 (if_then_else (match_operand:DI 0 "register_operand" "")
11667 (const_string "*")))])
11669 ;; This pattern can't accept a variable shift count, since shifts by
11670 ;; zero don't affect the flags. We assume that shifts by constant
11671 ;; zero are optimized away.
11672 (define_insn "*lshrdi3_cmp_rex64"
11673 [(set (reg FLAGS_REG)
11675 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11676 (match_operand:QI 2 "const_int_operand" "e"))
11678 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11679 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11680 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11681 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11682 "shr{q}\t{%2, %0|%0, %2}"
11683 [(set_attr "type" "ishift")
11684 (set_attr "mode" "DI")])
11686 (define_insn "*lshrdi3_1"
11687 [(set (match_operand:DI 0 "register_operand" "=r")
11688 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11689 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11690 (clobber (reg:CC FLAGS_REG))]
11693 [(set_attr "type" "multi")])
11695 ;; By default we don't ask for a scratch register, because when DImode
11696 ;; values are manipulated, registers are already at a premium. But if
11697 ;; we have one handy, we won't turn it away.
11699 [(match_scratch:SI 3 "r")
11700 (parallel [(set (match_operand:DI 0 "register_operand" "")
11701 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11702 (match_operand:QI 2 "nonmemory_operand" "")))
11703 (clobber (reg:CC FLAGS_REG))])
11705 "!TARGET_64BIT && TARGET_CMOVE"
11707 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11710 [(set (match_operand:DI 0 "register_operand" "")
11711 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11712 (match_operand:QI 2 "nonmemory_operand" "")))
11713 (clobber (reg:CC FLAGS_REG))]
11714 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11715 ? flow2_completed : reload_completed)"
11717 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11719 (define_expand "lshrsi3"
11720 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11721 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11722 (match_operand:QI 2 "nonmemory_operand" "")))
11723 (clobber (reg:CC FLAGS_REG))]
11725 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11727 (define_insn "*lshrsi3_1_one_bit"
11728 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11729 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11730 (match_operand:QI 2 "const1_operand" "")))
11731 (clobber (reg:CC FLAGS_REG))]
11732 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11733 && (TARGET_SHIFT1 || optimize_size)"
11735 [(set_attr "type" "ishift")
11736 (set (attr "length")
11737 (if_then_else (match_operand:SI 0 "register_operand" "")
11739 (const_string "*")))])
11741 (define_insn "*lshrsi3_1_one_bit_zext"
11742 [(set (match_operand:DI 0 "register_operand" "=r")
11743 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11744 (match_operand:QI 2 "const1_operand" "")))
11745 (clobber (reg:CC FLAGS_REG))]
11746 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11747 && (TARGET_SHIFT1 || optimize_size)"
11749 [(set_attr "type" "ishift")
11750 (set_attr "length" "2")])
11752 (define_insn "*lshrsi3_1"
11753 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11754 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11755 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11756 (clobber (reg:CC FLAGS_REG))]
11757 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11759 shr{l}\t{%2, %0|%0, %2}
11760 shr{l}\t{%b2, %0|%0, %b2}"
11761 [(set_attr "type" "ishift")
11762 (set_attr "mode" "SI")])
11764 (define_insn "*lshrsi3_1_zext"
11765 [(set (match_operand:DI 0 "register_operand" "=r,r")
11767 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11768 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11769 (clobber (reg:CC FLAGS_REG))]
11770 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11772 shr{l}\t{%2, %k0|%k0, %2}
11773 shr{l}\t{%b2, %k0|%k0, %b2}"
11774 [(set_attr "type" "ishift")
11775 (set_attr "mode" "SI")])
11777 ;; This pattern can't accept a variable shift count, since shifts by
11778 ;; zero don't affect the flags. We assume that shifts by constant
11779 ;; zero are optimized away.
11780 (define_insn "*lshrsi3_one_bit_cmp"
11781 [(set (reg FLAGS_REG)
11783 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11784 (match_operand:QI 2 "const1_operand" ""))
11786 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11787 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11788 "ix86_match_ccmode (insn, CCGOCmode)
11789 && (TARGET_SHIFT1 || optimize_size)
11790 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11792 [(set_attr "type" "ishift")
11793 (set (attr "length")
11794 (if_then_else (match_operand:SI 0 "register_operand" "")
11796 (const_string "*")))])
11798 (define_insn "*lshrsi3_cmp_one_bit_zext"
11799 [(set (reg FLAGS_REG)
11801 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11802 (match_operand:QI 2 "const1_operand" ""))
11804 (set (match_operand:DI 0 "register_operand" "=r")
11805 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11806 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11807 && (TARGET_SHIFT1 || optimize_size)
11808 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11810 [(set_attr "type" "ishift")
11811 (set_attr "length" "2")])
11813 ;; This pattern can't accept a variable shift count, since shifts by
11814 ;; zero don't affect the flags. We assume that shifts by constant
11815 ;; zero are optimized away.
11816 (define_insn "*lshrsi3_cmp"
11817 [(set (reg FLAGS_REG)
11819 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11820 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11822 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11823 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11824 "ix86_match_ccmode (insn, CCGOCmode)
11825 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11826 "shr{l}\t{%2, %0|%0, %2}"
11827 [(set_attr "type" "ishift")
11828 (set_attr "mode" "SI")])
11830 (define_insn "*lshrsi3_cmp_zext"
11831 [(set (reg FLAGS_REG)
11833 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11834 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11836 (set (match_operand:DI 0 "register_operand" "=r")
11837 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11838 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11839 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11840 "shr{l}\t{%2, %k0|%k0, %2}"
11841 [(set_attr "type" "ishift")
11842 (set_attr "mode" "SI")])
11844 (define_expand "lshrhi3"
11845 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11846 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11847 (match_operand:QI 2 "nonmemory_operand" "")))
11848 (clobber (reg:CC FLAGS_REG))]
11849 "TARGET_HIMODE_MATH"
11850 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11852 (define_insn "*lshrhi3_1_one_bit"
11853 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11854 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11855 (match_operand:QI 2 "const1_operand" "")))
11856 (clobber (reg:CC FLAGS_REG))]
11857 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11858 && (TARGET_SHIFT1 || optimize_size)"
11860 [(set_attr "type" "ishift")
11861 (set (attr "length")
11862 (if_then_else (match_operand 0 "register_operand" "")
11864 (const_string "*")))])
11866 (define_insn "*lshrhi3_1"
11867 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11868 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11869 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11870 (clobber (reg:CC FLAGS_REG))]
11871 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11873 shr{w}\t{%2, %0|%0, %2}
11874 shr{w}\t{%b2, %0|%0, %b2}"
11875 [(set_attr "type" "ishift")
11876 (set_attr "mode" "HI")])
11878 ;; This pattern can't accept a variable shift count, since shifts by
11879 ;; zero don't affect the flags. We assume that shifts by constant
11880 ;; zero are optimized away.
11881 (define_insn "*lshrhi3_one_bit_cmp"
11882 [(set (reg FLAGS_REG)
11884 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11885 (match_operand:QI 2 "const1_operand" ""))
11887 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11888 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11889 "ix86_match_ccmode (insn, CCGOCmode)
11890 && (TARGET_SHIFT1 || optimize_size)
11891 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11893 [(set_attr "type" "ishift")
11894 (set (attr "length")
11895 (if_then_else (match_operand:SI 0 "register_operand" "")
11897 (const_string "*")))])
11899 ;; This pattern can't accept a variable shift count, since shifts by
11900 ;; zero don't affect the flags. We assume that shifts by constant
11901 ;; zero are optimized away.
11902 (define_insn "*lshrhi3_cmp"
11903 [(set (reg FLAGS_REG)
11905 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11906 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11908 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11909 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11910 "ix86_match_ccmode (insn, CCGOCmode)
11911 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11912 "shr{w}\t{%2, %0|%0, %2}"
11913 [(set_attr "type" "ishift")
11914 (set_attr "mode" "HI")])
11916 (define_expand "lshrqi3"
11917 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11918 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11919 (match_operand:QI 2 "nonmemory_operand" "")))
11920 (clobber (reg:CC FLAGS_REG))]
11921 "TARGET_QIMODE_MATH"
11922 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11924 (define_insn "*lshrqi3_1_one_bit"
11925 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11926 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11927 (match_operand:QI 2 "const1_operand" "")))
11928 (clobber (reg:CC FLAGS_REG))]
11929 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11930 && (TARGET_SHIFT1 || optimize_size)"
11932 [(set_attr "type" "ishift")
11933 (set (attr "length")
11934 (if_then_else (match_operand 0 "register_operand" "")
11936 (const_string "*")))])
11938 (define_insn "*lshrqi3_1_one_bit_slp"
11939 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11940 (lshiftrt:QI (match_dup 0)
11941 (match_operand:QI 1 "const1_operand" "")))
11942 (clobber (reg:CC FLAGS_REG))]
11943 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11944 && (TARGET_SHIFT1 || optimize_size)"
11946 [(set_attr "type" "ishift1")
11947 (set (attr "length")
11948 (if_then_else (match_operand 0 "register_operand" "")
11950 (const_string "*")))])
11952 (define_insn "*lshrqi3_1"
11953 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11954 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11955 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11956 (clobber (reg:CC FLAGS_REG))]
11957 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11959 shr{b}\t{%2, %0|%0, %2}
11960 shr{b}\t{%b2, %0|%0, %b2}"
11961 [(set_attr "type" "ishift")
11962 (set_attr "mode" "QI")])
11964 (define_insn "*lshrqi3_1_slp"
11965 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11966 (lshiftrt:QI (match_dup 0)
11967 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11968 (clobber (reg:CC FLAGS_REG))]
11969 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11970 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11972 shr{b}\t{%1, %0|%0, %1}
11973 shr{b}\t{%b1, %0|%0, %b1}"
11974 [(set_attr "type" "ishift1")
11975 (set_attr "mode" "QI")])
11977 ;; This pattern can't accept a variable shift count, since shifts by
11978 ;; zero don't affect the flags. We assume that shifts by constant
11979 ;; zero are optimized away.
11980 (define_insn "*lshrqi2_one_bit_cmp"
11981 [(set (reg FLAGS_REG)
11983 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11984 (match_operand:QI 2 "const1_operand" ""))
11986 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11987 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11988 "ix86_match_ccmode (insn, CCGOCmode)
11989 && (TARGET_SHIFT1 || optimize_size)
11990 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11992 [(set_attr "type" "ishift")
11993 (set (attr "length")
11994 (if_then_else (match_operand:SI 0 "register_operand" "")
11996 (const_string "*")))])
11998 ;; This pattern can't accept a variable shift count, since shifts by
11999 ;; zero don't affect the flags. We assume that shifts by constant
12000 ;; zero are optimized away.
12001 (define_insn "*lshrqi2_cmp"
12002 [(set (reg FLAGS_REG)
12004 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12005 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12007 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12008 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12009 "ix86_match_ccmode (insn, CCGOCmode)
12010 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12011 "shr{b}\t{%2, %0|%0, %2}"
12012 [(set_attr "type" "ishift")
12013 (set_attr "mode" "QI")])
12015 ;; Rotate instructions
12017 (define_expand "rotldi3"
12018 [(set (match_operand:DI 0 "shiftdi_operand" "")
12019 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12020 (match_operand:QI 2 "nonmemory_operand" "")))
12021 (clobber (reg:CC FLAGS_REG))]
12026 ix86_expand_binary_operator (ROTATE, DImode, operands);
12029 if (!const_1_to_31_operand (operands[2], VOIDmode))
12031 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12035 ;; Implement rotation using two double-precision shift instructions
12036 ;; and a scratch register.
12037 (define_insn_and_split "ix86_rotldi3"
12038 [(set (match_operand:DI 0 "register_operand" "=r")
12039 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12040 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12041 (clobber (reg:CC FLAGS_REG))
12042 (clobber (match_scratch:SI 3 "=&r"))]
12045 "&& reload_completed"
12046 [(set (match_dup 3) (match_dup 4))
12048 [(set (match_dup 4)
12049 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12050 (lshiftrt:SI (match_dup 5)
12051 (minus:QI (const_int 32) (match_dup 2)))))
12052 (clobber (reg:CC FLAGS_REG))])
12054 [(set (match_dup 5)
12055 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12056 (lshiftrt:SI (match_dup 3)
12057 (minus:QI (const_int 32) (match_dup 2)))))
12058 (clobber (reg:CC FLAGS_REG))])]
12059 "split_di (operands, 1, operands + 4, operands + 5);")
12061 (define_insn "*rotlsi3_1_one_bit_rex64"
12062 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12063 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12064 (match_operand:QI 2 "const1_operand" "")))
12065 (clobber (reg:CC FLAGS_REG))]
12066 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12067 && (TARGET_SHIFT1 || optimize_size)"
12069 [(set_attr "type" "rotate")
12070 (set (attr "length")
12071 (if_then_else (match_operand:DI 0 "register_operand" "")
12073 (const_string "*")))])
12075 (define_insn "*rotldi3_1_rex64"
12076 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12077 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12078 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12079 (clobber (reg:CC FLAGS_REG))]
12080 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12082 rol{q}\t{%2, %0|%0, %2}
12083 rol{q}\t{%b2, %0|%0, %b2}"
12084 [(set_attr "type" "rotate")
12085 (set_attr "mode" "DI")])
12087 (define_expand "rotlsi3"
12088 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12089 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12090 (match_operand:QI 2 "nonmemory_operand" "")))
12091 (clobber (reg:CC FLAGS_REG))]
12093 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12095 (define_insn "*rotlsi3_1_one_bit"
12096 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12097 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12098 (match_operand:QI 2 "const1_operand" "")))
12099 (clobber (reg:CC FLAGS_REG))]
12100 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12101 && (TARGET_SHIFT1 || optimize_size)"
12103 [(set_attr "type" "rotate")
12104 (set (attr "length")
12105 (if_then_else (match_operand:SI 0 "register_operand" "")
12107 (const_string "*")))])
12109 (define_insn "*rotlsi3_1_one_bit_zext"
12110 [(set (match_operand:DI 0 "register_operand" "=r")
12112 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12113 (match_operand:QI 2 "const1_operand" ""))))
12114 (clobber (reg:CC FLAGS_REG))]
12115 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12116 && (TARGET_SHIFT1 || optimize_size)"
12118 [(set_attr "type" "rotate")
12119 (set_attr "length" "2")])
12121 (define_insn "*rotlsi3_1"
12122 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12123 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12124 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12125 (clobber (reg:CC FLAGS_REG))]
12126 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12128 rol{l}\t{%2, %0|%0, %2}
12129 rol{l}\t{%b2, %0|%0, %b2}"
12130 [(set_attr "type" "rotate")
12131 (set_attr "mode" "SI")])
12133 (define_insn "*rotlsi3_1_zext"
12134 [(set (match_operand:DI 0 "register_operand" "=r,r")
12136 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12137 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12138 (clobber (reg:CC FLAGS_REG))]
12139 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12141 rol{l}\t{%2, %k0|%k0, %2}
12142 rol{l}\t{%b2, %k0|%k0, %b2}"
12143 [(set_attr "type" "rotate")
12144 (set_attr "mode" "SI")])
12146 (define_expand "rotlhi3"
12147 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12148 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12149 (match_operand:QI 2 "nonmemory_operand" "")))
12150 (clobber (reg:CC FLAGS_REG))]
12151 "TARGET_HIMODE_MATH"
12152 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12154 (define_insn "*rotlhi3_1_one_bit"
12155 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12156 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12157 (match_operand:QI 2 "const1_operand" "")))
12158 (clobber (reg:CC FLAGS_REG))]
12159 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12160 && (TARGET_SHIFT1 || optimize_size)"
12162 [(set_attr "type" "rotate")
12163 (set (attr "length")
12164 (if_then_else (match_operand 0 "register_operand" "")
12166 (const_string "*")))])
12168 (define_insn "*rotlhi3_1"
12169 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12170 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12171 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12172 (clobber (reg:CC FLAGS_REG))]
12173 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12175 rol{w}\t{%2, %0|%0, %2}
12176 rol{w}\t{%b2, %0|%0, %b2}"
12177 [(set_attr "type" "rotate")
12178 (set_attr "mode" "HI")])
12180 (define_expand "rotlqi3"
12181 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12182 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12183 (match_operand:QI 2 "nonmemory_operand" "")))
12184 (clobber (reg:CC FLAGS_REG))]
12185 "TARGET_QIMODE_MATH"
12186 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12188 (define_insn "*rotlqi3_1_one_bit_slp"
12189 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12190 (rotate:QI (match_dup 0)
12191 (match_operand:QI 1 "const1_operand" "")))
12192 (clobber (reg:CC FLAGS_REG))]
12193 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12194 && (TARGET_SHIFT1 || optimize_size)"
12196 [(set_attr "type" "rotate1")
12197 (set (attr "length")
12198 (if_then_else (match_operand 0 "register_operand" "")
12200 (const_string "*")))])
12202 (define_insn "*rotlqi3_1_one_bit"
12203 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12204 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12205 (match_operand:QI 2 "const1_operand" "")))
12206 (clobber (reg:CC FLAGS_REG))]
12207 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12208 && (TARGET_SHIFT1 || optimize_size)"
12210 [(set_attr "type" "rotate")
12211 (set (attr "length")
12212 (if_then_else (match_operand 0 "register_operand" "")
12214 (const_string "*")))])
12216 (define_insn "*rotlqi3_1_slp"
12217 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12218 (rotate:QI (match_dup 0)
12219 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12220 (clobber (reg:CC FLAGS_REG))]
12221 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12222 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12224 rol{b}\t{%1, %0|%0, %1}
12225 rol{b}\t{%b1, %0|%0, %b1}"
12226 [(set_attr "type" "rotate1")
12227 (set_attr "mode" "QI")])
12229 (define_insn "*rotlqi3_1"
12230 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12231 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12232 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12233 (clobber (reg:CC FLAGS_REG))]
12234 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12236 rol{b}\t{%2, %0|%0, %2}
12237 rol{b}\t{%b2, %0|%0, %b2}"
12238 [(set_attr "type" "rotate")
12239 (set_attr "mode" "QI")])
12241 (define_expand "rotrdi3"
12242 [(set (match_operand:DI 0 "shiftdi_operand" "")
12243 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12244 (match_operand:QI 2 "nonmemory_operand" "")))
12245 (clobber (reg:CC FLAGS_REG))]
12250 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12253 if (!const_1_to_31_operand (operands[2], VOIDmode))
12255 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12259 ;; Implement rotation using two double-precision shift instructions
12260 ;; and a scratch register.
12261 (define_insn_and_split "ix86_rotrdi3"
12262 [(set (match_operand:DI 0 "register_operand" "=r")
12263 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12264 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12265 (clobber (reg:CC FLAGS_REG))
12266 (clobber (match_scratch:SI 3 "=&r"))]
12269 "&& reload_completed"
12270 [(set (match_dup 3) (match_dup 4))
12272 [(set (match_dup 4)
12273 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12274 (ashift:SI (match_dup 5)
12275 (minus:QI (const_int 32) (match_dup 2)))))
12276 (clobber (reg:CC FLAGS_REG))])
12278 [(set (match_dup 5)
12279 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12280 (ashift:SI (match_dup 3)
12281 (minus:QI (const_int 32) (match_dup 2)))))
12282 (clobber (reg:CC FLAGS_REG))])]
12283 "split_di (operands, 1, operands + 4, operands + 5);")
12285 (define_insn "*rotrdi3_1_one_bit_rex64"
12286 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12287 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12288 (match_operand:QI 2 "const1_operand" "")))
12289 (clobber (reg:CC FLAGS_REG))]
12290 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12291 && (TARGET_SHIFT1 || optimize_size)"
12293 [(set_attr "type" "rotate")
12294 (set (attr "length")
12295 (if_then_else (match_operand:DI 0 "register_operand" "")
12297 (const_string "*")))])
12299 (define_insn "*rotrdi3_1_rex64"
12300 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12301 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12302 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12303 (clobber (reg:CC FLAGS_REG))]
12304 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12306 ror{q}\t{%2, %0|%0, %2}
12307 ror{q}\t{%b2, %0|%0, %b2}"
12308 [(set_attr "type" "rotate")
12309 (set_attr "mode" "DI")])
12311 (define_expand "rotrsi3"
12312 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12313 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12314 (match_operand:QI 2 "nonmemory_operand" "")))
12315 (clobber (reg:CC FLAGS_REG))]
12317 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12319 (define_insn "*rotrsi3_1_one_bit"
12320 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12321 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12322 (match_operand:QI 2 "const1_operand" "")))
12323 (clobber (reg:CC FLAGS_REG))]
12324 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12325 && (TARGET_SHIFT1 || optimize_size)"
12327 [(set_attr "type" "rotate")
12328 (set (attr "length")
12329 (if_then_else (match_operand:SI 0 "register_operand" "")
12331 (const_string "*")))])
12333 (define_insn "*rotrsi3_1_one_bit_zext"
12334 [(set (match_operand:DI 0 "register_operand" "=r")
12336 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12337 (match_operand:QI 2 "const1_operand" ""))))
12338 (clobber (reg:CC FLAGS_REG))]
12339 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12340 && (TARGET_SHIFT1 || optimize_size)"
12342 [(set_attr "type" "rotate")
12343 (set (attr "length")
12344 (if_then_else (match_operand:SI 0 "register_operand" "")
12346 (const_string "*")))])
12348 (define_insn "*rotrsi3_1"
12349 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12350 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12351 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12352 (clobber (reg:CC FLAGS_REG))]
12353 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12355 ror{l}\t{%2, %0|%0, %2}
12356 ror{l}\t{%b2, %0|%0, %b2}"
12357 [(set_attr "type" "rotate")
12358 (set_attr "mode" "SI")])
12360 (define_insn "*rotrsi3_1_zext"
12361 [(set (match_operand:DI 0 "register_operand" "=r,r")
12363 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12364 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12365 (clobber (reg:CC FLAGS_REG))]
12366 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12368 ror{l}\t{%2, %k0|%k0, %2}
12369 ror{l}\t{%b2, %k0|%k0, %b2}"
12370 [(set_attr "type" "rotate")
12371 (set_attr "mode" "SI")])
12373 (define_expand "rotrhi3"
12374 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12375 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12376 (match_operand:QI 2 "nonmemory_operand" "")))
12377 (clobber (reg:CC FLAGS_REG))]
12378 "TARGET_HIMODE_MATH"
12379 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12381 (define_insn "*rotrhi3_one_bit"
12382 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12383 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384 (match_operand:QI 2 "const1_operand" "")))
12385 (clobber (reg:CC FLAGS_REG))]
12386 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12387 && (TARGET_SHIFT1 || optimize_size)"
12389 [(set_attr "type" "rotate")
12390 (set (attr "length")
12391 (if_then_else (match_operand 0 "register_operand" "")
12393 (const_string "*")))])
12395 (define_insn "*rotrhi3"
12396 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12397 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12398 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12399 (clobber (reg:CC FLAGS_REG))]
12400 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12402 ror{w}\t{%2, %0|%0, %2}
12403 ror{w}\t{%b2, %0|%0, %b2}"
12404 [(set_attr "type" "rotate")
12405 (set_attr "mode" "HI")])
12407 (define_expand "rotrqi3"
12408 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12409 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12410 (match_operand:QI 2 "nonmemory_operand" "")))
12411 (clobber (reg:CC FLAGS_REG))]
12412 "TARGET_QIMODE_MATH"
12413 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12415 (define_insn "*rotrqi3_1_one_bit"
12416 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12417 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12418 (match_operand:QI 2 "const1_operand" "")))
12419 (clobber (reg:CC FLAGS_REG))]
12420 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12421 && (TARGET_SHIFT1 || optimize_size)"
12423 [(set_attr "type" "rotate")
12424 (set (attr "length")
12425 (if_then_else (match_operand 0 "register_operand" "")
12427 (const_string "*")))])
12429 (define_insn "*rotrqi3_1_one_bit_slp"
12430 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12431 (rotatert:QI (match_dup 0)
12432 (match_operand:QI 1 "const1_operand" "")))
12433 (clobber (reg:CC FLAGS_REG))]
12434 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12435 && (TARGET_SHIFT1 || optimize_size)"
12437 [(set_attr "type" "rotate1")
12438 (set (attr "length")
12439 (if_then_else (match_operand 0 "register_operand" "")
12441 (const_string "*")))])
12443 (define_insn "*rotrqi3_1"
12444 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12445 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12446 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12447 (clobber (reg:CC FLAGS_REG))]
12448 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12450 ror{b}\t{%2, %0|%0, %2}
12451 ror{b}\t{%b2, %0|%0, %b2}"
12452 [(set_attr "type" "rotate")
12453 (set_attr "mode" "QI")])
12455 (define_insn "*rotrqi3_1_slp"
12456 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12457 (rotatert:QI (match_dup 0)
12458 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12459 (clobber (reg:CC FLAGS_REG))]
12460 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12461 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12463 ror{b}\t{%1, %0|%0, %1}
12464 ror{b}\t{%b1, %0|%0, %b1}"
12465 [(set_attr "type" "rotate1")
12466 (set_attr "mode" "QI")])
12468 ;; Bit set / bit test instructions
12470 (define_expand "extv"
12471 [(set (match_operand:SI 0 "register_operand" "")
12472 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12473 (match_operand:SI 2 "immediate_operand" "")
12474 (match_operand:SI 3 "immediate_operand" "")))]
12477 /* Handle extractions from %ah et al. */
12478 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12481 /* From mips.md: extract_bit_field doesn't verify that our source
12482 matches the predicate, so check it again here. */
12483 if (! ext_register_operand (operands[1], VOIDmode))
12487 (define_expand "extzv"
12488 [(set (match_operand:SI 0 "register_operand" "")
12489 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12490 (match_operand:SI 2 "immediate_operand" "")
12491 (match_operand:SI 3 "immediate_operand" "")))]
12494 /* Handle extractions from %ah et al. */
12495 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12498 /* From mips.md: extract_bit_field doesn't verify that our source
12499 matches the predicate, so check it again here. */
12500 if (! ext_register_operand (operands[1], VOIDmode))
12504 (define_expand "insv"
12505 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12506 (match_operand 1 "immediate_operand" "")
12507 (match_operand 2 "immediate_operand" ""))
12508 (match_operand 3 "register_operand" ""))]
12511 /* Handle extractions from %ah et al. */
12512 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12515 /* From mips.md: insert_bit_field doesn't verify that our source
12516 matches the predicate, so check it again here. */
12517 if (! ext_register_operand (operands[0], VOIDmode))
12521 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12523 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12528 ;; %%% bts, btr, btc, bt.
12529 ;; In general these instructions are *slow* when applied to memory,
12530 ;; since they enforce atomic operation. When applied to registers,
12531 ;; it depends on the cpu implementation. They're never faster than
12532 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12533 ;; no point. But in 64-bit, we can't hold the relevant immediates
12534 ;; within the instruction itself, so operating on bits in the high
12535 ;; 32-bits of a register becomes easier.
12537 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12538 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12539 ;; negdf respectively, so they can never be disabled entirely.
12541 (define_insn "*btsq"
12542 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12544 (match_operand:DI 1 "const_0_to_63_operand" ""))
12546 (clobber (reg:CC FLAGS_REG))]
12547 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12549 [(set_attr "type" "alu1")])
12551 (define_insn "*btrq"
12552 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12554 (match_operand:DI 1 "const_0_to_63_operand" ""))
12556 (clobber (reg:CC FLAGS_REG))]
12557 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12559 [(set_attr "type" "alu1")])
12561 (define_insn "*btcq"
12562 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12564 (match_operand:DI 1 "const_0_to_63_operand" ""))
12565 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12566 (clobber (reg:CC FLAGS_REG))]
12567 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12569 [(set_attr "type" "alu1")])
12571 ;; Allow Nocona to avoid these instructions if a register is available.
12574 [(match_scratch:DI 2 "r")
12575 (parallel [(set (zero_extract:DI
12576 (match_operand:DI 0 "register_operand" "")
12578 (match_operand:DI 1 "const_0_to_63_operand" ""))
12580 (clobber (reg:CC FLAGS_REG))])]
12581 "TARGET_64BIT && !TARGET_USE_BT"
12584 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12587 if (HOST_BITS_PER_WIDE_INT >= 64)
12588 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12589 else if (i < HOST_BITS_PER_WIDE_INT)
12590 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12592 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12594 op1 = immed_double_const (lo, hi, DImode);
12597 emit_move_insn (operands[2], op1);
12601 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12606 [(match_scratch:DI 2 "r")
12607 (parallel [(set (zero_extract:DI
12608 (match_operand:DI 0 "register_operand" "")
12610 (match_operand:DI 1 "const_0_to_63_operand" ""))
12612 (clobber (reg:CC FLAGS_REG))])]
12613 "TARGET_64BIT && !TARGET_USE_BT"
12616 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12619 if (HOST_BITS_PER_WIDE_INT >= 64)
12620 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12621 else if (i < HOST_BITS_PER_WIDE_INT)
12622 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12624 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12626 op1 = immed_double_const (~lo, ~hi, DImode);
12629 emit_move_insn (operands[2], op1);
12633 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12638 [(match_scratch:DI 2 "r")
12639 (parallel [(set (zero_extract:DI
12640 (match_operand:DI 0 "register_operand" "")
12642 (match_operand:DI 1 "const_0_to_63_operand" ""))
12643 (not:DI (zero_extract:DI
12644 (match_dup 0) (const_int 1) (match_dup 1))))
12645 (clobber (reg:CC FLAGS_REG))])]
12646 "TARGET_64BIT && !TARGET_USE_BT"
12649 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12652 if (HOST_BITS_PER_WIDE_INT >= 64)
12653 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654 else if (i < HOST_BITS_PER_WIDE_INT)
12655 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12657 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12659 op1 = immed_double_const (lo, hi, DImode);
12662 emit_move_insn (operands[2], op1);
12666 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12670 ;; Store-flag instructions.
12672 ;; For all sCOND expanders, also expand the compare or test insn that
12673 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12675 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12676 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12677 ;; way, which can later delete the movzx if only QImode is needed.
12679 (define_expand "seq"
12680 [(set (match_operand:QI 0 "register_operand" "")
12681 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12683 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12685 (define_expand "sne"
12686 [(set (match_operand:QI 0 "register_operand" "")
12687 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12689 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12691 (define_expand "sgt"
12692 [(set (match_operand:QI 0 "register_operand" "")
12693 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12695 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12697 (define_expand "sgtu"
12698 [(set (match_operand:QI 0 "register_operand" "")
12699 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12701 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12703 (define_expand "slt"
12704 [(set (match_operand:QI 0 "register_operand" "")
12705 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12707 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12709 (define_expand "sltu"
12710 [(set (match_operand:QI 0 "register_operand" "")
12711 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12713 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12715 (define_expand "sge"
12716 [(set (match_operand:QI 0 "register_operand" "")
12717 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12719 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12721 (define_expand "sgeu"
12722 [(set (match_operand:QI 0 "register_operand" "")
12723 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12725 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12727 (define_expand "sle"
12728 [(set (match_operand:QI 0 "register_operand" "")
12729 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12731 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12733 (define_expand "sleu"
12734 [(set (match_operand:QI 0 "register_operand" "")
12735 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12737 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12739 (define_expand "sunordered"
12740 [(set (match_operand:QI 0 "register_operand" "")
12741 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12742 "TARGET_80387 || TARGET_SSE"
12743 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12745 (define_expand "sordered"
12746 [(set (match_operand:QI 0 "register_operand" "")
12747 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12749 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12751 (define_expand "suneq"
12752 [(set (match_operand:QI 0 "register_operand" "")
12753 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12754 "TARGET_80387 || TARGET_SSE"
12755 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12757 (define_expand "sunge"
12758 [(set (match_operand:QI 0 "register_operand" "")
12759 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12760 "TARGET_80387 || TARGET_SSE"
12761 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12763 (define_expand "sungt"
12764 [(set (match_operand:QI 0 "register_operand" "")
12765 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12766 "TARGET_80387 || TARGET_SSE"
12767 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12769 (define_expand "sunle"
12770 [(set (match_operand:QI 0 "register_operand" "")
12771 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12772 "TARGET_80387 || TARGET_SSE"
12773 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12775 (define_expand "sunlt"
12776 [(set (match_operand:QI 0 "register_operand" "")
12777 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12778 "TARGET_80387 || TARGET_SSE"
12779 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12781 (define_expand "sltgt"
12782 [(set (match_operand:QI 0 "register_operand" "")
12783 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12784 "TARGET_80387 || TARGET_SSE"
12785 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12787 (define_insn "*setcc_1"
12788 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12789 (match_operator:QI 1 "ix86_comparison_operator"
12790 [(reg FLAGS_REG) (const_int 0)]))]
12793 [(set_attr "type" "setcc")
12794 (set_attr "mode" "QI")])
12796 (define_insn "*setcc_2"
12797 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12798 (match_operator:QI 1 "ix86_comparison_operator"
12799 [(reg FLAGS_REG) (const_int 0)]))]
12802 [(set_attr "type" "setcc")
12803 (set_attr "mode" "QI")])
12805 ;; In general it is not safe to assume too much about CCmode registers,
12806 ;; so simplify-rtx stops when it sees a second one. Under certain
12807 ;; conditions this is safe on x86, so help combine not create
12814 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12815 (ne:QI (match_operator 1 "ix86_comparison_operator"
12816 [(reg FLAGS_REG) (const_int 0)])
12819 [(set (match_dup 0) (match_dup 1))]
12821 PUT_MODE (operands[1], QImode);
12825 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12826 (ne:QI (match_operator 1 "ix86_comparison_operator"
12827 [(reg FLAGS_REG) (const_int 0)])
12830 [(set (match_dup 0) (match_dup 1))]
12832 PUT_MODE (operands[1], QImode);
12836 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12837 (eq:QI (match_operator 1 "ix86_comparison_operator"
12838 [(reg FLAGS_REG) (const_int 0)])
12841 [(set (match_dup 0) (match_dup 1))]
12843 rtx new_op1 = copy_rtx (operands[1]);
12844 operands[1] = new_op1;
12845 PUT_MODE (new_op1, QImode);
12846 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12847 GET_MODE (XEXP (new_op1, 0))));
12849 /* Make sure that (a) the CCmode we have for the flags is strong
12850 enough for the reversed compare or (b) we have a valid FP compare. */
12851 if (! ix86_comparison_operator (new_op1, VOIDmode))
12856 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12857 (eq:QI (match_operator 1 "ix86_comparison_operator"
12858 [(reg FLAGS_REG) (const_int 0)])
12861 [(set (match_dup 0) (match_dup 1))]
12863 rtx new_op1 = copy_rtx (operands[1]);
12864 operands[1] = new_op1;
12865 PUT_MODE (new_op1, QImode);
12866 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12867 GET_MODE (XEXP (new_op1, 0))));
12869 /* Make sure that (a) the CCmode we have for the flags is strong
12870 enough for the reversed compare or (b) we have a valid FP compare. */
12871 if (! ix86_comparison_operator (new_op1, VOIDmode))
12875 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12876 ;; subsequent logical operations are used to imitate conditional moves.
12877 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12880 (define_insn "*sse_setccsf"
12881 [(set (match_operand:SF 0 "register_operand" "=x")
12882 (match_operator:SF 1 "sse_comparison_operator"
12883 [(match_operand:SF 2 "register_operand" "0")
12884 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12886 "cmp%D1ss\t{%3, %0|%0, %3}"
12887 [(set_attr "type" "ssecmp")
12888 (set_attr "mode" "SF")])
12890 (define_insn "*sse_setccdf"
12891 [(set (match_operand:DF 0 "register_operand" "=Y")
12892 (match_operator:DF 1 "sse_comparison_operator"
12893 [(match_operand:DF 2 "register_operand" "0")
12894 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12896 "cmp%D1sd\t{%3, %0|%0, %3}"
12897 [(set_attr "type" "ssecmp")
12898 (set_attr "mode" "DF")])
12900 ;; Basic conditional jump instructions.
12901 ;; We ignore the overflow flag for signed branch instructions.
12903 ;; For all bCOND expanders, also expand the compare or test insn that
12904 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12906 (define_expand "beq"
12908 (if_then_else (match_dup 1)
12909 (label_ref (match_operand 0 "" ""))
12912 "ix86_expand_branch (EQ, operands[0]); DONE;")
12914 (define_expand "bne"
12916 (if_then_else (match_dup 1)
12917 (label_ref (match_operand 0 "" ""))
12920 "ix86_expand_branch (NE, operands[0]); DONE;")
12922 (define_expand "bgt"
12924 (if_then_else (match_dup 1)
12925 (label_ref (match_operand 0 "" ""))
12928 "ix86_expand_branch (GT, operands[0]); DONE;")
12930 (define_expand "bgtu"
12932 (if_then_else (match_dup 1)
12933 (label_ref (match_operand 0 "" ""))
12936 "ix86_expand_branch (GTU, operands[0]); DONE;")
12938 (define_expand "blt"
12940 (if_then_else (match_dup 1)
12941 (label_ref (match_operand 0 "" ""))
12944 "ix86_expand_branch (LT, operands[0]); DONE;")
12946 (define_expand "bltu"
12948 (if_then_else (match_dup 1)
12949 (label_ref (match_operand 0 "" ""))
12952 "ix86_expand_branch (LTU, operands[0]); DONE;")
12954 (define_expand "bge"
12956 (if_then_else (match_dup 1)
12957 (label_ref (match_operand 0 "" ""))
12960 "ix86_expand_branch (GE, operands[0]); DONE;")
12962 (define_expand "bgeu"
12964 (if_then_else (match_dup 1)
12965 (label_ref (match_operand 0 "" ""))
12968 "ix86_expand_branch (GEU, operands[0]); DONE;")
12970 (define_expand "ble"
12972 (if_then_else (match_dup 1)
12973 (label_ref (match_operand 0 "" ""))
12976 "ix86_expand_branch (LE, operands[0]); DONE;")
12978 (define_expand "bleu"
12980 (if_then_else (match_dup 1)
12981 (label_ref (match_operand 0 "" ""))
12984 "ix86_expand_branch (LEU, operands[0]); DONE;")
12986 (define_expand "bunordered"
12988 (if_then_else (match_dup 1)
12989 (label_ref (match_operand 0 "" ""))
12991 "TARGET_80387 || TARGET_SSE_MATH"
12992 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12994 (define_expand "bordered"
12996 (if_then_else (match_dup 1)
12997 (label_ref (match_operand 0 "" ""))
12999 "TARGET_80387 || TARGET_SSE_MATH"
13000 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13002 (define_expand "buneq"
13004 (if_then_else (match_dup 1)
13005 (label_ref (match_operand 0 "" ""))
13007 "TARGET_80387 || TARGET_SSE_MATH"
13008 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13010 (define_expand "bunge"
13012 (if_then_else (match_dup 1)
13013 (label_ref (match_operand 0 "" ""))
13015 "TARGET_80387 || TARGET_SSE_MATH"
13016 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13018 (define_expand "bungt"
13020 (if_then_else (match_dup 1)
13021 (label_ref (match_operand 0 "" ""))
13023 "TARGET_80387 || TARGET_SSE_MATH"
13024 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13026 (define_expand "bunle"
13028 (if_then_else (match_dup 1)
13029 (label_ref (match_operand 0 "" ""))
13031 "TARGET_80387 || TARGET_SSE_MATH"
13032 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13034 (define_expand "bunlt"
13036 (if_then_else (match_dup 1)
13037 (label_ref (match_operand 0 "" ""))
13039 "TARGET_80387 || TARGET_SSE_MATH"
13040 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13042 (define_expand "bltgt"
13044 (if_then_else (match_dup 1)
13045 (label_ref (match_operand 0 "" ""))
13047 "TARGET_80387 || TARGET_SSE_MATH"
13048 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13050 (define_insn "*jcc_1"
13052 (if_then_else (match_operator 1 "ix86_comparison_operator"
13053 [(reg FLAGS_REG) (const_int 0)])
13054 (label_ref (match_operand 0 "" ""))
13058 [(set_attr "type" "ibr")
13059 (set_attr "modrm" "0")
13060 (set (attr "length")
13061 (if_then_else (and (ge (minus (match_dup 0) (pc))
13063 (lt (minus (match_dup 0) (pc))
13068 (define_insn "*jcc_2"
13070 (if_then_else (match_operator 1 "ix86_comparison_operator"
13071 [(reg FLAGS_REG) (const_int 0)])
13073 (label_ref (match_operand 0 "" ""))))]
13076 [(set_attr "type" "ibr")
13077 (set_attr "modrm" "0")
13078 (set (attr "length")
13079 (if_then_else (and (ge (minus (match_dup 0) (pc))
13081 (lt (minus (match_dup 0) (pc))
13086 ;; In general it is not safe to assume too much about CCmode registers,
13087 ;; so simplify-rtx stops when it sees a second one. Under certain
13088 ;; conditions this is safe on x86, so help combine not create
13096 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13097 [(reg FLAGS_REG) (const_int 0)])
13099 (label_ref (match_operand 1 "" ""))
13103 (if_then_else (match_dup 0)
13104 (label_ref (match_dup 1))
13107 PUT_MODE (operands[0], VOIDmode);
13112 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13113 [(reg FLAGS_REG) (const_int 0)])
13115 (label_ref (match_operand 1 "" ""))
13119 (if_then_else (match_dup 0)
13120 (label_ref (match_dup 1))
13123 rtx new_op0 = copy_rtx (operands[0]);
13124 operands[0] = new_op0;
13125 PUT_MODE (new_op0, VOIDmode);
13126 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13127 GET_MODE (XEXP (new_op0, 0))));
13129 /* Make sure that (a) the CCmode we have for the flags is strong
13130 enough for the reversed compare or (b) we have a valid FP compare. */
13131 if (! ix86_comparison_operator (new_op0, VOIDmode))
13135 ;; Define combination compare-and-branch fp compare instructions to use
13136 ;; during early optimization. Splitting the operation apart early makes
13137 ;; for bad code when we want to reverse the operation.
13139 (define_insn "*fp_jcc_1_mixed"
13141 (if_then_else (match_operator 0 "comparison_operator"
13142 [(match_operand 1 "register_operand" "f#x,x#f")
13143 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13144 (label_ref (match_operand 3 "" ""))
13146 (clobber (reg:CCFP FPSR_REG))
13147 (clobber (reg:CCFP FLAGS_REG))]
13148 "TARGET_MIX_SSE_I387
13149 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13150 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13151 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13154 (define_insn "*fp_jcc_1_sse"
13156 (if_then_else (match_operator 0 "comparison_operator"
13157 [(match_operand 1 "register_operand" "x")
13158 (match_operand 2 "nonimmediate_operand" "xm")])
13159 (label_ref (match_operand 3 "" ""))
13161 (clobber (reg:CCFP FPSR_REG))
13162 (clobber (reg:CCFP FLAGS_REG))]
13164 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13165 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13166 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13169 (define_insn "*fp_jcc_1_387"
13171 (if_then_else (match_operator 0 "comparison_operator"
13172 [(match_operand 1 "register_operand" "f")
13173 (match_operand 2 "register_operand" "f")])
13174 (label_ref (match_operand 3 "" ""))
13176 (clobber (reg:CCFP FPSR_REG))
13177 (clobber (reg:CCFP FLAGS_REG))]
13178 "TARGET_CMOVE && TARGET_80387
13179 && FLOAT_MODE_P (GET_MODE (operands[1]))
13180 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13181 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13184 (define_insn "*fp_jcc_2_mixed"
13186 (if_then_else (match_operator 0 "comparison_operator"
13187 [(match_operand 1 "register_operand" "f#x,x#f")
13188 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13190 (label_ref (match_operand 3 "" ""))))
13191 (clobber (reg:CCFP FPSR_REG))
13192 (clobber (reg:CCFP FLAGS_REG))]
13193 "TARGET_MIX_SSE_I387
13194 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13195 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13196 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13199 (define_insn "*fp_jcc_2_sse"
13201 (if_then_else (match_operator 0 "comparison_operator"
13202 [(match_operand 1 "register_operand" "x")
13203 (match_operand 2 "nonimmediate_operand" "xm")])
13205 (label_ref (match_operand 3 "" ""))))
13206 (clobber (reg:CCFP FPSR_REG))
13207 (clobber (reg:CCFP FLAGS_REG))]
13209 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13210 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13211 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13214 (define_insn "*fp_jcc_2_387"
13216 (if_then_else (match_operator 0 "comparison_operator"
13217 [(match_operand 1 "register_operand" "f")
13218 (match_operand 2 "register_operand" "f")])
13220 (label_ref (match_operand 3 "" ""))))
13221 (clobber (reg:CCFP FPSR_REG))
13222 (clobber (reg:CCFP FLAGS_REG))]
13223 "TARGET_CMOVE && TARGET_80387
13224 && FLOAT_MODE_P (GET_MODE (operands[1]))
13225 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13226 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13229 (define_insn "*fp_jcc_3_387"
13231 (if_then_else (match_operator 0 "comparison_operator"
13232 [(match_operand 1 "register_operand" "f")
13233 (match_operand 2 "nonimmediate_operand" "fm")])
13234 (label_ref (match_operand 3 "" ""))
13236 (clobber (reg:CCFP FPSR_REG))
13237 (clobber (reg:CCFP FLAGS_REG))
13238 (clobber (match_scratch:HI 4 "=a"))]
13240 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13241 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13242 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13243 && SELECT_CC_MODE (GET_CODE (operands[0]),
13244 operands[1], operands[2]) == CCFPmode
13245 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13248 (define_insn "*fp_jcc_4_387"
13250 (if_then_else (match_operator 0 "comparison_operator"
13251 [(match_operand 1 "register_operand" "f")
13252 (match_operand 2 "nonimmediate_operand" "fm")])
13254 (label_ref (match_operand 3 "" ""))))
13255 (clobber (reg:CCFP FPSR_REG))
13256 (clobber (reg:CCFP FLAGS_REG))
13257 (clobber (match_scratch:HI 4 "=a"))]
13259 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13260 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13261 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13262 && SELECT_CC_MODE (GET_CODE (operands[0]),
13263 operands[1], operands[2]) == CCFPmode
13264 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13267 (define_insn "*fp_jcc_5_387"
13269 (if_then_else (match_operator 0 "comparison_operator"
13270 [(match_operand 1 "register_operand" "f")
13271 (match_operand 2 "register_operand" "f")])
13272 (label_ref (match_operand 3 "" ""))
13274 (clobber (reg:CCFP FPSR_REG))
13275 (clobber (reg:CCFP FLAGS_REG))
13276 (clobber (match_scratch:HI 4 "=a"))]
13278 && FLOAT_MODE_P (GET_MODE (operands[1]))
13279 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13280 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13283 (define_insn "*fp_jcc_6_387"
13285 (if_then_else (match_operator 0 "comparison_operator"
13286 [(match_operand 1 "register_operand" "f")
13287 (match_operand 2 "register_operand" "f")])
13289 (label_ref (match_operand 3 "" ""))))
13290 (clobber (reg:CCFP FPSR_REG))
13291 (clobber (reg:CCFP FLAGS_REG))
13292 (clobber (match_scratch:HI 4 "=a"))]
13294 && FLOAT_MODE_P (GET_MODE (operands[1]))
13295 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13296 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13299 (define_insn "*fp_jcc_7_387"
13301 (if_then_else (match_operator 0 "comparison_operator"
13302 [(match_operand 1 "register_operand" "f")
13303 (match_operand 2 "const0_operand" "X")])
13304 (label_ref (match_operand 3 "" ""))
13306 (clobber (reg:CCFP FPSR_REG))
13307 (clobber (reg:CCFP FLAGS_REG))
13308 (clobber (match_scratch:HI 4 "=a"))]
13310 && FLOAT_MODE_P (GET_MODE (operands[1]))
13311 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13312 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13313 && SELECT_CC_MODE (GET_CODE (operands[0]),
13314 operands[1], operands[2]) == CCFPmode
13315 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13318 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13319 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13320 ;; with a precedence over other operators and is always put in the first
13321 ;; place. Swap condition and operands to match ficom instruction.
13323 (define_insn "*fp_jcc_8<mode>_387"
13325 (if_then_else (match_operator 0 "comparison_operator"
13326 [(match_operator 1 "float_operator"
13327 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13328 (match_operand 3 "register_operand" "f,f")])
13329 (label_ref (match_operand 4 "" ""))
13331 (clobber (reg:CCFP FPSR_REG))
13332 (clobber (reg:CCFP FLAGS_REG))
13333 (clobber (match_scratch:HI 5 "=a,a"))]
13334 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13335 && FLOAT_MODE_P (GET_MODE (operands[3]))
13336 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13337 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13338 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13339 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13344 (if_then_else (match_operator 0 "comparison_operator"
13345 [(match_operand 1 "register_operand" "")
13346 (match_operand 2 "nonimmediate_operand" "")])
13347 (match_operand 3 "" "")
13348 (match_operand 4 "" "")))
13349 (clobber (reg:CCFP FPSR_REG))
13350 (clobber (reg:CCFP FLAGS_REG))]
13354 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13355 operands[3], operands[4], NULL_RTX, NULL_RTX);
13361 (if_then_else (match_operator 0 "comparison_operator"
13362 [(match_operand 1 "register_operand" "")
13363 (match_operand 2 "general_operand" "")])
13364 (match_operand 3 "" "")
13365 (match_operand 4 "" "")))
13366 (clobber (reg:CCFP FPSR_REG))
13367 (clobber (reg:CCFP FLAGS_REG))
13368 (clobber (match_scratch:HI 5 "=a"))]
13372 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13373 operands[3], operands[4], operands[5], NULL_RTX);
13379 (if_then_else (match_operator 0 "comparison_operator"
13380 [(match_operator 1 "float_operator"
13381 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13382 (match_operand 3 "register_operand" "")])
13383 (match_operand 4 "" "")
13384 (match_operand 5 "" "")))
13385 (clobber (reg:CCFP FPSR_REG))
13386 (clobber (reg:CCFP FLAGS_REG))
13387 (clobber (match_scratch:HI 6 "=a"))]
13391 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13392 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13393 operands[3], operands[7],
13394 operands[4], operands[5], operands[6], NULL_RTX);
13398 ;; %%% Kill this when reload knows how to do it.
13401 (if_then_else (match_operator 0 "comparison_operator"
13402 [(match_operator 1 "float_operator"
13403 [(match_operand:X87MODEI12 2 "register_operand" "")])
13404 (match_operand 3 "register_operand" "")])
13405 (match_operand 4 "" "")
13406 (match_operand 5 "" "")))
13407 (clobber (reg:CCFP FPSR_REG))
13408 (clobber (reg:CCFP FLAGS_REG))
13409 (clobber (match_scratch:HI 6 "=a"))]
13413 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13414 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13415 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13416 operands[3], operands[7],
13417 operands[4], operands[5], operands[6], operands[2]);
13421 ;; Unconditional and other jump instructions
13423 (define_insn "jump"
13425 (label_ref (match_operand 0 "" "")))]
13428 [(set_attr "type" "ibr")
13429 (set (attr "length")
13430 (if_then_else (and (ge (minus (match_dup 0) (pc))
13432 (lt (minus (match_dup 0) (pc))
13436 (set_attr "modrm" "0")])
13438 (define_expand "indirect_jump"
13439 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13443 (define_insn "*indirect_jump"
13444 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13447 [(set_attr "type" "ibr")
13448 (set_attr "length_immediate" "0")])
13450 (define_insn "*indirect_jump_rtx64"
13451 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13454 [(set_attr "type" "ibr")
13455 (set_attr "length_immediate" "0")])
13457 (define_expand "tablejump"
13458 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13459 (use (label_ref (match_operand 1 "" "")))])]
13462 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13463 relative. Convert the relative address to an absolute address. */
13467 enum rtx_code code;
13473 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13475 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13479 op1 = pic_offset_table_rtx;
13484 op0 = pic_offset_table_rtx;
13488 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13493 (define_insn "*tablejump_1"
13494 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13495 (use (label_ref (match_operand 1 "" "")))]
13498 [(set_attr "type" "ibr")
13499 (set_attr "length_immediate" "0")])
13501 (define_insn "*tablejump_1_rtx64"
13502 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13503 (use (label_ref (match_operand 1 "" "")))]
13506 [(set_attr "type" "ibr")
13507 (set_attr "length_immediate" "0")])
13509 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13512 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13513 (set (match_operand:QI 1 "register_operand" "")
13514 (match_operator:QI 2 "ix86_comparison_operator"
13515 [(reg FLAGS_REG) (const_int 0)]))
13516 (set (match_operand 3 "q_regs_operand" "")
13517 (zero_extend (match_dup 1)))]
13518 "(peep2_reg_dead_p (3, operands[1])
13519 || operands_match_p (operands[1], operands[3]))
13520 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13521 [(set (match_dup 4) (match_dup 0))
13522 (set (strict_low_part (match_dup 5))
13525 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13526 operands[5] = gen_lowpart (QImode, operands[3]);
13527 ix86_expand_clear (operands[3]);
13530 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13533 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13534 (set (match_operand:QI 1 "register_operand" "")
13535 (match_operator:QI 2 "ix86_comparison_operator"
13536 [(reg FLAGS_REG) (const_int 0)]))
13537 (parallel [(set (match_operand 3 "q_regs_operand" "")
13538 (zero_extend (match_dup 1)))
13539 (clobber (reg:CC FLAGS_REG))])]
13540 "(peep2_reg_dead_p (3, operands[1])
13541 || operands_match_p (operands[1], operands[3]))
13542 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13543 [(set (match_dup 4) (match_dup 0))
13544 (set (strict_low_part (match_dup 5))
13547 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13548 operands[5] = gen_lowpart (QImode, operands[3]);
13549 ix86_expand_clear (operands[3]);
13552 ;; Call instructions.
13554 ;; The predicates normally associated with named expanders are not properly
13555 ;; checked for calls. This is a bug in the generic code, but it isn't that
13556 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13558 ;; Call subroutine returning no value.
13560 (define_expand "call_pop"
13561 [(parallel [(call (match_operand:QI 0 "" "")
13562 (match_operand:SI 1 "" ""))
13563 (set (reg:SI SP_REG)
13564 (plus:SI (reg:SI SP_REG)
13565 (match_operand:SI 3 "" "")))])]
13568 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13572 (define_insn "*call_pop_0"
13573 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13574 (match_operand:SI 1 "" ""))
13575 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13576 (match_operand:SI 2 "immediate_operand" "")))]
13579 if (SIBLING_CALL_P (insn))
13582 return "call\t%P0";
13584 [(set_attr "type" "call")])
13586 (define_insn "*call_pop_1"
13587 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13588 (match_operand:SI 1 "" ""))
13589 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13590 (match_operand:SI 2 "immediate_operand" "i")))]
13593 if (constant_call_address_operand (operands[0], Pmode))
13595 if (SIBLING_CALL_P (insn))
13598 return "call\t%P0";
13600 if (SIBLING_CALL_P (insn))
13603 return "call\t%A0";
13605 [(set_attr "type" "call")])
13607 (define_expand "call"
13608 [(call (match_operand:QI 0 "" "")
13609 (match_operand 1 "" ""))
13610 (use (match_operand 2 "" ""))]
13613 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13617 (define_expand "sibcall"
13618 [(call (match_operand:QI 0 "" "")
13619 (match_operand 1 "" ""))
13620 (use (match_operand 2 "" ""))]
13623 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13627 (define_insn "*call_0"
13628 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13629 (match_operand 1 "" ""))]
13632 if (SIBLING_CALL_P (insn))
13635 return "call\t%P0";
13637 [(set_attr "type" "call")])
13639 (define_insn "*call_1"
13640 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13641 (match_operand 1 "" ""))]
13642 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13644 if (constant_call_address_operand (operands[0], Pmode))
13645 return "call\t%P0";
13646 return "call\t%A0";
13648 [(set_attr "type" "call")])
13650 (define_insn "*sibcall_1"
13651 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13652 (match_operand 1 "" ""))]
13653 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13655 if (constant_call_address_operand (operands[0], Pmode))
13659 [(set_attr "type" "call")])
13661 (define_insn "*call_1_rex64"
13662 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13663 (match_operand 1 "" ""))]
13664 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13666 if (constant_call_address_operand (operands[0], Pmode))
13667 return "call\t%P0";
13668 return "call\t%A0";
13670 [(set_attr "type" "call")])
13672 (define_insn "*sibcall_1_rex64"
13673 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13674 (match_operand 1 "" ""))]
13675 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13677 [(set_attr "type" "call")])
13679 (define_insn "*sibcall_1_rex64_v"
13680 [(call (mem:QI (reg:DI 40))
13681 (match_operand 0 "" ""))]
13682 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13684 [(set_attr "type" "call")])
13687 ;; Call subroutine, returning value in operand 0
13689 (define_expand "call_value_pop"
13690 [(parallel [(set (match_operand 0 "" "")
13691 (call (match_operand:QI 1 "" "")
13692 (match_operand:SI 2 "" "")))
13693 (set (reg:SI SP_REG)
13694 (plus:SI (reg:SI SP_REG)
13695 (match_operand:SI 4 "" "")))])]
13698 ix86_expand_call (operands[0], operands[1], operands[2],
13699 operands[3], operands[4], 0);
13703 (define_expand "call_value"
13704 [(set (match_operand 0 "" "")
13705 (call (match_operand:QI 1 "" "")
13706 (match_operand:SI 2 "" "")))
13707 (use (match_operand:SI 3 "" ""))]
13708 ;; Operand 2 not used on the i386.
13711 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13715 (define_expand "sibcall_value"
13716 [(set (match_operand 0 "" "")
13717 (call (match_operand:QI 1 "" "")
13718 (match_operand:SI 2 "" "")))
13719 (use (match_operand:SI 3 "" ""))]
13720 ;; Operand 2 not used on the i386.
13723 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13727 ;; Call subroutine returning any type.
13729 (define_expand "untyped_call"
13730 [(parallel [(call (match_operand 0 "" "")
13732 (match_operand 1 "" "")
13733 (match_operand 2 "" "")])]
13738 /* In order to give reg-stack an easier job in validating two
13739 coprocessor registers as containing a possible return value,
13740 simply pretend the untyped call returns a complex long double
13743 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13744 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13745 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13748 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13750 rtx set = XVECEXP (operands[2], 0, i);
13751 emit_move_insn (SET_DEST (set), SET_SRC (set));
13754 /* The optimizer does not know that the call sets the function value
13755 registers we stored in the result block. We avoid problems by
13756 claiming that all hard registers are used and clobbered at this
13758 emit_insn (gen_blockage (const0_rtx));
13763 ;; Prologue and epilogue instructions
13765 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13766 ;; all of memory. This blocks insns from being moved across this point.
13768 (define_insn "blockage"
13769 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13772 [(set_attr "length" "0")])
13774 ;; Insn emitted into the body of a function to return from a function.
13775 ;; This is only done if the function's epilogue is known to be simple.
13776 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13778 (define_expand "return"
13780 "ix86_can_use_return_insn_p ()"
13782 if (current_function_pops_args)
13784 rtx popc = GEN_INT (current_function_pops_args);
13785 emit_jump_insn (gen_return_pop_internal (popc));
13790 (define_insn "return_internal"
13794 [(set_attr "length" "1")
13795 (set_attr "length_immediate" "0")
13796 (set_attr "modrm" "0")])
13798 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13799 ;; instruction Athlon and K8 have.
13801 (define_insn "return_internal_long"
13803 (unspec [(const_int 0)] UNSPEC_REP)]
13806 [(set_attr "length" "1")
13807 (set_attr "length_immediate" "0")
13808 (set_attr "prefix_rep" "1")
13809 (set_attr "modrm" "0")])
13811 (define_insn "return_pop_internal"
13813 (use (match_operand:SI 0 "const_int_operand" ""))]
13816 [(set_attr "length" "3")
13817 (set_attr "length_immediate" "2")
13818 (set_attr "modrm" "0")])
13820 (define_insn "return_indirect_internal"
13822 (use (match_operand:SI 0 "register_operand" "r"))]
13825 [(set_attr "type" "ibr")
13826 (set_attr "length_immediate" "0")])
13832 [(set_attr "length" "1")
13833 (set_attr "length_immediate" "0")
13834 (set_attr "modrm" "0")])
13836 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13837 ;; branch prediction penalty for the third jump in a 16-byte
13840 (define_insn "align"
13841 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13844 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13845 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13847 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13848 The align insn is used to avoid 3 jump instructions in the row to improve
13849 branch prediction and the benefits hardly outweight the cost of extra 8
13850 nops on the average inserted by full alignment pseudo operation. */
13854 [(set_attr "length" "16")])
13856 (define_expand "prologue"
13859 "ix86_expand_prologue (); DONE;")
13861 (define_insn "set_got"
13862 [(set (match_operand:SI 0 "register_operand" "=r")
13863 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13864 (clobber (reg:CC FLAGS_REG))]
13866 { return output_set_got (operands[0]); }
13867 [(set_attr "type" "multi")
13868 (set_attr "length" "12")])
13870 (define_insn "set_got_rex64"
13871 [(set (match_operand:DI 0 "register_operand" "=r")
13872 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13874 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
13875 [(set_attr "type" "lea")
13876 (set_attr "length" "6")])
13878 (define_expand "epilogue"
13881 "ix86_expand_epilogue (1); DONE;")
13883 (define_expand "sibcall_epilogue"
13886 "ix86_expand_epilogue (0); DONE;")
13888 (define_expand "eh_return"
13889 [(use (match_operand 0 "register_operand" ""))]
13892 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13894 /* Tricky bit: we write the address of the handler to which we will
13895 be returning into someone else's stack frame, one word below the
13896 stack address we wish to restore. */
13897 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13898 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13899 tmp = gen_rtx_MEM (Pmode, tmp);
13900 emit_move_insn (tmp, ra);
13902 if (Pmode == SImode)
13903 emit_jump_insn (gen_eh_return_si (sa));
13905 emit_jump_insn (gen_eh_return_di (sa));
13910 (define_insn_and_split "eh_return_si"
13912 (unspec [(match_operand:SI 0 "register_operand" "c")]
13913 UNSPEC_EH_RETURN))]
13918 "ix86_expand_epilogue (2); DONE;")
13920 (define_insn_and_split "eh_return_di"
13922 (unspec [(match_operand:DI 0 "register_operand" "c")]
13923 UNSPEC_EH_RETURN))]
13928 "ix86_expand_epilogue (2); DONE;")
13930 (define_insn "leave"
13931 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13932 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13933 (clobber (mem:BLK (scratch)))]
13936 [(set_attr "type" "leave")])
13938 (define_insn "leave_rex64"
13939 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13940 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13941 (clobber (mem:BLK (scratch)))]
13944 [(set_attr "type" "leave")])
13946 (define_expand "ffssi2"
13948 [(set (match_operand:SI 0 "register_operand" "")
13949 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13950 (clobber (match_scratch:SI 2 ""))
13951 (clobber (reg:CC FLAGS_REG))])]
13955 (define_insn_and_split "*ffs_cmove"
13956 [(set (match_operand:SI 0 "register_operand" "=r")
13957 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13958 (clobber (match_scratch:SI 2 "=&r"))
13959 (clobber (reg:CC FLAGS_REG))]
13962 "&& reload_completed"
13963 [(set (match_dup 2) (const_int -1))
13964 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13965 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13966 (set (match_dup 0) (if_then_else:SI
13967 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13970 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13971 (clobber (reg:CC FLAGS_REG))])]
13974 (define_insn_and_split "*ffs_no_cmove"
13975 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13976 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13977 (clobber (match_scratch:SI 2 "=&q"))
13978 (clobber (reg:CC FLAGS_REG))]
13982 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13983 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13984 (set (strict_low_part (match_dup 3))
13985 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13986 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13987 (clobber (reg:CC FLAGS_REG))])
13988 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13989 (clobber (reg:CC FLAGS_REG))])
13990 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13991 (clobber (reg:CC FLAGS_REG))])]
13993 operands[3] = gen_lowpart (QImode, operands[2]);
13994 ix86_expand_clear (operands[2]);
13997 (define_insn "*ffssi_1"
13998 [(set (reg:CCZ FLAGS_REG)
13999 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14001 (set (match_operand:SI 0 "register_operand" "=r")
14002 (ctz:SI (match_dup 1)))]
14004 "bsf{l}\t{%1, %0|%0, %1}"
14005 [(set_attr "prefix_0f" "1")])
14007 (define_expand "ffsdi2"
14009 [(set (match_operand:DI 0 "register_operand" "")
14010 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14011 (clobber (match_scratch:DI 2 ""))
14012 (clobber (reg:CC FLAGS_REG))])]
14013 "TARGET_64BIT && TARGET_CMOVE"
14016 (define_insn_and_split "*ffs_rex64"
14017 [(set (match_operand:DI 0 "register_operand" "=r")
14018 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14019 (clobber (match_scratch:DI 2 "=&r"))
14020 (clobber (reg:CC FLAGS_REG))]
14021 "TARGET_64BIT && TARGET_CMOVE"
14023 "&& reload_completed"
14024 [(set (match_dup 2) (const_int -1))
14025 (parallel [(set (reg:CCZ FLAGS_REG)
14026 (compare:CCZ (match_dup 1) (const_int 0)))
14027 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14028 (set (match_dup 0) (if_then_else:DI
14029 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14032 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14033 (clobber (reg:CC FLAGS_REG))])]
14036 (define_insn "*ffsdi_1"
14037 [(set (reg:CCZ FLAGS_REG)
14038 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14040 (set (match_operand:DI 0 "register_operand" "=r")
14041 (ctz:DI (match_dup 1)))]
14043 "bsf{q}\t{%1, %0|%0, %1}"
14044 [(set_attr "prefix_0f" "1")])
14046 (define_insn "ctzsi2"
14047 [(set (match_operand:SI 0 "register_operand" "=r")
14048 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14049 (clobber (reg:CC FLAGS_REG))]
14051 "bsf{l}\t{%1, %0|%0, %1}"
14052 [(set_attr "prefix_0f" "1")])
14054 (define_insn "ctzdi2"
14055 [(set (match_operand:DI 0 "register_operand" "=r")
14056 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14057 (clobber (reg:CC FLAGS_REG))]
14059 "bsf{q}\t{%1, %0|%0, %1}"
14060 [(set_attr "prefix_0f" "1")])
14062 (define_expand "clzsi2"
14064 [(set (match_operand:SI 0 "register_operand" "")
14065 (minus:SI (const_int 31)
14066 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14067 (clobber (reg:CC FLAGS_REG))])
14069 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14070 (clobber (reg:CC FLAGS_REG))])]
14074 (define_insn "*bsr"
14075 [(set (match_operand:SI 0 "register_operand" "=r")
14076 (minus:SI (const_int 31)
14077 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14078 (clobber (reg:CC FLAGS_REG))]
14080 "bsr{l}\t{%1, %0|%0, %1}"
14081 [(set_attr "prefix_0f" "1")])
14083 (define_expand "clzdi2"
14085 [(set (match_operand:DI 0 "register_operand" "")
14086 (minus:DI (const_int 63)
14087 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14088 (clobber (reg:CC FLAGS_REG))])
14090 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14091 (clobber (reg:CC FLAGS_REG))])]
14095 (define_insn "*bsr_rex64"
14096 [(set (match_operand:DI 0 "register_operand" "=r")
14097 (minus:DI (const_int 63)
14098 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14099 (clobber (reg:CC FLAGS_REG))]
14101 "bsr{q}\t{%1, %0|%0, %1}"
14102 [(set_attr "prefix_0f" "1")])
14104 ;; Thread-local storage patterns for ELF.
14106 ;; Note that these code sequences must appear exactly as shown
14107 ;; in order to allow linker relaxation.
14109 (define_insn "*tls_global_dynamic_32_gnu"
14110 [(set (match_operand:SI 0 "register_operand" "=a")
14111 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14112 (match_operand:SI 2 "tls_symbolic_operand" "")
14113 (match_operand:SI 3 "call_insn_operand" "")]
14115 (clobber (match_scratch:SI 4 "=d"))
14116 (clobber (match_scratch:SI 5 "=c"))
14117 (clobber (reg:CC FLAGS_REG))]
14118 "!TARGET_64BIT && TARGET_GNU_TLS"
14119 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14120 [(set_attr "type" "multi")
14121 (set_attr "length" "12")])
14123 (define_insn "*tls_global_dynamic_32_sun"
14124 [(set (match_operand:SI 0 "register_operand" "=a")
14125 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14126 (match_operand:SI 2 "tls_symbolic_operand" "")
14127 (match_operand:SI 3 "call_insn_operand" "")]
14129 (clobber (match_scratch:SI 4 "=d"))
14130 (clobber (match_scratch:SI 5 "=c"))
14131 (clobber (reg:CC FLAGS_REG))]
14132 "!TARGET_64BIT && TARGET_SUN_TLS"
14133 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14134 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14135 [(set_attr "type" "multi")
14136 (set_attr "length" "14")])
14138 (define_expand "tls_global_dynamic_32"
14139 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14142 (match_operand:SI 1 "tls_symbolic_operand" "")
14145 (clobber (match_scratch:SI 4 ""))
14146 (clobber (match_scratch:SI 5 ""))
14147 (clobber (reg:CC FLAGS_REG))])]
14151 operands[2] = pic_offset_table_rtx;
14154 operands[2] = gen_reg_rtx (Pmode);
14155 emit_insn (gen_set_got (operands[2]));
14157 operands[3] = ix86_tls_get_addr ();
14160 (define_insn "*tls_global_dynamic_64"
14161 [(set (match_operand:DI 0 "register_operand" "=a")
14162 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14163 (match_operand:DI 3 "" "")))
14164 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14167 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14168 [(set_attr "type" "multi")
14169 (set_attr "length" "16")])
14171 (define_expand "tls_global_dynamic_64"
14172 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14173 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14174 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14178 operands[2] = ix86_tls_get_addr ();
14181 (define_insn "*tls_local_dynamic_base_32_gnu"
14182 [(set (match_operand:SI 0 "register_operand" "=a")
14183 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14184 (match_operand:SI 2 "call_insn_operand" "")]
14185 UNSPEC_TLS_LD_BASE))
14186 (clobber (match_scratch:SI 3 "=d"))
14187 (clobber (match_scratch:SI 4 "=c"))
14188 (clobber (reg:CC FLAGS_REG))]
14189 "!TARGET_64BIT && TARGET_GNU_TLS"
14190 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14191 [(set_attr "type" "multi")
14192 (set_attr "length" "11")])
14194 (define_insn "*tls_local_dynamic_base_32_sun"
14195 [(set (match_operand:SI 0 "register_operand" "=a")
14196 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14197 (match_operand:SI 2 "call_insn_operand" "")]
14198 UNSPEC_TLS_LD_BASE))
14199 (clobber (match_scratch:SI 3 "=d"))
14200 (clobber (match_scratch:SI 4 "=c"))
14201 (clobber (reg:CC FLAGS_REG))]
14202 "!TARGET_64BIT && TARGET_SUN_TLS"
14203 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14204 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14205 [(set_attr "type" "multi")
14206 (set_attr "length" "13")])
14208 (define_expand "tls_local_dynamic_base_32"
14209 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14210 (unspec:SI [(match_dup 1) (match_dup 2)]
14211 UNSPEC_TLS_LD_BASE))
14212 (clobber (match_scratch:SI 3 ""))
14213 (clobber (match_scratch:SI 4 ""))
14214 (clobber (reg:CC FLAGS_REG))])]
14218 operands[1] = pic_offset_table_rtx;
14221 operands[1] = gen_reg_rtx (Pmode);
14222 emit_insn (gen_set_got (operands[1]));
14224 operands[2] = ix86_tls_get_addr ();
14227 (define_insn "*tls_local_dynamic_base_64"
14228 [(set (match_operand:DI 0 "register_operand" "=a")
14229 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14230 (match_operand:DI 2 "" "")))
14231 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14233 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14234 [(set_attr "type" "multi")
14235 (set_attr "length" "12")])
14237 (define_expand "tls_local_dynamic_base_64"
14238 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14239 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14240 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14243 operands[1] = ix86_tls_get_addr ();
14246 ;; Local dynamic of a single variable is a lose. Show combine how
14247 ;; to convert that back to global dynamic.
14249 (define_insn_and_split "*tls_local_dynamic_32_once"
14250 [(set (match_operand:SI 0 "register_operand" "=a")
14251 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14252 (match_operand:SI 2 "call_insn_operand" "")]
14253 UNSPEC_TLS_LD_BASE)
14254 (const:SI (unspec:SI
14255 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14257 (clobber (match_scratch:SI 4 "=d"))
14258 (clobber (match_scratch:SI 5 "=c"))
14259 (clobber (reg:CC FLAGS_REG))]
14263 [(parallel [(set (match_dup 0)
14264 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14266 (clobber (match_dup 4))
14267 (clobber (match_dup 5))
14268 (clobber (reg:CC FLAGS_REG))])]
14271 ;; Load and add the thread base pointer from %gs:0.
14273 (define_insn "*load_tp_si"
14274 [(set (match_operand:SI 0 "register_operand" "=r")
14275 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14277 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14278 [(set_attr "type" "imov")
14279 (set_attr "modrm" "0")
14280 (set_attr "length" "7")
14281 (set_attr "memory" "load")
14282 (set_attr "imm_disp" "false")])
14284 (define_insn "*add_tp_si"
14285 [(set (match_operand:SI 0 "register_operand" "=r")
14286 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14287 (match_operand:SI 1 "register_operand" "0")))
14288 (clobber (reg:CC FLAGS_REG))]
14290 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14291 [(set_attr "type" "alu")
14292 (set_attr "modrm" "0")
14293 (set_attr "length" "7")
14294 (set_attr "memory" "load")
14295 (set_attr "imm_disp" "false")])
14297 (define_insn "*load_tp_di"
14298 [(set (match_operand:DI 0 "register_operand" "=r")
14299 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14301 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14302 [(set_attr "type" "imov")
14303 (set_attr "modrm" "0")
14304 (set_attr "length" "7")
14305 (set_attr "memory" "load")
14306 (set_attr "imm_disp" "false")])
14308 (define_insn "*add_tp_di"
14309 [(set (match_operand:DI 0 "register_operand" "=r")
14310 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14311 (match_operand:DI 1 "register_operand" "0")))
14312 (clobber (reg:CC FLAGS_REG))]
14314 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14315 [(set_attr "type" "alu")
14316 (set_attr "modrm" "0")
14317 (set_attr "length" "7")
14318 (set_attr "memory" "load")
14319 (set_attr "imm_disp" "false")])
14321 ;; These patterns match the binary 387 instructions for addM3, subM3,
14322 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14323 ;; SFmode. The first is the normal insn, the second the same insn but
14324 ;; with one operand a conversion, and the third the same insn but with
14325 ;; the other operand a conversion. The conversion may be SFmode or
14326 ;; SImode if the target mode DFmode, but only SImode if the target mode
14329 ;; Gcc is slightly more smart about handling normal two address instructions
14330 ;; so use special patterns for add and mull.
14332 (define_insn "*fop_sf_comm_mixed"
14333 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14334 (match_operator:SF 3 "binary_fp_operator"
14335 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14336 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14337 "TARGET_MIX_SSE_I387
14338 && COMMUTATIVE_ARITH_P (operands[3])
14339 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14340 "* return output_387_binary_op (insn, operands);"
14341 [(set (attr "type")
14342 (if_then_else (eq_attr "alternative" "1")
14343 (if_then_else (match_operand:SF 3 "mult_operator" "")
14344 (const_string "ssemul")
14345 (const_string "sseadd"))
14346 (if_then_else (match_operand:SF 3 "mult_operator" "")
14347 (const_string "fmul")
14348 (const_string "fop"))))
14349 (set_attr "mode" "SF")])
14351 (define_insn "*fop_sf_comm_sse"
14352 [(set (match_operand:SF 0 "register_operand" "=x")
14353 (match_operator:SF 3 "binary_fp_operator"
14354 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14355 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14357 && COMMUTATIVE_ARITH_P (operands[3])
14358 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14359 "* return output_387_binary_op (insn, operands);"
14360 [(set (attr "type")
14361 (if_then_else (match_operand:SF 3 "mult_operator" "")
14362 (const_string "ssemul")
14363 (const_string "sseadd")))
14364 (set_attr "mode" "SF")])
14366 (define_insn "*fop_sf_comm_i387"
14367 [(set (match_operand:SF 0 "register_operand" "=f")
14368 (match_operator:SF 3 "binary_fp_operator"
14369 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14370 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14372 && COMMUTATIVE_ARITH_P (operands[3])
14373 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14374 "* return output_387_binary_op (insn, operands);"
14375 [(set (attr "type")
14376 (if_then_else (match_operand:SF 3 "mult_operator" "")
14377 (const_string "fmul")
14378 (const_string "fop")))
14379 (set_attr "mode" "SF")])
14381 (define_insn "*fop_sf_1_mixed"
14382 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14383 (match_operator:SF 3 "binary_fp_operator"
14384 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14385 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14386 "TARGET_MIX_SSE_I387
14387 && !COMMUTATIVE_ARITH_P (operands[3])
14388 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14389 "* return output_387_binary_op (insn, operands);"
14390 [(set (attr "type")
14391 (cond [(and (eq_attr "alternative" "2")
14392 (match_operand:SF 3 "mult_operator" ""))
14393 (const_string "ssemul")
14394 (and (eq_attr "alternative" "2")
14395 (match_operand:SF 3 "div_operator" ""))
14396 (const_string "ssediv")
14397 (eq_attr "alternative" "2")
14398 (const_string "sseadd")
14399 (match_operand:SF 3 "mult_operator" "")
14400 (const_string "fmul")
14401 (match_operand:SF 3 "div_operator" "")
14402 (const_string "fdiv")
14404 (const_string "fop")))
14405 (set_attr "mode" "SF")])
14407 (define_insn "*fop_sf_1_sse"
14408 [(set (match_operand:SF 0 "register_operand" "=x")
14409 (match_operator:SF 3 "binary_fp_operator"
14410 [(match_operand:SF 1 "register_operand" "0")
14411 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14413 && !COMMUTATIVE_ARITH_P (operands[3])"
14414 "* return output_387_binary_op (insn, operands);"
14415 [(set (attr "type")
14416 (cond [(match_operand:SF 3 "mult_operator" "")
14417 (const_string "ssemul")
14418 (match_operand:SF 3 "div_operator" "")
14419 (const_string "ssediv")
14421 (const_string "sseadd")))
14422 (set_attr "mode" "SF")])
14424 ;; This pattern is not fully shadowed by the pattern above.
14425 (define_insn "*fop_sf_1_i387"
14426 [(set (match_operand:SF 0 "register_operand" "=f,f")
14427 (match_operator:SF 3 "binary_fp_operator"
14428 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14429 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14430 "TARGET_80387 && !TARGET_SSE_MATH
14431 && !COMMUTATIVE_ARITH_P (operands[3])
14432 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14433 "* return output_387_binary_op (insn, operands);"
14434 [(set (attr "type")
14435 (cond [(match_operand:SF 3 "mult_operator" "")
14436 (const_string "fmul")
14437 (match_operand:SF 3 "div_operator" "")
14438 (const_string "fdiv")
14440 (const_string "fop")))
14441 (set_attr "mode" "SF")])
14443 ;; ??? Add SSE splitters for these!
14444 (define_insn "*fop_sf_2<mode>_i387"
14445 [(set (match_operand:SF 0 "register_operand" "=f,f")
14446 (match_operator:SF 3 "binary_fp_operator"
14447 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14448 (match_operand:SF 2 "register_operand" "0,0")]))]
14449 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14450 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14451 [(set (attr "type")
14452 (cond [(match_operand:SF 3 "mult_operator" "")
14453 (const_string "fmul")
14454 (match_operand:SF 3 "div_operator" "")
14455 (const_string "fdiv")
14457 (const_string "fop")))
14458 (set_attr "fp_int_src" "true")
14459 (set_attr "mode" "<MODE>")])
14461 (define_insn "*fop_sf_3<mode>_i387"
14462 [(set (match_operand:SF 0 "register_operand" "=f,f")
14463 (match_operator:SF 3 "binary_fp_operator"
14464 [(match_operand:SF 1 "register_operand" "0,0")
14465 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14466 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14467 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14468 [(set (attr "type")
14469 (cond [(match_operand:SF 3 "mult_operator" "")
14470 (const_string "fmul")
14471 (match_operand:SF 3 "div_operator" "")
14472 (const_string "fdiv")
14474 (const_string "fop")))
14475 (set_attr "fp_int_src" "true")
14476 (set_attr "mode" "<MODE>")])
14478 (define_insn "*fop_df_comm_mixed"
14479 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14480 (match_operator:DF 3 "binary_fp_operator"
14481 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14482 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14483 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14484 && COMMUTATIVE_ARITH_P (operands[3])
14485 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14486 "* return output_387_binary_op (insn, operands);"
14487 [(set (attr "type")
14488 (if_then_else (eq_attr "alternative" "1")
14489 (if_then_else (match_operand:SF 3 "mult_operator" "")
14490 (const_string "ssemul")
14491 (const_string "sseadd"))
14492 (if_then_else (match_operand:SF 3 "mult_operator" "")
14493 (const_string "fmul")
14494 (const_string "fop"))))
14495 (set_attr "mode" "DF")])
14497 (define_insn "*fop_df_comm_sse"
14498 [(set (match_operand:DF 0 "register_operand" "=Y")
14499 (match_operator:DF 3 "binary_fp_operator"
14500 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14501 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14502 "TARGET_SSE2 && TARGET_SSE_MATH
14503 && COMMUTATIVE_ARITH_P (operands[3])
14504 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14505 "* return output_387_binary_op (insn, operands);"
14506 [(set (attr "type")
14507 (if_then_else (match_operand:SF 3 "mult_operator" "")
14508 (const_string "ssemul")
14509 (const_string "sseadd")))
14510 (set_attr "mode" "DF")])
14512 (define_insn "*fop_df_comm_i387"
14513 [(set (match_operand:DF 0 "register_operand" "=f")
14514 (match_operator:DF 3 "binary_fp_operator"
14515 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14516 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14518 && COMMUTATIVE_ARITH_P (operands[3])
14519 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14520 "* return output_387_binary_op (insn, operands);"
14521 [(set (attr "type")
14522 (if_then_else (match_operand:SF 3 "mult_operator" "")
14523 (const_string "fmul")
14524 (const_string "fop")))
14525 (set_attr "mode" "DF")])
14527 (define_insn "*fop_df_1_mixed"
14528 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14529 (match_operator:DF 3 "binary_fp_operator"
14530 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14531 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14532 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14533 && !COMMUTATIVE_ARITH_P (operands[3])
14534 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14535 "* return output_387_binary_op (insn, operands);"
14536 [(set (attr "type")
14537 (cond [(and (eq_attr "alternative" "2")
14538 (match_operand:SF 3 "mult_operator" ""))
14539 (const_string "ssemul")
14540 (and (eq_attr "alternative" "2")
14541 (match_operand:SF 3 "div_operator" ""))
14542 (const_string "ssediv")
14543 (eq_attr "alternative" "2")
14544 (const_string "sseadd")
14545 (match_operand:DF 3 "mult_operator" "")
14546 (const_string "fmul")
14547 (match_operand:DF 3 "div_operator" "")
14548 (const_string "fdiv")
14550 (const_string "fop")))
14551 (set_attr "mode" "DF")])
14553 (define_insn "*fop_df_1_sse"
14554 [(set (match_operand:DF 0 "register_operand" "=Y")
14555 (match_operator:DF 3 "binary_fp_operator"
14556 [(match_operand:DF 1 "register_operand" "0")
14557 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14558 "TARGET_SSE2 && TARGET_SSE_MATH
14559 && !COMMUTATIVE_ARITH_P (operands[3])"
14560 "* return output_387_binary_op (insn, operands);"
14561 [(set_attr "mode" "DF")
14563 (cond [(match_operand:SF 3 "mult_operator" "")
14564 (const_string "ssemul")
14565 (match_operand:SF 3 "div_operator" "")
14566 (const_string "ssediv")
14568 (const_string "sseadd")))])
14570 ;; This pattern is not fully shadowed by the pattern above.
14571 (define_insn "*fop_df_1_i387"
14572 [(set (match_operand:DF 0 "register_operand" "=f,f")
14573 (match_operator:DF 3 "binary_fp_operator"
14574 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14575 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14576 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14577 && !COMMUTATIVE_ARITH_P (operands[3])
14578 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14579 "* return output_387_binary_op (insn, operands);"
14580 [(set (attr "type")
14581 (cond [(match_operand:DF 3 "mult_operator" "")
14582 (const_string "fmul")
14583 (match_operand:DF 3 "div_operator" "")
14584 (const_string "fdiv")
14586 (const_string "fop")))
14587 (set_attr "mode" "DF")])
14589 ;; ??? Add SSE splitters for these!
14590 (define_insn "*fop_df_2<mode>_i387"
14591 [(set (match_operand:DF 0 "register_operand" "=f,f")
14592 (match_operator:DF 3 "binary_fp_operator"
14593 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14594 (match_operand:DF 2 "register_operand" "0,0")]))]
14595 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14596 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14597 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14598 [(set (attr "type")
14599 (cond [(match_operand:DF 3 "mult_operator" "")
14600 (const_string "fmul")
14601 (match_operand:DF 3 "div_operator" "")
14602 (const_string "fdiv")
14604 (const_string "fop")))
14605 (set_attr "fp_int_src" "true")
14606 (set_attr "mode" "<MODE>")])
14608 (define_insn "*fop_df_3<mode>_i387"
14609 [(set (match_operand:DF 0 "register_operand" "=f,f")
14610 (match_operator:DF 3 "binary_fp_operator"
14611 [(match_operand:DF 1 "register_operand" "0,0")
14612 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14613 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14614 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14615 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14616 [(set (attr "type")
14617 (cond [(match_operand:DF 3 "mult_operator" "")
14618 (const_string "fmul")
14619 (match_operand:DF 3 "div_operator" "")
14620 (const_string "fdiv")
14622 (const_string "fop")))
14623 (set_attr "fp_int_src" "true")
14624 (set_attr "mode" "<MODE>")])
14626 (define_insn "*fop_df_4_i387"
14627 [(set (match_operand:DF 0 "register_operand" "=f,f")
14628 (match_operator:DF 3 "binary_fp_operator"
14629 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14630 (match_operand:DF 2 "register_operand" "0,f")]))]
14631 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14632 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14633 "* return output_387_binary_op (insn, operands);"
14634 [(set (attr "type")
14635 (cond [(match_operand:DF 3 "mult_operator" "")
14636 (const_string "fmul")
14637 (match_operand:DF 3 "div_operator" "")
14638 (const_string "fdiv")
14640 (const_string "fop")))
14641 (set_attr "mode" "SF")])
14643 (define_insn "*fop_df_5_i387"
14644 [(set (match_operand:DF 0 "register_operand" "=f,f")
14645 (match_operator:DF 3 "binary_fp_operator"
14646 [(match_operand:DF 1 "register_operand" "0,f")
14648 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14649 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14650 "* return output_387_binary_op (insn, operands);"
14651 [(set (attr "type")
14652 (cond [(match_operand:DF 3 "mult_operator" "")
14653 (const_string "fmul")
14654 (match_operand:DF 3 "div_operator" "")
14655 (const_string "fdiv")
14657 (const_string "fop")))
14658 (set_attr "mode" "SF")])
14660 (define_insn "*fop_df_6_i387"
14661 [(set (match_operand:DF 0 "register_operand" "=f,f")
14662 (match_operator:DF 3 "binary_fp_operator"
14664 (match_operand:SF 1 "register_operand" "0,f"))
14666 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14667 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14668 "* return output_387_binary_op (insn, operands);"
14669 [(set (attr "type")
14670 (cond [(match_operand:DF 3 "mult_operator" "")
14671 (const_string "fmul")
14672 (match_operand:DF 3 "div_operator" "")
14673 (const_string "fdiv")
14675 (const_string "fop")))
14676 (set_attr "mode" "SF")])
14678 (define_insn "*fop_xf_comm_i387"
14679 [(set (match_operand:XF 0 "register_operand" "=f")
14680 (match_operator:XF 3 "binary_fp_operator"
14681 [(match_operand:XF 1 "register_operand" "%0")
14682 (match_operand:XF 2 "register_operand" "f")]))]
14684 && COMMUTATIVE_ARITH_P (operands[3])"
14685 "* return output_387_binary_op (insn, operands);"
14686 [(set (attr "type")
14687 (if_then_else (match_operand:XF 3 "mult_operator" "")
14688 (const_string "fmul")
14689 (const_string "fop")))
14690 (set_attr "mode" "XF")])
14692 (define_insn "*fop_xf_1_i387"
14693 [(set (match_operand:XF 0 "register_operand" "=f,f")
14694 (match_operator:XF 3 "binary_fp_operator"
14695 [(match_operand:XF 1 "register_operand" "0,f")
14696 (match_operand:XF 2 "register_operand" "f,0")]))]
14698 && !COMMUTATIVE_ARITH_P (operands[3])"
14699 "* return output_387_binary_op (insn, operands);"
14700 [(set (attr "type")
14701 (cond [(match_operand:XF 3 "mult_operator" "")
14702 (const_string "fmul")
14703 (match_operand:XF 3 "div_operator" "")
14704 (const_string "fdiv")
14706 (const_string "fop")))
14707 (set_attr "mode" "XF")])
14709 (define_insn "*fop_xf_2<mode>_i387"
14710 [(set (match_operand:XF 0 "register_operand" "=f,f")
14711 (match_operator:XF 3 "binary_fp_operator"
14712 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14713 (match_operand:XF 2 "register_operand" "0,0")]))]
14714 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14715 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14716 [(set (attr "type")
14717 (cond [(match_operand:XF 3 "mult_operator" "")
14718 (const_string "fmul")
14719 (match_operand:XF 3 "div_operator" "")
14720 (const_string "fdiv")
14722 (const_string "fop")))
14723 (set_attr "fp_int_src" "true")
14724 (set_attr "mode" "<MODE>")])
14726 (define_insn "*fop_xf_3<mode>_i387"
14727 [(set (match_operand:XF 0 "register_operand" "=f,f")
14728 (match_operator:XF 3 "binary_fp_operator"
14729 [(match_operand:XF 1 "register_operand" "0,0")
14730 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14731 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14732 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14733 [(set (attr "type")
14734 (cond [(match_operand:XF 3 "mult_operator" "")
14735 (const_string "fmul")
14736 (match_operand:XF 3 "div_operator" "")
14737 (const_string "fdiv")
14739 (const_string "fop")))
14740 (set_attr "fp_int_src" "true")
14741 (set_attr "mode" "<MODE>")])
14743 (define_insn "*fop_xf_4_i387"
14744 [(set (match_operand:XF 0 "register_operand" "=f,f")
14745 (match_operator:XF 3 "binary_fp_operator"
14746 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14747 (match_operand:XF 2 "register_operand" "0,f")]))]
14749 "* return output_387_binary_op (insn, operands);"
14750 [(set (attr "type")
14751 (cond [(match_operand:XF 3 "mult_operator" "")
14752 (const_string "fmul")
14753 (match_operand:XF 3 "div_operator" "")
14754 (const_string "fdiv")
14756 (const_string "fop")))
14757 (set_attr "mode" "SF")])
14759 (define_insn "*fop_xf_5_i387"
14760 [(set (match_operand:XF 0 "register_operand" "=f,f")
14761 (match_operator:XF 3 "binary_fp_operator"
14762 [(match_operand:XF 1 "register_operand" "0,f")
14764 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14766 "* return output_387_binary_op (insn, operands);"
14767 [(set (attr "type")
14768 (cond [(match_operand:XF 3 "mult_operator" "")
14769 (const_string "fmul")
14770 (match_operand:XF 3 "div_operator" "")
14771 (const_string "fdiv")
14773 (const_string "fop")))
14774 (set_attr "mode" "SF")])
14776 (define_insn "*fop_xf_6_i387"
14777 [(set (match_operand:XF 0 "register_operand" "=f,f")
14778 (match_operator:XF 3 "binary_fp_operator"
14780 (match_operand 1 "register_operand" "0,f"))
14782 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14784 "* return output_387_binary_op (insn, operands);"
14785 [(set (attr "type")
14786 (cond [(match_operand:XF 3 "mult_operator" "")
14787 (const_string "fmul")
14788 (match_operand:XF 3 "div_operator" "")
14789 (const_string "fdiv")
14791 (const_string "fop")))
14792 (set_attr "mode" "SF")])
14795 [(set (match_operand 0 "register_operand" "")
14796 (match_operator 3 "binary_fp_operator"
14797 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14798 (match_operand 2 "register_operand" "")]))]
14799 "TARGET_80387 && reload_completed
14800 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14803 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14804 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14805 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14806 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14807 GET_MODE (operands[3]),
14810 ix86_free_from_memory (GET_MODE (operands[1]));
14815 [(set (match_operand 0 "register_operand" "")
14816 (match_operator 3 "binary_fp_operator"
14817 [(match_operand 1 "register_operand" "")
14818 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14819 "TARGET_80387 && reload_completed
14820 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14823 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14824 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14825 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14826 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14827 GET_MODE (operands[3]),
14830 ix86_free_from_memory (GET_MODE (operands[2]));
14834 ;; FPU special functions.
14836 (define_expand "sqrtsf2"
14837 [(set (match_operand:SF 0 "register_operand" "")
14838 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14839 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14841 if (!TARGET_SSE_MATH)
14842 operands[1] = force_reg (SFmode, operands[1]);
14845 (define_insn "*sqrtsf2_mixed"
14846 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14847 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14848 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14851 sqrtss\t{%1, %0|%0, %1}"
14852 [(set_attr "type" "fpspc,sse")
14853 (set_attr "mode" "SF,SF")
14854 (set_attr "athlon_decode" "direct,*")])
14856 (define_insn "*sqrtsf2_sse"
14857 [(set (match_operand:SF 0 "register_operand" "=x")
14858 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14860 "sqrtss\t{%1, %0|%0, %1}"
14861 [(set_attr "type" "sse")
14862 (set_attr "mode" "SF")
14863 (set_attr "athlon_decode" "*")])
14865 (define_insn "*sqrtsf2_i387"
14866 [(set (match_operand:SF 0 "register_operand" "=f")
14867 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14868 "TARGET_USE_FANCY_MATH_387"
14870 [(set_attr "type" "fpspc")
14871 (set_attr "mode" "SF")
14872 (set_attr "athlon_decode" "direct")])
14874 (define_expand "sqrtdf2"
14875 [(set (match_operand:DF 0 "register_operand" "")
14876 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14877 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14879 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14880 operands[1] = force_reg (DFmode, operands[1]);
14883 (define_insn "*sqrtdf2_mixed"
14884 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14885 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14886 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14889 sqrtsd\t{%1, %0|%0, %1}"
14890 [(set_attr "type" "fpspc,sse")
14891 (set_attr "mode" "DF,DF")
14892 (set_attr "athlon_decode" "direct,*")])
14894 (define_insn "*sqrtdf2_sse"
14895 [(set (match_operand:DF 0 "register_operand" "=Y")
14896 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14897 "TARGET_SSE2 && TARGET_SSE_MATH"
14898 "sqrtsd\t{%1, %0|%0, %1}"
14899 [(set_attr "type" "sse")
14900 (set_attr "mode" "DF")
14901 (set_attr "athlon_decode" "*")])
14903 (define_insn "*sqrtdf2_i387"
14904 [(set (match_operand:DF 0 "register_operand" "=f")
14905 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14906 "TARGET_USE_FANCY_MATH_387"
14908 [(set_attr "type" "fpspc")
14909 (set_attr "mode" "DF")
14910 (set_attr "athlon_decode" "direct")])
14912 (define_insn "*sqrtextendsfdf2_i387"
14913 [(set (match_operand:DF 0 "register_operand" "=f")
14914 (sqrt:DF (float_extend:DF
14915 (match_operand:SF 1 "register_operand" "0"))))]
14916 "TARGET_USE_FANCY_MATH_387
14917 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14919 [(set_attr "type" "fpspc")
14920 (set_attr "mode" "DF")
14921 (set_attr "athlon_decode" "direct")])
14923 (define_insn "sqrtxf2"
14924 [(set (match_operand:XF 0 "register_operand" "=f")
14925 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14926 "TARGET_USE_FANCY_MATH_387
14927 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14929 [(set_attr "type" "fpspc")
14930 (set_attr "mode" "XF")
14931 (set_attr "athlon_decode" "direct")])
14933 (define_insn "*sqrtextendsfxf2_i387"
14934 [(set (match_operand:XF 0 "register_operand" "=f")
14935 (sqrt:XF (float_extend:XF
14936 (match_operand:SF 1 "register_operand" "0"))))]
14937 "TARGET_USE_FANCY_MATH_387"
14939 [(set_attr "type" "fpspc")
14940 (set_attr "mode" "XF")
14941 (set_attr "athlon_decode" "direct")])
14943 (define_insn "*sqrtextenddfxf2_i387"
14944 [(set (match_operand:XF 0 "register_operand" "=f")
14945 (sqrt:XF (float_extend:XF
14946 (match_operand:DF 1 "register_operand" "0"))))]
14947 "TARGET_USE_FANCY_MATH_387"
14949 [(set_attr "type" "fpspc")
14950 (set_attr "mode" "XF")
14951 (set_attr "athlon_decode" "direct")])
14953 (define_insn "fpremxf4"
14954 [(set (match_operand:XF 0 "register_operand" "=f")
14955 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14956 (match_operand:XF 3 "register_operand" "1")]
14958 (set (match_operand:XF 1 "register_operand" "=u")
14959 (unspec:XF [(match_dup 2) (match_dup 3)]
14961 (set (reg:CCFP FPSR_REG)
14962 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14963 "TARGET_USE_FANCY_MATH_387
14964 && flag_unsafe_math_optimizations"
14966 [(set_attr "type" "fpspc")
14967 (set_attr "mode" "XF")])
14969 (define_expand "fmodsf3"
14970 [(use (match_operand:SF 0 "register_operand" ""))
14971 (use (match_operand:SF 1 "register_operand" ""))
14972 (use (match_operand:SF 2 "register_operand" ""))]
14973 "TARGET_USE_FANCY_MATH_387
14974 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14975 && flag_unsafe_math_optimizations"
14977 rtx label = gen_label_rtx ();
14979 rtx op1 = gen_reg_rtx (XFmode);
14980 rtx op2 = gen_reg_rtx (XFmode);
14982 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14983 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14985 emit_label (label);
14987 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14988 ix86_emit_fp_unordered_jump (label);
14990 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14994 (define_expand "fmoddf3"
14995 [(use (match_operand:DF 0 "register_operand" ""))
14996 (use (match_operand:DF 1 "register_operand" ""))
14997 (use (match_operand:DF 2 "register_operand" ""))]
14998 "TARGET_USE_FANCY_MATH_387
14999 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15000 && flag_unsafe_math_optimizations"
15002 rtx label = gen_label_rtx ();
15004 rtx op1 = gen_reg_rtx (XFmode);
15005 rtx op2 = gen_reg_rtx (XFmode);
15007 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15008 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15010 emit_label (label);
15012 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15013 ix86_emit_fp_unordered_jump (label);
15015 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15019 (define_expand "fmodxf3"
15020 [(use (match_operand:XF 0 "register_operand" ""))
15021 (use (match_operand:XF 1 "register_operand" ""))
15022 (use (match_operand:XF 2 "register_operand" ""))]
15023 "TARGET_USE_FANCY_MATH_387
15024 && flag_unsafe_math_optimizations"
15026 rtx label = gen_label_rtx ();
15028 emit_label (label);
15030 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15031 operands[1], operands[2]));
15032 ix86_emit_fp_unordered_jump (label);
15034 emit_move_insn (operands[0], operands[1]);
15038 (define_insn "fprem1xf4"
15039 [(set (match_operand:XF 0 "register_operand" "=f")
15040 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15041 (match_operand:XF 3 "register_operand" "1")]
15043 (set (match_operand:XF 1 "register_operand" "=u")
15044 (unspec:XF [(match_dup 2) (match_dup 3)]
15046 (set (reg:CCFP FPSR_REG)
15047 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15048 "TARGET_USE_FANCY_MATH_387
15049 && flag_unsafe_math_optimizations"
15051 [(set_attr "type" "fpspc")
15052 (set_attr "mode" "XF")])
15054 (define_expand "dremsf3"
15055 [(use (match_operand:SF 0 "register_operand" ""))
15056 (use (match_operand:SF 1 "register_operand" ""))
15057 (use (match_operand:SF 2 "register_operand" ""))]
15058 "TARGET_USE_FANCY_MATH_387
15059 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15060 && flag_unsafe_math_optimizations"
15062 rtx label = gen_label_rtx ();
15064 rtx op1 = gen_reg_rtx (XFmode);
15065 rtx op2 = gen_reg_rtx (XFmode);
15067 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15068 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15070 emit_label (label);
15072 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15073 ix86_emit_fp_unordered_jump (label);
15075 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15079 (define_expand "dremdf3"
15080 [(use (match_operand:DF 0 "register_operand" ""))
15081 (use (match_operand:DF 1 "register_operand" ""))
15082 (use (match_operand:DF 2 "register_operand" ""))]
15083 "TARGET_USE_FANCY_MATH_387
15084 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15085 && flag_unsafe_math_optimizations"
15087 rtx label = gen_label_rtx ();
15089 rtx op1 = gen_reg_rtx (XFmode);
15090 rtx op2 = gen_reg_rtx (XFmode);
15092 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15093 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15095 emit_label (label);
15097 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15098 ix86_emit_fp_unordered_jump (label);
15100 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15104 (define_expand "dremxf3"
15105 [(use (match_operand:XF 0 "register_operand" ""))
15106 (use (match_operand:XF 1 "register_operand" ""))
15107 (use (match_operand:XF 2 "register_operand" ""))]
15108 "TARGET_USE_FANCY_MATH_387
15109 && flag_unsafe_math_optimizations"
15111 rtx label = gen_label_rtx ();
15113 emit_label (label);
15115 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15116 operands[1], operands[2]));
15117 ix86_emit_fp_unordered_jump (label);
15119 emit_move_insn (operands[0], operands[1]);
15123 (define_insn "*sindf2"
15124 [(set (match_operand:DF 0 "register_operand" "=f")
15125 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15126 "TARGET_USE_FANCY_MATH_387
15127 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15128 && flag_unsafe_math_optimizations"
15130 [(set_attr "type" "fpspc")
15131 (set_attr "mode" "DF")])
15133 (define_insn "*sinsf2"
15134 [(set (match_operand:SF 0 "register_operand" "=f")
15135 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15136 "TARGET_USE_FANCY_MATH_387
15137 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15138 && flag_unsafe_math_optimizations"
15140 [(set_attr "type" "fpspc")
15141 (set_attr "mode" "SF")])
15143 (define_insn "*sinextendsfdf2"
15144 [(set (match_operand:DF 0 "register_operand" "=f")
15145 (unspec:DF [(float_extend:DF
15146 (match_operand:SF 1 "register_operand" "0"))]
15148 "TARGET_USE_FANCY_MATH_387
15149 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15150 && flag_unsafe_math_optimizations"
15152 [(set_attr "type" "fpspc")
15153 (set_attr "mode" "DF")])
15155 (define_insn "*sinxf2"
15156 [(set (match_operand:XF 0 "register_operand" "=f")
15157 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15158 "TARGET_USE_FANCY_MATH_387
15159 && flag_unsafe_math_optimizations"
15161 [(set_attr "type" "fpspc")
15162 (set_attr "mode" "XF")])
15164 (define_insn "*cosdf2"
15165 [(set (match_operand:DF 0 "register_operand" "=f")
15166 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15167 "TARGET_USE_FANCY_MATH_387
15168 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15169 && flag_unsafe_math_optimizations"
15171 [(set_attr "type" "fpspc")
15172 (set_attr "mode" "DF")])
15174 (define_insn "*cossf2"
15175 [(set (match_operand:SF 0 "register_operand" "=f")
15176 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15177 "TARGET_USE_FANCY_MATH_387
15178 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15179 && flag_unsafe_math_optimizations"
15181 [(set_attr "type" "fpspc")
15182 (set_attr "mode" "SF")])
15184 (define_insn "*cosextendsfdf2"
15185 [(set (match_operand:DF 0 "register_operand" "=f")
15186 (unspec:DF [(float_extend:DF
15187 (match_operand:SF 1 "register_operand" "0"))]
15189 "TARGET_USE_FANCY_MATH_387
15190 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15191 && flag_unsafe_math_optimizations"
15193 [(set_attr "type" "fpspc")
15194 (set_attr "mode" "DF")])
15196 (define_insn "*cosxf2"
15197 [(set (match_operand:XF 0 "register_operand" "=f")
15198 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15199 "TARGET_USE_FANCY_MATH_387
15200 && flag_unsafe_math_optimizations"
15202 [(set_attr "type" "fpspc")
15203 (set_attr "mode" "XF")])
15205 ;; With sincos pattern defined, sin and cos builtin function will be
15206 ;; expanded to sincos pattern with one of its outputs left unused.
15207 ;; Cse pass will detected, if two sincos patterns can be combined,
15208 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15209 ;; depending on the unused output.
15211 (define_insn "sincosdf3"
15212 [(set (match_operand:DF 0 "register_operand" "=f")
15213 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15214 UNSPEC_SINCOS_COS))
15215 (set (match_operand:DF 1 "register_operand" "=u")
15216 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15217 "TARGET_USE_FANCY_MATH_387
15218 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15219 && flag_unsafe_math_optimizations"
15221 [(set_attr "type" "fpspc")
15222 (set_attr "mode" "DF")])
15225 [(set (match_operand:DF 0 "register_operand" "")
15226 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15227 UNSPEC_SINCOS_COS))
15228 (set (match_operand:DF 1 "register_operand" "")
15229 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15230 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15231 && !reload_completed && !reload_in_progress"
15232 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15236 [(set (match_operand:DF 0 "register_operand" "")
15237 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15238 UNSPEC_SINCOS_COS))
15239 (set (match_operand:DF 1 "register_operand" "")
15240 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15241 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15242 && !reload_completed && !reload_in_progress"
15243 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15246 (define_insn "sincossf3"
15247 [(set (match_operand:SF 0 "register_operand" "=f")
15248 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15249 UNSPEC_SINCOS_COS))
15250 (set (match_operand:SF 1 "register_operand" "=u")
15251 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15252 "TARGET_USE_FANCY_MATH_387
15253 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15254 && flag_unsafe_math_optimizations"
15256 [(set_attr "type" "fpspc")
15257 (set_attr "mode" "SF")])
15260 [(set (match_operand:SF 0 "register_operand" "")
15261 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15262 UNSPEC_SINCOS_COS))
15263 (set (match_operand:SF 1 "register_operand" "")
15264 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15265 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15266 && !reload_completed && !reload_in_progress"
15267 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15271 [(set (match_operand:SF 0 "register_operand" "")
15272 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15273 UNSPEC_SINCOS_COS))
15274 (set (match_operand:SF 1 "register_operand" "")
15275 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15276 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15277 && !reload_completed && !reload_in_progress"
15278 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15281 (define_insn "*sincosextendsfdf3"
15282 [(set (match_operand:DF 0 "register_operand" "=f")
15283 (unspec:DF [(float_extend:DF
15284 (match_operand:SF 2 "register_operand" "0"))]
15285 UNSPEC_SINCOS_COS))
15286 (set (match_operand:DF 1 "register_operand" "=u")
15287 (unspec:DF [(float_extend:DF
15288 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15289 "TARGET_USE_FANCY_MATH_387
15290 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15291 && flag_unsafe_math_optimizations"
15293 [(set_attr "type" "fpspc")
15294 (set_attr "mode" "DF")])
15297 [(set (match_operand:DF 0 "register_operand" "")
15298 (unspec:DF [(float_extend:DF
15299 (match_operand:SF 2 "register_operand" ""))]
15300 UNSPEC_SINCOS_COS))
15301 (set (match_operand:DF 1 "register_operand" "")
15302 (unspec:DF [(float_extend:DF
15303 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15304 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15305 && !reload_completed && !reload_in_progress"
15306 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15307 (match_dup 2))] UNSPEC_SIN))]
15311 [(set (match_operand:DF 0 "register_operand" "")
15312 (unspec:DF [(float_extend:DF
15313 (match_operand:SF 2 "register_operand" ""))]
15314 UNSPEC_SINCOS_COS))
15315 (set (match_operand:DF 1 "register_operand" "")
15316 (unspec:DF [(float_extend:DF
15317 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15318 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15319 && !reload_completed && !reload_in_progress"
15320 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15321 (match_dup 2))] UNSPEC_COS))]
15324 (define_insn "sincosxf3"
15325 [(set (match_operand:XF 0 "register_operand" "=f")
15326 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15327 UNSPEC_SINCOS_COS))
15328 (set (match_operand:XF 1 "register_operand" "=u")
15329 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15330 "TARGET_USE_FANCY_MATH_387
15331 && flag_unsafe_math_optimizations"
15333 [(set_attr "type" "fpspc")
15334 (set_attr "mode" "XF")])
15337 [(set (match_operand:XF 0 "register_operand" "")
15338 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15339 UNSPEC_SINCOS_COS))
15340 (set (match_operand:XF 1 "register_operand" "")
15341 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15342 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15343 && !reload_completed && !reload_in_progress"
15344 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15348 [(set (match_operand:XF 0 "register_operand" "")
15349 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15350 UNSPEC_SINCOS_COS))
15351 (set (match_operand:XF 1 "register_operand" "")
15352 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15353 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15354 && !reload_completed && !reload_in_progress"
15355 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15358 (define_insn "*tandf3_1"
15359 [(set (match_operand:DF 0 "register_operand" "=f")
15360 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15362 (set (match_operand:DF 1 "register_operand" "=u")
15363 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15364 "TARGET_USE_FANCY_MATH_387
15365 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15366 && flag_unsafe_math_optimizations"
15368 [(set_attr "type" "fpspc")
15369 (set_attr "mode" "DF")])
15371 ;; optimize sequence: fptan
15374 ;; into fptan insn.
15377 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15378 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15380 (set (match_operand:DF 1 "register_operand" "")
15381 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15383 (match_operand:DF 3 "immediate_operand" ""))]
15384 "standard_80387_constant_p (operands[3]) == 2"
15385 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15386 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15389 (define_expand "tandf2"
15390 [(parallel [(set (match_dup 2)
15391 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15393 (set (match_operand:DF 0 "register_operand" "")
15394 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15395 "TARGET_USE_FANCY_MATH_387
15396 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15397 && flag_unsafe_math_optimizations"
15399 operands[2] = gen_reg_rtx (DFmode);
15402 (define_insn "*tansf3_1"
15403 [(set (match_operand:SF 0 "register_operand" "=f")
15404 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15406 (set (match_operand:SF 1 "register_operand" "=u")
15407 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15408 "TARGET_USE_FANCY_MATH_387
15409 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15410 && flag_unsafe_math_optimizations"
15412 [(set_attr "type" "fpspc")
15413 (set_attr "mode" "SF")])
15415 ;; optimize sequence: fptan
15418 ;; into fptan insn.
15421 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15422 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15424 (set (match_operand:SF 1 "register_operand" "")
15425 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15427 (match_operand:SF 3 "immediate_operand" ""))]
15428 "standard_80387_constant_p (operands[3]) == 2"
15429 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15430 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15433 (define_expand "tansf2"
15434 [(parallel [(set (match_dup 2)
15435 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15437 (set (match_operand:SF 0 "register_operand" "")
15438 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15439 "TARGET_USE_FANCY_MATH_387
15440 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15441 && flag_unsafe_math_optimizations"
15443 operands[2] = gen_reg_rtx (SFmode);
15446 (define_insn "*tanxf3_1"
15447 [(set (match_operand:XF 0 "register_operand" "=f")
15448 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15450 (set (match_operand:XF 1 "register_operand" "=u")
15451 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15452 "TARGET_USE_FANCY_MATH_387
15453 && flag_unsafe_math_optimizations"
15455 [(set_attr "type" "fpspc")
15456 (set_attr "mode" "XF")])
15458 ;; optimize sequence: fptan
15461 ;; into fptan insn.
15464 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15465 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15467 (set (match_operand:XF 1 "register_operand" "")
15468 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15470 (match_operand:XF 3 "immediate_operand" ""))]
15471 "standard_80387_constant_p (operands[3]) == 2"
15472 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15473 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15476 (define_expand "tanxf2"
15477 [(parallel [(set (match_dup 2)
15478 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15480 (set (match_operand:XF 0 "register_operand" "")
15481 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15482 "TARGET_USE_FANCY_MATH_387
15483 && flag_unsafe_math_optimizations"
15485 operands[2] = gen_reg_rtx (XFmode);
15488 (define_insn "atan2df3_1"
15489 [(set (match_operand:DF 0 "register_operand" "=f")
15490 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15491 (match_operand:DF 1 "register_operand" "u")]
15493 (clobber (match_scratch:DF 3 "=1"))]
15494 "TARGET_USE_FANCY_MATH_387
15495 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15496 && flag_unsafe_math_optimizations"
15498 [(set_attr "type" "fpspc")
15499 (set_attr "mode" "DF")])
15501 (define_expand "atan2df3"
15502 [(use (match_operand:DF 0 "register_operand" ""))
15503 (use (match_operand:DF 2 "register_operand" ""))
15504 (use (match_operand:DF 1 "register_operand" ""))]
15505 "TARGET_USE_FANCY_MATH_387
15506 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15507 && flag_unsafe_math_optimizations"
15509 rtx copy = gen_reg_rtx (DFmode);
15510 emit_move_insn (copy, operands[1]);
15511 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15515 (define_expand "atandf2"
15516 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15517 (unspec:DF [(match_dup 2)
15518 (match_operand:DF 1 "register_operand" "")]
15520 (clobber (match_scratch:DF 3 ""))])]
15521 "TARGET_USE_FANCY_MATH_387
15522 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15523 && flag_unsafe_math_optimizations"
15525 operands[2] = gen_reg_rtx (DFmode);
15526 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15529 (define_insn "atan2sf3_1"
15530 [(set (match_operand:SF 0 "register_operand" "=f")
15531 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15532 (match_operand:SF 1 "register_operand" "u")]
15534 (clobber (match_scratch:SF 3 "=1"))]
15535 "TARGET_USE_FANCY_MATH_387
15536 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15537 && flag_unsafe_math_optimizations"
15539 [(set_attr "type" "fpspc")
15540 (set_attr "mode" "SF")])
15542 (define_expand "atan2sf3"
15543 [(use (match_operand:SF 0 "register_operand" ""))
15544 (use (match_operand:SF 2 "register_operand" ""))
15545 (use (match_operand:SF 1 "register_operand" ""))]
15546 "TARGET_USE_FANCY_MATH_387
15547 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15548 && flag_unsafe_math_optimizations"
15550 rtx copy = gen_reg_rtx (SFmode);
15551 emit_move_insn (copy, operands[1]);
15552 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15556 (define_expand "atansf2"
15557 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15558 (unspec:SF [(match_dup 2)
15559 (match_operand:SF 1 "register_operand" "")]
15561 (clobber (match_scratch:SF 3 ""))])]
15562 "TARGET_USE_FANCY_MATH_387
15563 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15564 && flag_unsafe_math_optimizations"
15566 operands[2] = gen_reg_rtx (SFmode);
15567 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15570 (define_insn "atan2xf3_1"
15571 [(set (match_operand:XF 0 "register_operand" "=f")
15572 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15573 (match_operand:XF 1 "register_operand" "u")]
15575 (clobber (match_scratch:XF 3 "=1"))]
15576 "TARGET_USE_FANCY_MATH_387
15577 && flag_unsafe_math_optimizations"
15579 [(set_attr "type" "fpspc")
15580 (set_attr "mode" "XF")])
15582 (define_expand "atan2xf3"
15583 [(use (match_operand:XF 0 "register_operand" ""))
15584 (use (match_operand:XF 2 "register_operand" ""))
15585 (use (match_operand:XF 1 "register_operand" ""))]
15586 "TARGET_USE_FANCY_MATH_387
15587 && flag_unsafe_math_optimizations"
15589 rtx copy = gen_reg_rtx (XFmode);
15590 emit_move_insn (copy, operands[1]);
15591 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15595 (define_expand "atanxf2"
15596 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15597 (unspec:XF [(match_dup 2)
15598 (match_operand:XF 1 "register_operand" "")]
15600 (clobber (match_scratch:XF 3 ""))])]
15601 "TARGET_USE_FANCY_MATH_387
15602 && flag_unsafe_math_optimizations"
15604 operands[2] = gen_reg_rtx (XFmode);
15605 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15608 (define_expand "asindf2"
15609 [(set (match_dup 2)
15610 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15611 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15612 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15613 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15614 (parallel [(set (match_dup 7)
15615 (unspec:XF [(match_dup 6) (match_dup 2)]
15617 (clobber (match_scratch:XF 8 ""))])
15618 (set (match_operand:DF 0 "register_operand" "")
15619 (float_truncate:DF (match_dup 7)))]
15620 "TARGET_USE_FANCY_MATH_387
15621 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15622 && flag_unsafe_math_optimizations"
15626 for (i=2; i<8; i++)
15627 operands[i] = gen_reg_rtx (XFmode);
15629 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15632 (define_expand "asinsf2"
15633 [(set (match_dup 2)
15634 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15635 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15636 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15637 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15638 (parallel [(set (match_dup 7)
15639 (unspec:XF [(match_dup 6) (match_dup 2)]
15641 (clobber (match_scratch:XF 8 ""))])
15642 (set (match_operand:SF 0 "register_operand" "")
15643 (float_truncate:SF (match_dup 7)))]
15644 "TARGET_USE_FANCY_MATH_387
15645 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15646 && flag_unsafe_math_optimizations"
15650 for (i=2; i<8; i++)
15651 operands[i] = gen_reg_rtx (XFmode);
15653 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15656 (define_expand "asinxf2"
15657 [(set (match_dup 2)
15658 (mult:XF (match_operand:XF 1 "register_operand" "")
15660 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15661 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15662 (parallel [(set (match_operand:XF 0 "register_operand" "")
15663 (unspec:XF [(match_dup 5) (match_dup 1)]
15665 (clobber (match_scratch:XF 6 ""))])]
15666 "TARGET_USE_FANCY_MATH_387
15667 && flag_unsafe_math_optimizations"
15671 for (i=2; i<6; i++)
15672 operands[i] = gen_reg_rtx (XFmode);
15674 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15677 (define_expand "acosdf2"
15678 [(set (match_dup 2)
15679 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15680 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15681 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15682 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15683 (parallel [(set (match_dup 7)
15684 (unspec:XF [(match_dup 2) (match_dup 6)]
15686 (clobber (match_scratch:XF 8 ""))])
15687 (set (match_operand:DF 0 "register_operand" "")
15688 (float_truncate:DF (match_dup 7)))]
15689 "TARGET_USE_FANCY_MATH_387
15690 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15691 && flag_unsafe_math_optimizations"
15695 for (i=2; i<8; i++)
15696 operands[i] = gen_reg_rtx (XFmode);
15698 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15701 (define_expand "acossf2"
15702 [(set (match_dup 2)
15703 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15704 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15705 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15706 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15707 (parallel [(set (match_dup 7)
15708 (unspec:XF [(match_dup 2) (match_dup 6)]
15710 (clobber (match_scratch:XF 8 ""))])
15711 (set (match_operand:SF 0 "register_operand" "")
15712 (float_truncate:SF (match_dup 7)))]
15713 "TARGET_USE_FANCY_MATH_387
15714 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15715 && flag_unsafe_math_optimizations"
15719 for (i=2; i<8; i++)
15720 operands[i] = gen_reg_rtx (XFmode);
15722 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15725 (define_expand "acosxf2"
15726 [(set (match_dup 2)
15727 (mult:XF (match_operand:XF 1 "register_operand" "")
15729 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15730 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15731 (parallel [(set (match_operand:XF 0 "register_operand" "")
15732 (unspec:XF [(match_dup 1) (match_dup 5)]
15734 (clobber (match_scratch:XF 6 ""))])]
15735 "TARGET_USE_FANCY_MATH_387
15736 && flag_unsafe_math_optimizations"
15740 for (i=2; i<6; i++)
15741 operands[i] = gen_reg_rtx (XFmode);
15743 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15746 (define_insn "fyl2x_xf3"
15747 [(set (match_operand:XF 0 "register_operand" "=f")
15748 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15749 (match_operand:XF 1 "register_operand" "u")]
15751 (clobber (match_scratch:XF 3 "=1"))]
15752 "TARGET_USE_FANCY_MATH_387
15753 && flag_unsafe_math_optimizations"
15755 [(set_attr "type" "fpspc")
15756 (set_attr "mode" "XF")])
15758 (define_expand "logsf2"
15759 [(set (match_dup 2)
15760 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15761 (parallel [(set (match_dup 4)
15762 (unspec:XF [(match_dup 2)
15763 (match_dup 3)] UNSPEC_FYL2X))
15764 (clobber (match_scratch:XF 5 ""))])
15765 (set (match_operand:SF 0 "register_operand" "")
15766 (float_truncate:SF (match_dup 4)))]
15767 "TARGET_USE_FANCY_MATH_387
15768 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15769 && flag_unsafe_math_optimizations"
15773 operands[2] = gen_reg_rtx (XFmode);
15774 operands[3] = gen_reg_rtx (XFmode);
15775 operands[4] = gen_reg_rtx (XFmode);
15777 temp = standard_80387_constant_rtx (4); /* fldln2 */
15778 emit_move_insn (operands[3], temp);
15781 (define_expand "logdf2"
15782 [(set (match_dup 2)
15783 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15784 (parallel [(set (match_dup 4)
15785 (unspec:XF [(match_dup 2)
15786 (match_dup 3)] UNSPEC_FYL2X))
15787 (clobber (match_scratch:XF 5 ""))])
15788 (set (match_operand:DF 0 "register_operand" "")
15789 (float_truncate:DF (match_dup 4)))]
15790 "TARGET_USE_FANCY_MATH_387
15791 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15792 && flag_unsafe_math_optimizations"
15796 operands[2] = gen_reg_rtx (XFmode);
15797 operands[3] = gen_reg_rtx (XFmode);
15798 operands[4] = gen_reg_rtx (XFmode);
15800 temp = standard_80387_constant_rtx (4); /* fldln2 */
15801 emit_move_insn (operands[3], temp);
15804 (define_expand "logxf2"
15805 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15806 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15807 (match_dup 2)] UNSPEC_FYL2X))
15808 (clobber (match_scratch:XF 3 ""))])]
15809 "TARGET_USE_FANCY_MATH_387
15810 && flag_unsafe_math_optimizations"
15814 operands[2] = gen_reg_rtx (XFmode);
15815 temp = standard_80387_constant_rtx (4); /* fldln2 */
15816 emit_move_insn (operands[2], temp);
15819 (define_expand "log10sf2"
15820 [(set (match_dup 2)
15821 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15822 (parallel [(set (match_dup 4)
15823 (unspec:XF [(match_dup 2)
15824 (match_dup 3)] UNSPEC_FYL2X))
15825 (clobber (match_scratch:XF 5 ""))])
15826 (set (match_operand:SF 0 "register_operand" "")
15827 (float_truncate:SF (match_dup 4)))]
15828 "TARGET_USE_FANCY_MATH_387
15829 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15830 && flag_unsafe_math_optimizations"
15834 operands[2] = gen_reg_rtx (XFmode);
15835 operands[3] = gen_reg_rtx (XFmode);
15836 operands[4] = gen_reg_rtx (XFmode);
15838 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15839 emit_move_insn (operands[3], temp);
15842 (define_expand "log10df2"
15843 [(set (match_dup 2)
15844 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15845 (parallel [(set (match_dup 4)
15846 (unspec:XF [(match_dup 2)
15847 (match_dup 3)] UNSPEC_FYL2X))
15848 (clobber (match_scratch:XF 5 ""))])
15849 (set (match_operand:DF 0 "register_operand" "")
15850 (float_truncate:DF (match_dup 4)))]
15851 "TARGET_USE_FANCY_MATH_387
15852 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15853 && flag_unsafe_math_optimizations"
15857 operands[2] = gen_reg_rtx (XFmode);
15858 operands[3] = gen_reg_rtx (XFmode);
15859 operands[4] = gen_reg_rtx (XFmode);
15861 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15862 emit_move_insn (operands[3], temp);
15865 (define_expand "log10xf2"
15866 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15867 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15868 (match_dup 2)] UNSPEC_FYL2X))
15869 (clobber (match_scratch:XF 3 ""))])]
15870 "TARGET_USE_FANCY_MATH_387
15871 && flag_unsafe_math_optimizations"
15875 operands[2] = gen_reg_rtx (XFmode);
15876 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15877 emit_move_insn (operands[2], temp);
15880 (define_expand "log2sf2"
15881 [(set (match_dup 2)
15882 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15883 (parallel [(set (match_dup 4)
15884 (unspec:XF [(match_dup 2)
15885 (match_dup 3)] UNSPEC_FYL2X))
15886 (clobber (match_scratch:XF 5 ""))])
15887 (set (match_operand:SF 0 "register_operand" "")
15888 (float_truncate:SF (match_dup 4)))]
15889 "TARGET_USE_FANCY_MATH_387
15890 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15891 && flag_unsafe_math_optimizations"
15893 operands[2] = gen_reg_rtx (XFmode);
15894 operands[3] = gen_reg_rtx (XFmode);
15895 operands[4] = gen_reg_rtx (XFmode);
15897 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15900 (define_expand "log2df2"
15901 [(set (match_dup 2)
15902 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15903 (parallel [(set (match_dup 4)
15904 (unspec:XF [(match_dup 2)
15905 (match_dup 3)] UNSPEC_FYL2X))
15906 (clobber (match_scratch:XF 5 ""))])
15907 (set (match_operand:DF 0 "register_operand" "")
15908 (float_truncate:DF (match_dup 4)))]
15909 "TARGET_USE_FANCY_MATH_387
15910 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15911 && flag_unsafe_math_optimizations"
15913 operands[2] = gen_reg_rtx (XFmode);
15914 operands[3] = gen_reg_rtx (XFmode);
15915 operands[4] = gen_reg_rtx (XFmode);
15917 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15920 (define_expand "log2xf2"
15921 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15922 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15923 (match_dup 2)] UNSPEC_FYL2X))
15924 (clobber (match_scratch:XF 3 ""))])]
15925 "TARGET_USE_FANCY_MATH_387
15926 && flag_unsafe_math_optimizations"
15928 operands[2] = gen_reg_rtx (XFmode);
15929 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15932 (define_insn "fyl2xp1_xf3"
15933 [(set (match_operand:XF 0 "register_operand" "=f")
15934 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15935 (match_operand:XF 1 "register_operand" "u")]
15937 (clobber (match_scratch:XF 3 "=1"))]
15938 "TARGET_USE_FANCY_MATH_387
15939 && flag_unsafe_math_optimizations"
15941 [(set_attr "type" "fpspc")
15942 (set_attr "mode" "XF")])
15944 (define_expand "log1psf2"
15945 [(use (match_operand:SF 0 "register_operand" ""))
15946 (use (match_operand:SF 1 "register_operand" ""))]
15947 "TARGET_USE_FANCY_MATH_387
15948 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15949 && flag_unsafe_math_optimizations"
15951 rtx op0 = gen_reg_rtx (XFmode);
15952 rtx op1 = gen_reg_rtx (XFmode);
15954 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15955 ix86_emit_i387_log1p (op0, op1);
15956 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15960 (define_expand "log1pdf2"
15961 [(use (match_operand:DF 0 "register_operand" ""))
15962 (use (match_operand:DF 1 "register_operand" ""))]
15963 "TARGET_USE_FANCY_MATH_387
15964 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15965 && flag_unsafe_math_optimizations"
15967 rtx op0 = gen_reg_rtx (XFmode);
15968 rtx op1 = gen_reg_rtx (XFmode);
15970 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15971 ix86_emit_i387_log1p (op0, op1);
15972 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15976 (define_expand "log1pxf2"
15977 [(use (match_operand:XF 0 "register_operand" ""))
15978 (use (match_operand:XF 1 "register_operand" ""))]
15979 "TARGET_USE_FANCY_MATH_387
15980 && flag_unsafe_math_optimizations"
15982 ix86_emit_i387_log1p (operands[0], operands[1]);
15986 (define_insn "*fxtractxf3"
15987 [(set (match_operand:XF 0 "register_operand" "=f")
15988 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15989 UNSPEC_XTRACT_FRACT))
15990 (set (match_operand:XF 1 "register_operand" "=u")
15991 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15992 "TARGET_USE_FANCY_MATH_387
15993 && flag_unsafe_math_optimizations"
15995 [(set_attr "type" "fpspc")
15996 (set_attr "mode" "XF")])
15998 (define_expand "logbsf2"
15999 [(set (match_dup 2)
16000 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16001 (parallel [(set (match_dup 3)
16002 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16004 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16005 (set (match_operand:SF 0 "register_operand" "")
16006 (float_truncate:SF (match_dup 4)))]
16007 "TARGET_USE_FANCY_MATH_387
16008 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16009 && flag_unsafe_math_optimizations"
16011 operands[2] = gen_reg_rtx (XFmode);
16012 operands[3] = gen_reg_rtx (XFmode);
16013 operands[4] = gen_reg_rtx (XFmode);
16016 (define_expand "logbdf2"
16017 [(set (match_dup 2)
16018 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16019 (parallel [(set (match_dup 3)
16020 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16022 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16023 (set (match_operand:DF 0 "register_operand" "")
16024 (float_truncate:DF (match_dup 4)))]
16025 "TARGET_USE_FANCY_MATH_387
16026 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16027 && flag_unsafe_math_optimizations"
16029 operands[2] = gen_reg_rtx (XFmode);
16030 operands[3] = gen_reg_rtx (XFmode);
16031 operands[4] = gen_reg_rtx (XFmode);
16034 (define_expand "logbxf2"
16035 [(parallel [(set (match_dup 2)
16036 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16037 UNSPEC_XTRACT_FRACT))
16038 (set (match_operand:XF 0 "register_operand" "")
16039 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16040 "TARGET_USE_FANCY_MATH_387
16041 && flag_unsafe_math_optimizations"
16043 operands[2] = gen_reg_rtx (XFmode);
16046 (define_expand "ilogbsi2"
16047 [(parallel [(set (match_dup 2)
16048 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16049 UNSPEC_XTRACT_FRACT))
16050 (set (match_operand:XF 3 "register_operand" "")
16051 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16052 (parallel [(set (match_operand:SI 0 "register_operand" "")
16053 (fix:SI (match_dup 3)))
16054 (clobber (reg:CC FLAGS_REG))])]
16055 "TARGET_USE_FANCY_MATH_387
16056 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16057 && flag_unsafe_math_optimizations"
16059 operands[2] = gen_reg_rtx (XFmode);
16060 operands[3] = gen_reg_rtx (XFmode);
16063 (define_insn "*f2xm1xf2"
16064 [(set (match_operand:XF 0 "register_operand" "=f")
16065 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16067 "TARGET_USE_FANCY_MATH_387
16068 && flag_unsafe_math_optimizations"
16070 [(set_attr "type" "fpspc")
16071 (set_attr "mode" "XF")])
16073 (define_insn "*fscalexf4"
16074 [(set (match_operand:XF 0 "register_operand" "=f")
16075 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16076 (match_operand:XF 3 "register_operand" "1")]
16077 UNSPEC_FSCALE_FRACT))
16078 (set (match_operand:XF 1 "register_operand" "=u")
16079 (unspec:XF [(match_dup 2) (match_dup 3)]
16080 UNSPEC_FSCALE_EXP))]
16081 "TARGET_USE_FANCY_MATH_387
16082 && flag_unsafe_math_optimizations"
16084 [(set_attr "type" "fpspc")
16085 (set_attr "mode" "XF")])
16087 (define_expand "expsf2"
16088 [(set (match_dup 2)
16089 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16090 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16091 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16092 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16093 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16094 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16095 (parallel [(set (match_dup 10)
16096 (unspec:XF [(match_dup 9) (match_dup 5)]
16097 UNSPEC_FSCALE_FRACT))
16098 (set (match_dup 11)
16099 (unspec:XF [(match_dup 9) (match_dup 5)]
16100 UNSPEC_FSCALE_EXP))])
16101 (set (match_operand:SF 0 "register_operand" "")
16102 (float_truncate:SF (match_dup 10)))]
16103 "TARGET_USE_FANCY_MATH_387
16104 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16105 && flag_unsafe_math_optimizations"
16110 for (i=2; i<12; i++)
16111 operands[i] = gen_reg_rtx (XFmode);
16112 temp = standard_80387_constant_rtx (5); /* fldl2e */
16113 emit_move_insn (operands[3], temp);
16114 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16117 (define_expand "expdf2"
16118 [(set (match_dup 2)
16119 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16120 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16121 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16122 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16123 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16124 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16125 (parallel [(set (match_dup 10)
16126 (unspec:XF [(match_dup 9) (match_dup 5)]
16127 UNSPEC_FSCALE_FRACT))
16128 (set (match_dup 11)
16129 (unspec:XF [(match_dup 9) (match_dup 5)]
16130 UNSPEC_FSCALE_EXP))])
16131 (set (match_operand:DF 0 "register_operand" "")
16132 (float_truncate:DF (match_dup 10)))]
16133 "TARGET_USE_FANCY_MATH_387
16134 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16135 && flag_unsafe_math_optimizations"
16140 for (i=2; i<12; i++)
16141 operands[i] = gen_reg_rtx (XFmode);
16142 temp = standard_80387_constant_rtx (5); /* fldl2e */
16143 emit_move_insn (operands[3], temp);
16144 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16147 (define_expand "expxf2"
16148 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16150 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16151 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16152 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16153 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16154 (parallel [(set (match_operand:XF 0 "register_operand" "")
16155 (unspec:XF [(match_dup 8) (match_dup 4)]
16156 UNSPEC_FSCALE_FRACT))
16158 (unspec:XF [(match_dup 8) (match_dup 4)]
16159 UNSPEC_FSCALE_EXP))])]
16160 "TARGET_USE_FANCY_MATH_387
16161 && flag_unsafe_math_optimizations"
16166 for (i=2; i<10; i++)
16167 operands[i] = gen_reg_rtx (XFmode);
16168 temp = standard_80387_constant_rtx (5); /* fldl2e */
16169 emit_move_insn (operands[2], temp);
16170 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16173 (define_expand "exp10sf2"
16174 [(set (match_dup 2)
16175 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16176 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16177 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16178 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16179 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16180 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16181 (parallel [(set (match_dup 10)
16182 (unspec:XF [(match_dup 9) (match_dup 5)]
16183 UNSPEC_FSCALE_FRACT))
16184 (set (match_dup 11)
16185 (unspec:XF [(match_dup 9) (match_dup 5)]
16186 UNSPEC_FSCALE_EXP))])
16187 (set (match_operand:SF 0 "register_operand" "")
16188 (float_truncate:SF (match_dup 10)))]
16189 "TARGET_USE_FANCY_MATH_387
16190 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16191 && flag_unsafe_math_optimizations"
16196 for (i=2; i<12; i++)
16197 operands[i] = gen_reg_rtx (XFmode);
16198 temp = standard_80387_constant_rtx (6); /* fldl2t */
16199 emit_move_insn (operands[3], temp);
16200 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16203 (define_expand "exp10df2"
16204 [(set (match_dup 2)
16205 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16206 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16207 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16208 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16209 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16210 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16211 (parallel [(set (match_dup 10)
16212 (unspec:XF [(match_dup 9) (match_dup 5)]
16213 UNSPEC_FSCALE_FRACT))
16214 (set (match_dup 11)
16215 (unspec:XF [(match_dup 9) (match_dup 5)]
16216 UNSPEC_FSCALE_EXP))])
16217 (set (match_operand:DF 0 "register_operand" "")
16218 (float_truncate:DF (match_dup 10)))]
16219 "TARGET_USE_FANCY_MATH_387
16220 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16221 && flag_unsafe_math_optimizations"
16226 for (i=2; i<12; i++)
16227 operands[i] = gen_reg_rtx (XFmode);
16228 temp = standard_80387_constant_rtx (6); /* fldl2t */
16229 emit_move_insn (operands[3], temp);
16230 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16233 (define_expand "exp10xf2"
16234 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16236 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16237 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16238 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16239 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16240 (parallel [(set (match_operand:XF 0 "register_operand" "")
16241 (unspec:XF [(match_dup 8) (match_dup 4)]
16242 UNSPEC_FSCALE_FRACT))
16244 (unspec:XF [(match_dup 8) (match_dup 4)]
16245 UNSPEC_FSCALE_EXP))])]
16246 "TARGET_USE_FANCY_MATH_387
16247 && flag_unsafe_math_optimizations"
16252 for (i=2; i<10; i++)
16253 operands[i] = gen_reg_rtx (XFmode);
16254 temp = standard_80387_constant_rtx (6); /* fldl2t */
16255 emit_move_insn (operands[2], temp);
16256 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16259 (define_expand "exp2sf2"
16260 [(set (match_dup 2)
16261 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16262 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16263 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16264 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16265 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16266 (parallel [(set (match_dup 8)
16267 (unspec:XF [(match_dup 7) (match_dup 3)]
16268 UNSPEC_FSCALE_FRACT))
16270 (unspec:XF [(match_dup 7) (match_dup 3)]
16271 UNSPEC_FSCALE_EXP))])
16272 (set (match_operand:SF 0 "register_operand" "")
16273 (float_truncate:SF (match_dup 8)))]
16274 "TARGET_USE_FANCY_MATH_387
16275 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16276 && flag_unsafe_math_optimizations"
16280 for (i=2; i<10; i++)
16281 operands[i] = gen_reg_rtx (XFmode);
16282 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16285 (define_expand "exp2df2"
16286 [(set (match_dup 2)
16287 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16288 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16289 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16290 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16291 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16292 (parallel [(set (match_dup 8)
16293 (unspec:XF [(match_dup 7) (match_dup 3)]
16294 UNSPEC_FSCALE_FRACT))
16296 (unspec:XF [(match_dup 7) (match_dup 3)]
16297 UNSPEC_FSCALE_EXP))])
16298 (set (match_operand:DF 0 "register_operand" "")
16299 (float_truncate:DF (match_dup 8)))]
16300 "TARGET_USE_FANCY_MATH_387
16301 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16302 && flag_unsafe_math_optimizations"
16306 for (i=2; i<10; i++)
16307 operands[i] = gen_reg_rtx (XFmode);
16308 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16311 (define_expand "exp2xf2"
16312 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16313 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16314 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16315 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16316 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16317 (parallel [(set (match_operand:XF 0 "register_operand" "")
16318 (unspec:XF [(match_dup 7) (match_dup 3)]
16319 UNSPEC_FSCALE_FRACT))
16321 (unspec:XF [(match_dup 7) (match_dup 3)]
16322 UNSPEC_FSCALE_EXP))])]
16323 "TARGET_USE_FANCY_MATH_387
16324 && flag_unsafe_math_optimizations"
16328 for (i=2; i<9; i++)
16329 operands[i] = gen_reg_rtx (XFmode);
16330 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16333 (define_expand "expm1df2"
16334 [(set (match_dup 2)
16335 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16336 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16337 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16338 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16339 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16340 (parallel [(set (match_dup 8)
16341 (unspec:XF [(match_dup 7) (match_dup 5)]
16342 UNSPEC_FSCALE_FRACT))
16344 (unspec:XF [(match_dup 7) (match_dup 5)]
16345 UNSPEC_FSCALE_EXP))])
16346 (parallel [(set (match_dup 11)
16347 (unspec:XF [(match_dup 10) (match_dup 9)]
16348 UNSPEC_FSCALE_FRACT))
16349 (set (match_dup 12)
16350 (unspec:XF [(match_dup 10) (match_dup 9)]
16351 UNSPEC_FSCALE_EXP))])
16352 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16353 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16354 (set (match_operand:DF 0 "register_operand" "")
16355 (float_truncate:DF (match_dup 14)))]
16356 "TARGET_USE_FANCY_MATH_387
16357 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16358 && flag_unsafe_math_optimizations"
16363 for (i=2; i<15; i++)
16364 operands[i] = gen_reg_rtx (XFmode);
16365 temp = standard_80387_constant_rtx (5); /* fldl2e */
16366 emit_move_insn (operands[3], temp);
16367 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16370 (define_expand "expm1sf2"
16371 [(set (match_dup 2)
16372 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16373 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16374 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16375 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16376 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16377 (parallel [(set (match_dup 8)
16378 (unspec:XF [(match_dup 7) (match_dup 5)]
16379 UNSPEC_FSCALE_FRACT))
16381 (unspec:XF [(match_dup 7) (match_dup 5)]
16382 UNSPEC_FSCALE_EXP))])
16383 (parallel [(set (match_dup 11)
16384 (unspec:XF [(match_dup 10) (match_dup 9)]
16385 UNSPEC_FSCALE_FRACT))
16386 (set (match_dup 12)
16387 (unspec:XF [(match_dup 10) (match_dup 9)]
16388 UNSPEC_FSCALE_EXP))])
16389 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16390 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16391 (set (match_operand:SF 0 "register_operand" "")
16392 (float_truncate:SF (match_dup 14)))]
16393 "TARGET_USE_FANCY_MATH_387
16394 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16395 && flag_unsafe_math_optimizations"
16400 for (i=2; i<15; i++)
16401 operands[i] = gen_reg_rtx (XFmode);
16402 temp = standard_80387_constant_rtx (5); /* fldl2e */
16403 emit_move_insn (operands[3], temp);
16404 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16407 (define_expand "expm1xf2"
16408 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16410 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16411 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16412 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16413 (parallel [(set (match_dup 7)
16414 (unspec:XF [(match_dup 6) (match_dup 4)]
16415 UNSPEC_FSCALE_FRACT))
16417 (unspec:XF [(match_dup 6) (match_dup 4)]
16418 UNSPEC_FSCALE_EXP))])
16419 (parallel [(set (match_dup 10)
16420 (unspec:XF [(match_dup 9) (match_dup 8)]
16421 UNSPEC_FSCALE_FRACT))
16422 (set (match_dup 11)
16423 (unspec:XF [(match_dup 9) (match_dup 8)]
16424 UNSPEC_FSCALE_EXP))])
16425 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16426 (set (match_operand:XF 0 "register_operand" "")
16427 (plus:XF (match_dup 12) (match_dup 7)))]
16428 "TARGET_USE_FANCY_MATH_387
16429 && flag_unsafe_math_optimizations"
16434 for (i=2; i<13; i++)
16435 operands[i] = gen_reg_rtx (XFmode);
16436 temp = standard_80387_constant_rtx (5); /* fldl2e */
16437 emit_move_insn (operands[2], temp);
16438 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16441 (define_expand "ldexpdf3"
16442 [(set (match_dup 3)
16443 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16445 (float:XF (match_operand:SI 2 "register_operand" "")))
16446 (parallel [(set (match_dup 5)
16447 (unspec:XF [(match_dup 3) (match_dup 4)]
16448 UNSPEC_FSCALE_FRACT))
16450 (unspec:XF [(match_dup 3) (match_dup 4)]
16451 UNSPEC_FSCALE_EXP))])
16452 (set (match_operand:DF 0 "register_operand" "")
16453 (float_truncate:DF (match_dup 5)))]
16454 "TARGET_USE_FANCY_MATH_387
16455 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16456 && flag_unsafe_math_optimizations"
16460 for (i=3; i<7; i++)
16461 operands[i] = gen_reg_rtx (XFmode);
16464 (define_expand "ldexpsf3"
16465 [(set (match_dup 3)
16466 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16468 (float:XF (match_operand:SI 2 "register_operand" "")))
16469 (parallel [(set (match_dup 5)
16470 (unspec:XF [(match_dup 3) (match_dup 4)]
16471 UNSPEC_FSCALE_FRACT))
16473 (unspec:XF [(match_dup 3) (match_dup 4)]
16474 UNSPEC_FSCALE_EXP))])
16475 (set (match_operand:SF 0 "register_operand" "")
16476 (float_truncate:SF (match_dup 5)))]
16477 "TARGET_USE_FANCY_MATH_387
16478 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16479 && flag_unsafe_math_optimizations"
16483 for (i=3; i<7; i++)
16484 operands[i] = gen_reg_rtx (XFmode);
16487 (define_expand "ldexpxf3"
16488 [(set (match_dup 3)
16489 (float:XF (match_operand:SI 2 "register_operand" "")))
16490 (parallel [(set (match_operand:XF 0 " register_operand" "")
16491 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16493 UNSPEC_FSCALE_FRACT))
16495 (unspec:XF [(match_dup 1) (match_dup 3)]
16496 UNSPEC_FSCALE_EXP))])]
16497 "TARGET_USE_FANCY_MATH_387
16498 && flag_unsafe_math_optimizations"
16502 for (i=3; i<5; i++)
16503 operands[i] = gen_reg_rtx (XFmode);
16507 (define_insn "frndintxf2"
16508 [(set (match_operand:XF 0 "register_operand" "=f")
16509 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16511 "TARGET_USE_FANCY_MATH_387
16512 && flag_unsafe_math_optimizations"
16514 [(set_attr "type" "fpspc")
16515 (set_attr "mode" "XF")])
16517 (define_expand "rintdf2"
16518 [(use (match_operand:DF 0 "register_operand" ""))
16519 (use (match_operand:DF 1 "register_operand" ""))]
16520 "TARGET_USE_FANCY_MATH_387
16521 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16522 && flag_unsafe_math_optimizations"
16524 rtx op0 = gen_reg_rtx (XFmode);
16525 rtx op1 = gen_reg_rtx (XFmode);
16527 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16528 emit_insn (gen_frndintxf2 (op0, op1));
16530 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16534 (define_expand "rintsf2"
16535 [(use (match_operand:SF 0 "register_operand" ""))
16536 (use (match_operand:SF 1 "register_operand" ""))]
16537 "TARGET_USE_FANCY_MATH_387
16538 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16539 && flag_unsafe_math_optimizations"
16541 rtx op0 = gen_reg_rtx (XFmode);
16542 rtx op1 = gen_reg_rtx (XFmode);
16544 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16545 emit_insn (gen_frndintxf2 (op0, op1));
16547 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16551 (define_expand "rintxf2"
16552 [(use (match_operand:XF 0 "register_operand" ""))
16553 (use (match_operand:XF 1 "register_operand" ""))]
16554 "TARGET_USE_FANCY_MATH_387
16555 && flag_unsafe_math_optimizations"
16557 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16561 (define_insn_and_split "*fistdi2_1"
16562 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16563 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16565 "TARGET_USE_FANCY_MATH_387
16566 && flag_unsafe_math_optimizations
16567 && !(reload_completed || reload_in_progress)"
16572 if (memory_operand (operands[0], VOIDmode))
16573 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16576 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16577 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16582 [(set_attr "type" "fpspc")
16583 (set_attr "mode" "DI")])
16585 (define_insn "fistdi2"
16586 [(set (match_operand:DI 0 "memory_operand" "=m")
16587 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16589 (clobber (match_scratch:XF 2 "=&1f"))]
16590 "TARGET_USE_FANCY_MATH_387
16591 && flag_unsafe_math_optimizations"
16592 "* return output_fix_trunc (insn, operands, 0);"
16593 [(set_attr "type" "fpspc")
16594 (set_attr "mode" "DI")])
16596 (define_insn "fistdi2_with_temp"
16597 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16598 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16600 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16601 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16602 "TARGET_USE_FANCY_MATH_387
16603 && flag_unsafe_math_optimizations"
16605 [(set_attr "type" "fpspc")
16606 (set_attr "mode" "DI")])
16609 [(set (match_operand:DI 0 "register_operand" "")
16610 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16612 (clobber (match_operand:DI 2 "memory_operand" ""))
16613 (clobber (match_scratch 3 ""))]
16615 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16616 (clobber (match_dup 3))])
16617 (set (match_dup 0) (match_dup 2))]
16621 [(set (match_operand:DI 0 "memory_operand" "")
16622 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16624 (clobber (match_operand:DI 2 "memory_operand" ""))
16625 (clobber (match_scratch 3 ""))]
16627 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16628 (clobber (match_dup 3))])]
16631 (define_insn_and_split "*fist<mode>2_1"
16632 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16633 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16635 "TARGET_USE_FANCY_MATH_387
16636 && flag_unsafe_math_optimizations
16637 && !(reload_completed || reload_in_progress)"
16642 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16643 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16647 [(set_attr "type" "fpspc")
16648 (set_attr "mode" "<MODE>")])
16650 (define_insn "fist<mode>2"
16651 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16652 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16654 "TARGET_USE_FANCY_MATH_387
16655 && flag_unsafe_math_optimizations"
16656 "* return output_fix_trunc (insn, operands, 0);"
16657 [(set_attr "type" "fpspc")
16658 (set_attr "mode" "<MODE>")])
16660 (define_insn "fist<mode>2_with_temp"
16661 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16662 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16664 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16665 "TARGET_USE_FANCY_MATH_387
16666 && flag_unsafe_math_optimizations"
16668 [(set_attr "type" "fpspc")
16669 (set_attr "mode" "<MODE>")])
16672 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16673 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16675 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16677 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16679 (set (match_dup 0) (match_dup 2))]
16683 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16684 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16686 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16688 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16692 (define_expand "lrint<mode>2"
16693 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16694 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16696 "TARGET_USE_FANCY_MATH_387
16697 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16698 && flag_unsafe_math_optimizations"
16701 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16702 (define_insn_and_split "frndintxf2_floor"
16703 [(set (match_operand:XF 0 "register_operand" "=f")
16704 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16705 UNSPEC_FRNDINT_FLOOR))
16706 (clobber (reg:CC FLAGS_REG))]
16707 "TARGET_USE_FANCY_MATH_387
16708 && flag_unsafe_math_optimizations
16709 && !(reload_completed || reload_in_progress)"
16714 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16716 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16717 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16719 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16720 operands[2], operands[3]));
16723 [(set_attr "type" "frndint")
16724 (set_attr "i387_cw" "floor")
16725 (set_attr "mode" "XF")])
16727 (define_insn "frndintxf2_floor_i387"
16728 [(set (match_operand:XF 0 "register_operand" "=f")
16729 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16730 UNSPEC_FRNDINT_FLOOR))
16731 (use (match_operand:HI 2 "memory_operand" "m"))
16732 (use (match_operand:HI 3 "memory_operand" "m"))]
16733 "TARGET_USE_FANCY_MATH_387
16734 && flag_unsafe_math_optimizations"
16735 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16736 [(set_attr "type" "frndint")
16737 (set_attr "i387_cw" "floor")
16738 (set_attr "mode" "XF")])
16740 (define_expand "floorxf2"
16741 [(use (match_operand:XF 0 "register_operand" ""))
16742 (use (match_operand:XF 1 "register_operand" ""))]
16743 "TARGET_USE_FANCY_MATH_387
16744 && flag_unsafe_math_optimizations"
16746 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16750 (define_expand "floordf2"
16751 [(use (match_operand:DF 0 "register_operand" ""))
16752 (use (match_operand:DF 1 "register_operand" ""))]
16753 "TARGET_USE_FANCY_MATH_387
16754 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16755 && flag_unsafe_math_optimizations"
16757 rtx op0 = gen_reg_rtx (XFmode);
16758 rtx op1 = gen_reg_rtx (XFmode);
16760 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16761 emit_insn (gen_frndintxf2_floor (op0, op1));
16763 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16767 (define_expand "floorsf2"
16768 [(use (match_operand:SF 0 "register_operand" ""))
16769 (use (match_operand:SF 1 "register_operand" ""))]
16770 "TARGET_USE_FANCY_MATH_387
16771 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16772 && flag_unsafe_math_optimizations"
16774 rtx op0 = gen_reg_rtx (XFmode);
16775 rtx op1 = gen_reg_rtx (XFmode);
16777 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16778 emit_insn (gen_frndintxf2_floor (op0, op1));
16780 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16784 (define_insn_and_split "*fist<mode>2_floor_1"
16785 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16786 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16787 UNSPEC_FIST_FLOOR))
16788 (clobber (reg:CC FLAGS_REG))]
16789 "TARGET_USE_FANCY_MATH_387
16790 && flag_unsafe_math_optimizations
16791 && !(reload_completed || reload_in_progress)"
16796 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16798 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16799 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16800 if (memory_operand (operands[0], VOIDmode))
16801 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16802 operands[2], operands[3]));
16805 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16806 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16807 operands[2], operands[3],
16812 [(set_attr "type" "fistp")
16813 (set_attr "i387_cw" "floor")
16814 (set_attr "mode" "<MODE>")])
16816 (define_insn "fistdi2_floor"
16817 [(set (match_operand:DI 0 "memory_operand" "=m")
16818 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16819 UNSPEC_FIST_FLOOR))
16820 (use (match_operand:HI 2 "memory_operand" "m"))
16821 (use (match_operand:HI 3 "memory_operand" "m"))
16822 (clobber (match_scratch:XF 4 "=&1f"))]
16823 "TARGET_USE_FANCY_MATH_387
16824 && flag_unsafe_math_optimizations"
16825 "* return output_fix_trunc (insn, operands, 0);"
16826 [(set_attr "type" "fistp")
16827 (set_attr "i387_cw" "floor")
16828 (set_attr "mode" "DI")])
16830 (define_insn "fistdi2_floor_with_temp"
16831 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16832 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16833 UNSPEC_FIST_FLOOR))
16834 (use (match_operand:HI 2 "memory_operand" "m,m"))
16835 (use (match_operand:HI 3 "memory_operand" "m,m"))
16836 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16837 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16838 "TARGET_USE_FANCY_MATH_387
16839 && flag_unsafe_math_optimizations"
16841 [(set_attr "type" "fistp")
16842 (set_attr "i387_cw" "floor")
16843 (set_attr "mode" "DI")])
16846 [(set (match_operand:DI 0 "register_operand" "")
16847 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16848 UNSPEC_FIST_FLOOR))
16849 (use (match_operand:HI 2 "memory_operand" ""))
16850 (use (match_operand:HI 3 "memory_operand" ""))
16851 (clobber (match_operand:DI 4 "memory_operand" ""))
16852 (clobber (match_scratch 5 ""))]
16854 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16855 (use (match_dup 2))
16856 (use (match_dup 3))
16857 (clobber (match_dup 5))])
16858 (set (match_dup 0) (match_dup 4))]
16862 [(set (match_operand:DI 0 "memory_operand" "")
16863 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16864 UNSPEC_FIST_FLOOR))
16865 (use (match_operand:HI 2 "memory_operand" ""))
16866 (use (match_operand:HI 3 "memory_operand" ""))
16867 (clobber (match_operand:DI 4 "memory_operand" ""))
16868 (clobber (match_scratch 5 ""))]
16870 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16871 (use (match_dup 2))
16872 (use (match_dup 3))
16873 (clobber (match_dup 5))])]
16876 (define_insn "fist<mode>2_floor"
16877 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16878 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16879 UNSPEC_FIST_FLOOR))
16880 (use (match_operand:HI 2 "memory_operand" "m"))
16881 (use (match_operand:HI 3 "memory_operand" "m"))]
16882 "TARGET_USE_FANCY_MATH_387
16883 && flag_unsafe_math_optimizations"
16884 "* return output_fix_trunc (insn, operands, 0);"
16885 [(set_attr "type" "fistp")
16886 (set_attr "i387_cw" "floor")
16887 (set_attr "mode" "<MODE>")])
16889 (define_insn "fist<mode>2_floor_with_temp"
16890 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16891 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16892 UNSPEC_FIST_FLOOR))
16893 (use (match_operand:HI 2 "memory_operand" "m,m"))
16894 (use (match_operand:HI 3 "memory_operand" "m,m"))
16895 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16896 "TARGET_USE_FANCY_MATH_387
16897 && flag_unsafe_math_optimizations"
16899 [(set_attr "type" "fistp")
16900 (set_attr "i387_cw" "floor")
16901 (set_attr "mode" "<MODE>")])
16904 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16905 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16906 UNSPEC_FIST_FLOOR))
16907 (use (match_operand:HI 2 "memory_operand" ""))
16908 (use (match_operand:HI 3 "memory_operand" ""))
16909 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16911 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16912 UNSPEC_FIST_FLOOR))
16913 (use (match_dup 2))
16914 (use (match_dup 3))])
16915 (set (match_dup 0) (match_dup 4))]
16919 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16920 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16921 UNSPEC_FIST_FLOOR))
16922 (use (match_operand:HI 2 "memory_operand" ""))
16923 (use (match_operand:HI 3 "memory_operand" ""))
16924 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16926 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16927 UNSPEC_FIST_FLOOR))
16928 (use (match_dup 2))
16929 (use (match_dup 3))])]
16932 (define_expand "lfloor<mode>2"
16933 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16934 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16935 UNSPEC_FIST_FLOOR))
16936 (clobber (reg:CC FLAGS_REG))])]
16937 "TARGET_USE_FANCY_MATH_387
16938 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16939 && flag_unsafe_math_optimizations"
16942 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16943 (define_insn_and_split "frndintxf2_ceil"
16944 [(set (match_operand:XF 0 "register_operand" "=f")
16945 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16946 UNSPEC_FRNDINT_CEIL))
16947 (clobber (reg:CC FLAGS_REG))]
16948 "TARGET_USE_FANCY_MATH_387
16949 && flag_unsafe_math_optimizations
16950 && !(reload_completed || reload_in_progress)"
16955 ix86_optimize_mode_switching[I387_CEIL] = 1;
16957 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16958 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16960 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16961 operands[2], operands[3]));
16964 [(set_attr "type" "frndint")
16965 (set_attr "i387_cw" "ceil")
16966 (set_attr "mode" "XF")])
16968 (define_insn "frndintxf2_ceil_i387"
16969 [(set (match_operand:XF 0 "register_operand" "=f")
16970 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16971 UNSPEC_FRNDINT_CEIL))
16972 (use (match_operand:HI 2 "memory_operand" "m"))
16973 (use (match_operand:HI 3 "memory_operand" "m"))]
16974 "TARGET_USE_FANCY_MATH_387
16975 && flag_unsafe_math_optimizations"
16976 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16977 [(set_attr "type" "frndint")
16978 (set_attr "i387_cw" "ceil")
16979 (set_attr "mode" "XF")])
16981 (define_expand "ceilxf2"
16982 [(use (match_operand:XF 0 "register_operand" ""))
16983 (use (match_operand:XF 1 "register_operand" ""))]
16984 "TARGET_USE_FANCY_MATH_387
16985 && flag_unsafe_math_optimizations"
16987 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16991 (define_expand "ceildf2"
16992 [(use (match_operand:DF 0 "register_operand" ""))
16993 (use (match_operand:DF 1 "register_operand" ""))]
16994 "TARGET_USE_FANCY_MATH_387
16995 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16996 && flag_unsafe_math_optimizations"
16998 rtx op0 = gen_reg_rtx (XFmode);
16999 rtx op1 = gen_reg_rtx (XFmode);
17001 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17002 emit_insn (gen_frndintxf2_ceil (op0, op1));
17004 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17008 (define_expand "ceilsf2"
17009 [(use (match_operand:SF 0 "register_operand" ""))
17010 (use (match_operand:SF 1 "register_operand" ""))]
17011 "TARGET_USE_FANCY_MATH_387
17012 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17013 && flag_unsafe_math_optimizations"
17015 rtx op0 = gen_reg_rtx (XFmode);
17016 rtx op1 = gen_reg_rtx (XFmode);
17018 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17019 emit_insn (gen_frndintxf2_ceil (op0, op1));
17021 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17025 (define_insn_and_split "*fist<mode>2_ceil_1"
17026 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17027 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17029 (clobber (reg:CC FLAGS_REG))]
17030 "TARGET_USE_FANCY_MATH_387
17031 && flag_unsafe_math_optimizations
17032 && !(reload_completed || reload_in_progress)"
17037 ix86_optimize_mode_switching[I387_CEIL] = 1;
17039 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17040 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17041 if (memory_operand (operands[0], VOIDmode))
17042 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17043 operands[2], operands[3]));
17046 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17047 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17048 operands[2], operands[3],
17053 [(set_attr "type" "fistp")
17054 (set_attr "i387_cw" "ceil")
17055 (set_attr "mode" "<MODE>")])
17057 (define_insn "fistdi2_ceil"
17058 [(set (match_operand:DI 0 "memory_operand" "=m")
17059 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17061 (use (match_operand:HI 2 "memory_operand" "m"))
17062 (use (match_operand:HI 3 "memory_operand" "m"))
17063 (clobber (match_scratch:XF 4 "=&1f"))]
17064 "TARGET_USE_FANCY_MATH_387
17065 && flag_unsafe_math_optimizations"
17066 "* return output_fix_trunc (insn, operands, 0);"
17067 [(set_attr "type" "fistp")
17068 (set_attr "i387_cw" "ceil")
17069 (set_attr "mode" "DI")])
17071 (define_insn "fistdi2_ceil_with_temp"
17072 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17073 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17075 (use (match_operand:HI 2 "memory_operand" "m,m"))
17076 (use (match_operand:HI 3 "memory_operand" "m,m"))
17077 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17078 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17079 "TARGET_USE_FANCY_MATH_387
17080 && flag_unsafe_math_optimizations"
17082 [(set_attr "type" "fistp")
17083 (set_attr "i387_cw" "ceil")
17084 (set_attr "mode" "DI")])
17087 [(set (match_operand:DI 0 "register_operand" "")
17088 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17090 (use (match_operand:HI 2 "memory_operand" ""))
17091 (use (match_operand:HI 3 "memory_operand" ""))
17092 (clobber (match_operand:DI 4 "memory_operand" ""))
17093 (clobber (match_scratch 5 ""))]
17095 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17096 (use (match_dup 2))
17097 (use (match_dup 3))
17098 (clobber (match_dup 5))])
17099 (set (match_dup 0) (match_dup 4))]
17103 [(set (match_operand:DI 0 "memory_operand" "")
17104 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17106 (use (match_operand:HI 2 "memory_operand" ""))
17107 (use (match_operand:HI 3 "memory_operand" ""))
17108 (clobber (match_operand:DI 4 "memory_operand" ""))
17109 (clobber (match_scratch 5 ""))]
17111 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17112 (use (match_dup 2))
17113 (use (match_dup 3))
17114 (clobber (match_dup 5))])]
17117 (define_insn "fist<mode>2_ceil"
17118 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17119 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17121 (use (match_operand:HI 2 "memory_operand" "m"))
17122 (use (match_operand:HI 3 "memory_operand" "m"))]
17123 "TARGET_USE_FANCY_MATH_387
17124 && flag_unsafe_math_optimizations"
17125 "* return output_fix_trunc (insn, operands, 0);"
17126 [(set_attr "type" "fistp")
17127 (set_attr "i387_cw" "ceil")
17128 (set_attr "mode" "<MODE>")])
17130 (define_insn "fist<mode>2_ceil_with_temp"
17131 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17132 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17134 (use (match_operand:HI 2 "memory_operand" "m,m"))
17135 (use (match_operand:HI 3 "memory_operand" "m,m"))
17136 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17137 "TARGET_USE_FANCY_MATH_387
17138 && flag_unsafe_math_optimizations"
17140 [(set_attr "type" "fistp")
17141 (set_attr "i387_cw" "ceil")
17142 (set_attr "mode" "<MODE>")])
17145 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17146 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17148 (use (match_operand:HI 2 "memory_operand" ""))
17149 (use (match_operand:HI 3 "memory_operand" ""))
17150 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17152 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17154 (use (match_dup 2))
17155 (use (match_dup 3))])
17156 (set (match_dup 0) (match_dup 4))]
17160 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17161 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17163 (use (match_operand:HI 2 "memory_operand" ""))
17164 (use (match_operand:HI 3 "memory_operand" ""))
17165 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17167 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17169 (use (match_dup 2))
17170 (use (match_dup 3))])]
17173 (define_expand "lceil<mode>2"
17174 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17175 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17177 (clobber (reg:CC FLAGS_REG))])]
17178 "TARGET_USE_FANCY_MATH_387
17179 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17180 && flag_unsafe_math_optimizations"
17183 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17184 (define_insn_and_split "frndintxf2_trunc"
17185 [(set (match_operand:XF 0 "register_operand" "=f")
17186 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17187 UNSPEC_FRNDINT_TRUNC))
17188 (clobber (reg:CC FLAGS_REG))]
17189 "TARGET_USE_FANCY_MATH_387
17190 && flag_unsafe_math_optimizations
17191 && !(reload_completed || reload_in_progress)"
17196 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17198 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17199 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17201 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17202 operands[2], operands[3]));
17205 [(set_attr "type" "frndint")
17206 (set_attr "i387_cw" "trunc")
17207 (set_attr "mode" "XF")])
17209 (define_insn "frndintxf2_trunc_i387"
17210 [(set (match_operand:XF 0 "register_operand" "=f")
17211 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17212 UNSPEC_FRNDINT_TRUNC))
17213 (use (match_operand:HI 2 "memory_operand" "m"))
17214 (use (match_operand:HI 3 "memory_operand" "m"))]
17215 "TARGET_USE_FANCY_MATH_387
17216 && flag_unsafe_math_optimizations"
17217 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17218 [(set_attr "type" "frndint")
17219 (set_attr "i387_cw" "trunc")
17220 (set_attr "mode" "XF")])
17222 (define_expand "btruncxf2"
17223 [(use (match_operand:XF 0 "register_operand" ""))
17224 (use (match_operand:XF 1 "register_operand" ""))]
17225 "TARGET_USE_FANCY_MATH_387
17226 && flag_unsafe_math_optimizations"
17228 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17232 (define_expand "btruncdf2"
17233 [(use (match_operand:DF 0 "register_operand" ""))
17234 (use (match_operand:DF 1 "register_operand" ""))]
17235 "TARGET_USE_FANCY_MATH_387
17236 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17237 && flag_unsafe_math_optimizations"
17239 rtx op0 = gen_reg_rtx (XFmode);
17240 rtx op1 = gen_reg_rtx (XFmode);
17242 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17243 emit_insn (gen_frndintxf2_trunc (op0, op1));
17245 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17249 (define_expand "btruncsf2"
17250 [(use (match_operand:SF 0 "register_operand" ""))
17251 (use (match_operand:SF 1 "register_operand" ""))]
17252 "TARGET_USE_FANCY_MATH_387
17253 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17254 && flag_unsafe_math_optimizations"
17256 rtx op0 = gen_reg_rtx (XFmode);
17257 rtx op1 = gen_reg_rtx (XFmode);
17259 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17260 emit_insn (gen_frndintxf2_trunc (op0, op1));
17262 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17266 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17267 (define_insn_and_split "frndintxf2_mask_pm"
17268 [(set (match_operand:XF 0 "register_operand" "=f")
17269 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17270 UNSPEC_FRNDINT_MASK_PM))
17271 (clobber (reg:CC FLAGS_REG))]
17272 "TARGET_USE_FANCY_MATH_387
17273 && flag_unsafe_math_optimizations
17274 && !(reload_completed || reload_in_progress)"
17279 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17281 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17282 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17284 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17285 operands[2], operands[3]));
17288 [(set_attr "type" "frndint")
17289 (set_attr "i387_cw" "mask_pm")
17290 (set_attr "mode" "XF")])
17292 (define_insn "frndintxf2_mask_pm_i387"
17293 [(set (match_operand:XF 0 "register_operand" "=f")
17294 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17295 UNSPEC_FRNDINT_MASK_PM))
17296 (use (match_operand:HI 2 "memory_operand" "m"))
17297 (use (match_operand:HI 3 "memory_operand" "m"))]
17298 "TARGET_USE_FANCY_MATH_387
17299 && flag_unsafe_math_optimizations"
17300 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17301 [(set_attr "type" "frndint")
17302 (set_attr "i387_cw" "mask_pm")
17303 (set_attr "mode" "XF")])
17305 (define_expand "nearbyintxf2"
17306 [(use (match_operand:XF 0 "register_operand" ""))
17307 (use (match_operand:XF 1 "register_operand" ""))]
17308 "TARGET_USE_FANCY_MATH_387
17309 && flag_unsafe_math_optimizations"
17311 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17316 (define_expand "nearbyintdf2"
17317 [(use (match_operand:DF 0 "register_operand" ""))
17318 (use (match_operand:DF 1 "register_operand" ""))]
17319 "TARGET_USE_FANCY_MATH_387
17320 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17321 && flag_unsafe_math_optimizations"
17323 rtx op0 = gen_reg_rtx (XFmode);
17324 rtx op1 = gen_reg_rtx (XFmode);
17326 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17327 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17329 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17333 (define_expand "nearbyintsf2"
17334 [(use (match_operand:SF 0 "register_operand" ""))
17335 (use (match_operand:SF 1 "register_operand" ""))]
17336 "TARGET_USE_FANCY_MATH_387
17337 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17338 && flag_unsafe_math_optimizations"
17340 rtx op0 = gen_reg_rtx (XFmode);
17341 rtx op1 = gen_reg_rtx (XFmode);
17343 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17344 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17346 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17351 ;; Block operation instructions
17354 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17357 [(set_attr "type" "cld")])
17359 (define_expand "movmemsi"
17360 [(use (match_operand:BLK 0 "memory_operand" ""))
17361 (use (match_operand:BLK 1 "memory_operand" ""))
17362 (use (match_operand:SI 2 "nonmemory_operand" ""))
17363 (use (match_operand:SI 3 "const_int_operand" ""))]
17364 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17366 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17372 (define_expand "movmemdi"
17373 [(use (match_operand:BLK 0 "memory_operand" ""))
17374 (use (match_operand:BLK 1 "memory_operand" ""))
17375 (use (match_operand:DI 2 "nonmemory_operand" ""))
17376 (use (match_operand:DI 3 "const_int_operand" ""))]
17379 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17385 ;; Most CPUs don't like single string operations
17386 ;; Handle this case here to simplify previous expander.
17388 (define_expand "strmov"
17389 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17390 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17391 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17392 (clobber (reg:CC FLAGS_REG))])
17393 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17394 (clobber (reg:CC FLAGS_REG))])]
17397 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17399 /* If .md ever supports :P for Pmode, these can be directly
17400 in the pattern above. */
17401 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17402 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17404 if (TARGET_SINGLE_STRINGOP || optimize_size)
17406 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17407 operands[2], operands[3],
17408 operands[5], operands[6]));
17412 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17415 (define_expand "strmov_singleop"
17416 [(parallel [(set (match_operand 1 "memory_operand" "")
17417 (match_operand 3 "memory_operand" ""))
17418 (set (match_operand 0 "register_operand" "")
17419 (match_operand 4 "" ""))
17420 (set (match_operand 2 "register_operand" "")
17421 (match_operand 5 "" ""))
17422 (use (reg:SI DIRFLAG_REG))])]
17423 "TARGET_SINGLE_STRINGOP || optimize_size"
17426 (define_insn "*strmovdi_rex_1"
17427 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17428 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17429 (set (match_operand:DI 0 "register_operand" "=D")
17430 (plus:DI (match_dup 2)
17432 (set (match_operand:DI 1 "register_operand" "=S")
17433 (plus:DI (match_dup 3)
17435 (use (reg:SI DIRFLAG_REG))]
17436 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17438 [(set_attr "type" "str")
17439 (set_attr "mode" "DI")
17440 (set_attr "memory" "both")])
17442 (define_insn "*strmovsi_1"
17443 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17444 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17445 (set (match_operand:SI 0 "register_operand" "=D")
17446 (plus:SI (match_dup 2)
17448 (set (match_operand:SI 1 "register_operand" "=S")
17449 (plus:SI (match_dup 3)
17451 (use (reg:SI DIRFLAG_REG))]
17452 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17454 [(set_attr "type" "str")
17455 (set_attr "mode" "SI")
17456 (set_attr "memory" "both")])
17458 (define_insn "*strmovsi_rex_1"
17459 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17460 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17461 (set (match_operand:DI 0 "register_operand" "=D")
17462 (plus:DI (match_dup 2)
17464 (set (match_operand:DI 1 "register_operand" "=S")
17465 (plus:DI (match_dup 3)
17467 (use (reg:SI DIRFLAG_REG))]
17468 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17470 [(set_attr "type" "str")
17471 (set_attr "mode" "SI")
17472 (set_attr "memory" "both")])
17474 (define_insn "*strmovhi_1"
17475 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17476 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17477 (set (match_operand:SI 0 "register_operand" "=D")
17478 (plus:SI (match_dup 2)
17480 (set (match_operand:SI 1 "register_operand" "=S")
17481 (plus:SI (match_dup 3)
17483 (use (reg:SI DIRFLAG_REG))]
17484 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17486 [(set_attr "type" "str")
17487 (set_attr "memory" "both")
17488 (set_attr "mode" "HI")])
17490 (define_insn "*strmovhi_rex_1"
17491 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17492 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17493 (set (match_operand:DI 0 "register_operand" "=D")
17494 (plus:DI (match_dup 2)
17496 (set (match_operand:DI 1 "register_operand" "=S")
17497 (plus:DI (match_dup 3)
17499 (use (reg:SI DIRFLAG_REG))]
17500 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17502 [(set_attr "type" "str")
17503 (set_attr "memory" "both")
17504 (set_attr "mode" "HI")])
17506 (define_insn "*strmovqi_1"
17507 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17508 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17509 (set (match_operand:SI 0 "register_operand" "=D")
17510 (plus:SI (match_dup 2)
17512 (set (match_operand:SI 1 "register_operand" "=S")
17513 (plus:SI (match_dup 3)
17515 (use (reg:SI DIRFLAG_REG))]
17516 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17518 [(set_attr "type" "str")
17519 (set_attr "memory" "both")
17520 (set_attr "mode" "QI")])
17522 (define_insn "*strmovqi_rex_1"
17523 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17524 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17525 (set (match_operand:DI 0 "register_operand" "=D")
17526 (plus:DI (match_dup 2)
17528 (set (match_operand:DI 1 "register_operand" "=S")
17529 (plus:DI (match_dup 3)
17531 (use (reg:SI DIRFLAG_REG))]
17532 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17534 [(set_attr "type" "str")
17535 (set_attr "memory" "both")
17536 (set_attr "mode" "QI")])
17538 (define_expand "rep_mov"
17539 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17540 (set (match_operand 0 "register_operand" "")
17541 (match_operand 5 "" ""))
17542 (set (match_operand 2 "register_operand" "")
17543 (match_operand 6 "" ""))
17544 (set (match_operand 1 "memory_operand" "")
17545 (match_operand 3 "memory_operand" ""))
17546 (use (match_dup 4))
17547 (use (reg:SI DIRFLAG_REG))])]
17551 (define_insn "*rep_movdi_rex64"
17552 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17553 (set (match_operand:DI 0 "register_operand" "=D")
17554 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17556 (match_operand:DI 3 "register_operand" "0")))
17557 (set (match_operand:DI 1 "register_operand" "=S")
17558 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17559 (match_operand:DI 4 "register_operand" "1")))
17560 (set (mem:BLK (match_dup 3))
17561 (mem:BLK (match_dup 4)))
17562 (use (match_dup 5))
17563 (use (reg:SI DIRFLAG_REG))]
17565 "{rep\;movsq|rep movsq}"
17566 [(set_attr "type" "str")
17567 (set_attr "prefix_rep" "1")
17568 (set_attr "memory" "both")
17569 (set_attr "mode" "DI")])
17571 (define_insn "*rep_movsi"
17572 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17573 (set (match_operand:SI 0 "register_operand" "=D")
17574 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17576 (match_operand:SI 3 "register_operand" "0")))
17577 (set (match_operand:SI 1 "register_operand" "=S")
17578 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17579 (match_operand:SI 4 "register_operand" "1")))
17580 (set (mem:BLK (match_dup 3))
17581 (mem:BLK (match_dup 4)))
17582 (use (match_dup 5))
17583 (use (reg:SI DIRFLAG_REG))]
17585 "{rep\;movsl|rep movsd}"
17586 [(set_attr "type" "str")
17587 (set_attr "prefix_rep" "1")
17588 (set_attr "memory" "both")
17589 (set_attr "mode" "SI")])
17591 (define_insn "*rep_movsi_rex64"
17592 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17593 (set (match_operand:DI 0 "register_operand" "=D")
17594 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17596 (match_operand:DI 3 "register_operand" "0")))
17597 (set (match_operand:DI 1 "register_operand" "=S")
17598 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17599 (match_operand:DI 4 "register_operand" "1")))
17600 (set (mem:BLK (match_dup 3))
17601 (mem:BLK (match_dup 4)))
17602 (use (match_dup 5))
17603 (use (reg:SI DIRFLAG_REG))]
17605 "{rep\;movsl|rep movsd}"
17606 [(set_attr "type" "str")
17607 (set_attr "prefix_rep" "1")
17608 (set_attr "memory" "both")
17609 (set_attr "mode" "SI")])
17611 (define_insn "*rep_movqi"
17612 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17613 (set (match_operand:SI 0 "register_operand" "=D")
17614 (plus:SI (match_operand:SI 3 "register_operand" "0")
17615 (match_operand:SI 5 "register_operand" "2")))
17616 (set (match_operand:SI 1 "register_operand" "=S")
17617 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17618 (set (mem:BLK (match_dup 3))
17619 (mem:BLK (match_dup 4)))
17620 (use (match_dup 5))
17621 (use (reg:SI DIRFLAG_REG))]
17623 "{rep\;movsb|rep movsb}"
17624 [(set_attr "type" "str")
17625 (set_attr "prefix_rep" "1")
17626 (set_attr "memory" "both")
17627 (set_attr "mode" "SI")])
17629 (define_insn "*rep_movqi_rex64"
17630 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17631 (set (match_operand:DI 0 "register_operand" "=D")
17632 (plus:DI (match_operand:DI 3 "register_operand" "0")
17633 (match_operand:DI 5 "register_operand" "2")))
17634 (set (match_operand:DI 1 "register_operand" "=S")
17635 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17636 (set (mem:BLK (match_dup 3))
17637 (mem:BLK (match_dup 4)))
17638 (use (match_dup 5))
17639 (use (reg:SI DIRFLAG_REG))]
17641 "{rep\;movsb|rep movsb}"
17642 [(set_attr "type" "str")
17643 (set_attr "prefix_rep" "1")
17644 (set_attr "memory" "both")
17645 (set_attr "mode" "SI")])
17647 (define_expand "setmemsi"
17648 [(use (match_operand:BLK 0 "memory_operand" ""))
17649 (use (match_operand:SI 1 "nonmemory_operand" ""))
17650 (use (match_operand 2 "const_int_operand" ""))
17651 (use (match_operand 3 "const_int_operand" ""))]
17654 /* If value to set is not zero, use the library routine. */
17655 if (operands[2] != const0_rtx)
17658 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17664 (define_expand "setmemdi"
17665 [(use (match_operand:BLK 0 "memory_operand" ""))
17666 (use (match_operand:DI 1 "nonmemory_operand" ""))
17667 (use (match_operand 2 "const_int_operand" ""))
17668 (use (match_operand 3 "const_int_operand" ""))]
17671 /* If value to set is not zero, use the library routine. */
17672 if (operands[2] != const0_rtx)
17675 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
17681 ;; Most CPUs don't like single string operations
17682 ;; Handle this case here to simplify previous expander.
17684 (define_expand "strset"
17685 [(set (match_operand 1 "memory_operand" "")
17686 (match_operand 2 "register_operand" ""))
17687 (parallel [(set (match_operand 0 "register_operand" "")
17689 (clobber (reg:CC FLAGS_REG))])]
17692 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17693 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17695 /* If .md ever supports :P for Pmode, this can be directly
17696 in the pattern above. */
17697 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17698 GEN_INT (GET_MODE_SIZE (GET_MODE
17700 if (TARGET_SINGLE_STRINGOP || optimize_size)
17702 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17708 (define_expand "strset_singleop"
17709 [(parallel [(set (match_operand 1 "memory_operand" "")
17710 (match_operand 2 "register_operand" ""))
17711 (set (match_operand 0 "register_operand" "")
17712 (match_operand 3 "" ""))
17713 (use (reg:SI DIRFLAG_REG))])]
17714 "TARGET_SINGLE_STRINGOP || optimize_size"
17717 (define_insn "*strsetdi_rex_1"
17718 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17719 (match_operand:DI 2 "register_operand" "a"))
17720 (set (match_operand:DI 0 "register_operand" "=D")
17721 (plus:DI (match_dup 1)
17723 (use (reg:SI DIRFLAG_REG))]
17724 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17726 [(set_attr "type" "str")
17727 (set_attr "memory" "store")
17728 (set_attr "mode" "DI")])
17730 (define_insn "*strsetsi_1"
17731 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17732 (match_operand:SI 2 "register_operand" "a"))
17733 (set (match_operand:SI 0 "register_operand" "=D")
17734 (plus:SI (match_dup 1)
17736 (use (reg:SI DIRFLAG_REG))]
17737 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17739 [(set_attr "type" "str")
17740 (set_attr "memory" "store")
17741 (set_attr "mode" "SI")])
17743 (define_insn "*strsetsi_rex_1"
17744 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17745 (match_operand:SI 2 "register_operand" "a"))
17746 (set (match_operand:DI 0 "register_operand" "=D")
17747 (plus:DI (match_dup 1)
17749 (use (reg:SI DIRFLAG_REG))]
17750 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17752 [(set_attr "type" "str")
17753 (set_attr "memory" "store")
17754 (set_attr "mode" "SI")])
17756 (define_insn "*strsethi_1"
17757 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17758 (match_operand:HI 2 "register_operand" "a"))
17759 (set (match_operand:SI 0 "register_operand" "=D")
17760 (plus:SI (match_dup 1)
17762 (use (reg:SI DIRFLAG_REG))]
17763 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17765 [(set_attr "type" "str")
17766 (set_attr "memory" "store")
17767 (set_attr "mode" "HI")])
17769 (define_insn "*strsethi_rex_1"
17770 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17771 (match_operand:HI 2 "register_operand" "a"))
17772 (set (match_operand:DI 0 "register_operand" "=D")
17773 (plus:DI (match_dup 1)
17775 (use (reg:SI DIRFLAG_REG))]
17776 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17778 [(set_attr "type" "str")
17779 (set_attr "memory" "store")
17780 (set_attr "mode" "HI")])
17782 (define_insn "*strsetqi_1"
17783 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17784 (match_operand:QI 2 "register_operand" "a"))
17785 (set (match_operand:SI 0 "register_operand" "=D")
17786 (plus:SI (match_dup 1)
17788 (use (reg:SI DIRFLAG_REG))]
17789 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17791 [(set_attr "type" "str")
17792 (set_attr "memory" "store")
17793 (set_attr "mode" "QI")])
17795 (define_insn "*strsetqi_rex_1"
17796 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17797 (match_operand:QI 2 "register_operand" "a"))
17798 (set (match_operand:DI 0 "register_operand" "=D")
17799 (plus:DI (match_dup 1)
17801 (use (reg:SI DIRFLAG_REG))]
17802 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17804 [(set_attr "type" "str")
17805 (set_attr "memory" "store")
17806 (set_attr "mode" "QI")])
17808 (define_expand "rep_stos"
17809 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17810 (set (match_operand 0 "register_operand" "")
17811 (match_operand 4 "" ""))
17812 (set (match_operand 2 "memory_operand" "") (const_int 0))
17813 (use (match_operand 3 "register_operand" ""))
17814 (use (match_dup 1))
17815 (use (reg:SI DIRFLAG_REG))])]
17819 (define_insn "*rep_stosdi_rex64"
17820 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17821 (set (match_operand:DI 0 "register_operand" "=D")
17822 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17824 (match_operand:DI 3 "register_operand" "0")))
17825 (set (mem:BLK (match_dup 3))
17827 (use (match_operand:DI 2 "register_operand" "a"))
17828 (use (match_dup 4))
17829 (use (reg:SI DIRFLAG_REG))]
17831 "{rep\;stosq|rep stosq}"
17832 [(set_attr "type" "str")
17833 (set_attr "prefix_rep" "1")
17834 (set_attr "memory" "store")
17835 (set_attr "mode" "DI")])
17837 (define_insn "*rep_stossi"
17838 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17839 (set (match_operand:SI 0 "register_operand" "=D")
17840 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17842 (match_operand:SI 3 "register_operand" "0")))
17843 (set (mem:BLK (match_dup 3))
17845 (use (match_operand:SI 2 "register_operand" "a"))
17846 (use (match_dup 4))
17847 (use (reg:SI DIRFLAG_REG))]
17849 "{rep\;stosl|rep stosd}"
17850 [(set_attr "type" "str")
17851 (set_attr "prefix_rep" "1")
17852 (set_attr "memory" "store")
17853 (set_attr "mode" "SI")])
17855 (define_insn "*rep_stossi_rex64"
17856 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17857 (set (match_operand:DI 0 "register_operand" "=D")
17858 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17860 (match_operand:DI 3 "register_operand" "0")))
17861 (set (mem:BLK (match_dup 3))
17863 (use (match_operand:SI 2 "register_operand" "a"))
17864 (use (match_dup 4))
17865 (use (reg:SI DIRFLAG_REG))]
17867 "{rep\;stosl|rep stosd}"
17868 [(set_attr "type" "str")
17869 (set_attr "prefix_rep" "1")
17870 (set_attr "memory" "store")
17871 (set_attr "mode" "SI")])
17873 (define_insn "*rep_stosqi"
17874 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17875 (set (match_operand:SI 0 "register_operand" "=D")
17876 (plus:SI (match_operand:SI 3 "register_operand" "0")
17877 (match_operand:SI 4 "register_operand" "1")))
17878 (set (mem:BLK (match_dup 3))
17880 (use (match_operand:QI 2 "register_operand" "a"))
17881 (use (match_dup 4))
17882 (use (reg:SI DIRFLAG_REG))]
17884 "{rep\;stosb|rep stosb}"
17885 [(set_attr "type" "str")
17886 (set_attr "prefix_rep" "1")
17887 (set_attr "memory" "store")
17888 (set_attr "mode" "QI")])
17890 (define_insn "*rep_stosqi_rex64"
17891 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17892 (set (match_operand:DI 0 "register_operand" "=D")
17893 (plus:DI (match_operand:DI 3 "register_operand" "0")
17894 (match_operand:DI 4 "register_operand" "1")))
17895 (set (mem:BLK (match_dup 3))
17897 (use (match_operand:QI 2 "register_operand" "a"))
17898 (use (match_dup 4))
17899 (use (reg:SI DIRFLAG_REG))]
17901 "{rep\;stosb|rep stosb}"
17902 [(set_attr "type" "str")
17903 (set_attr "prefix_rep" "1")
17904 (set_attr "memory" "store")
17905 (set_attr "mode" "QI")])
17907 (define_expand "cmpstrnsi"
17908 [(set (match_operand:SI 0 "register_operand" "")
17909 (compare:SI (match_operand:BLK 1 "general_operand" "")
17910 (match_operand:BLK 2 "general_operand" "")))
17911 (use (match_operand 3 "general_operand" ""))
17912 (use (match_operand 4 "immediate_operand" ""))]
17913 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17915 rtx addr1, addr2, out, outlow, count, countreg, align;
17917 /* Can't use this if the user has appropriated esi or edi. */
17918 if (global_regs[4] || global_regs[5])
17922 if (GET_CODE (out) != REG)
17923 out = gen_reg_rtx (SImode);
17925 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17926 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17927 if (addr1 != XEXP (operands[1], 0))
17928 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17929 if (addr2 != XEXP (operands[2], 0))
17930 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17932 count = operands[3];
17933 countreg = ix86_zero_extend_to_Pmode (count);
17935 /* %%% Iff we are testing strict equality, we can use known alignment
17936 to good advantage. This may be possible with combine, particularly
17937 once cc0 is dead. */
17938 align = operands[4];
17940 emit_insn (gen_cld ());
17941 if (GET_CODE (count) == CONST_INT)
17943 if (INTVAL (count) == 0)
17945 emit_move_insn (operands[0], const0_rtx);
17948 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17949 operands[1], operands[2]));
17954 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17956 emit_insn (gen_cmpsi_1 (countreg, countreg));
17957 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17958 operands[1], operands[2]));
17961 outlow = gen_lowpart (QImode, out);
17962 emit_insn (gen_cmpintqi (outlow));
17963 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17965 if (operands[0] != out)
17966 emit_move_insn (operands[0], out);
17971 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17973 (define_expand "cmpintqi"
17974 [(set (match_dup 1)
17975 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17977 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17978 (parallel [(set (match_operand:QI 0 "register_operand" "")
17979 (minus:QI (match_dup 1)
17981 (clobber (reg:CC FLAGS_REG))])]
17983 "operands[1] = gen_reg_rtx (QImode);
17984 operands[2] = gen_reg_rtx (QImode);")
17986 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17987 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17989 (define_expand "cmpstrnqi_nz_1"
17990 [(parallel [(set (reg:CC FLAGS_REG)
17991 (compare:CC (match_operand 4 "memory_operand" "")
17992 (match_operand 5 "memory_operand" "")))
17993 (use (match_operand 2 "register_operand" ""))
17994 (use (match_operand:SI 3 "immediate_operand" ""))
17995 (use (reg:SI DIRFLAG_REG))
17996 (clobber (match_operand 0 "register_operand" ""))
17997 (clobber (match_operand 1 "register_operand" ""))
17998 (clobber (match_dup 2))])]
18002 (define_insn "*cmpstrnqi_nz_1"
18003 [(set (reg:CC FLAGS_REG)
18004 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18005 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18006 (use (match_operand:SI 6 "register_operand" "2"))
18007 (use (match_operand:SI 3 "immediate_operand" "i"))
18008 (use (reg:SI DIRFLAG_REG))
18009 (clobber (match_operand:SI 0 "register_operand" "=S"))
18010 (clobber (match_operand:SI 1 "register_operand" "=D"))
18011 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18014 [(set_attr "type" "str")
18015 (set_attr "mode" "QI")
18016 (set_attr "prefix_rep" "1")])
18018 (define_insn "*cmpstrnqi_nz_rex_1"
18019 [(set (reg:CC FLAGS_REG)
18020 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18021 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18022 (use (match_operand:DI 6 "register_operand" "2"))
18023 (use (match_operand:SI 3 "immediate_operand" "i"))
18024 (use (reg:SI DIRFLAG_REG))
18025 (clobber (match_operand:DI 0 "register_operand" "=S"))
18026 (clobber (match_operand:DI 1 "register_operand" "=D"))
18027 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18030 [(set_attr "type" "str")
18031 (set_attr "mode" "QI")
18032 (set_attr "prefix_rep" "1")])
18034 ;; The same, but the count is not known to not be zero.
18036 (define_expand "cmpstrnqi_1"
18037 [(parallel [(set (reg:CC FLAGS_REG)
18038 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18040 (compare:CC (match_operand 4 "memory_operand" "")
18041 (match_operand 5 "memory_operand" ""))
18043 (use (match_operand:SI 3 "immediate_operand" ""))
18044 (use (reg:CC FLAGS_REG))
18045 (use (reg:SI DIRFLAG_REG))
18046 (clobber (match_operand 0 "register_operand" ""))
18047 (clobber (match_operand 1 "register_operand" ""))
18048 (clobber (match_dup 2))])]
18052 (define_insn "*cmpstrnqi_1"
18053 [(set (reg:CC FLAGS_REG)
18054 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18056 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18057 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18059 (use (match_operand:SI 3 "immediate_operand" "i"))
18060 (use (reg:CC FLAGS_REG))
18061 (use (reg:SI DIRFLAG_REG))
18062 (clobber (match_operand:SI 0 "register_operand" "=S"))
18063 (clobber (match_operand:SI 1 "register_operand" "=D"))
18064 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18067 [(set_attr "type" "str")
18068 (set_attr "mode" "QI")
18069 (set_attr "prefix_rep" "1")])
18071 (define_insn "*cmpstrnqi_rex_1"
18072 [(set (reg:CC FLAGS_REG)
18073 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18075 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18076 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18078 (use (match_operand:SI 3 "immediate_operand" "i"))
18079 (use (reg:CC FLAGS_REG))
18080 (use (reg:SI DIRFLAG_REG))
18081 (clobber (match_operand:DI 0 "register_operand" "=S"))
18082 (clobber (match_operand:DI 1 "register_operand" "=D"))
18083 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18086 [(set_attr "type" "str")
18087 (set_attr "mode" "QI")
18088 (set_attr "prefix_rep" "1")])
18090 (define_expand "strlensi"
18091 [(set (match_operand:SI 0 "register_operand" "")
18092 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18093 (match_operand:QI 2 "immediate_operand" "")
18094 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18097 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18103 (define_expand "strlendi"
18104 [(set (match_operand:DI 0 "register_operand" "")
18105 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18106 (match_operand:QI 2 "immediate_operand" "")
18107 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18110 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18116 (define_expand "strlenqi_1"
18117 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18118 (use (reg:SI DIRFLAG_REG))
18119 (clobber (match_operand 1 "register_operand" ""))
18120 (clobber (reg:CC FLAGS_REG))])]
18124 (define_insn "*strlenqi_1"
18125 [(set (match_operand:SI 0 "register_operand" "=&c")
18126 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18127 (match_operand:QI 2 "register_operand" "a")
18128 (match_operand:SI 3 "immediate_operand" "i")
18129 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18130 (use (reg:SI DIRFLAG_REG))
18131 (clobber (match_operand:SI 1 "register_operand" "=D"))
18132 (clobber (reg:CC FLAGS_REG))]
18135 [(set_attr "type" "str")
18136 (set_attr "mode" "QI")
18137 (set_attr "prefix_rep" "1")])
18139 (define_insn "*strlenqi_rex_1"
18140 [(set (match_operand:DI 0 "register_operand" "=&c")
18141 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18142 (match_operand:QI 2 "register_operand" "a")
18143 (match_operand:DI 3 "immediate_operand" "i")
18144 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18145 (use (reg:SI DIRFLAG_REG))
18146 (clobber (match_operand:DI 1 "register_operand" "=D"))
18147 (clobber (reg:CC FLAGS_REG))]
18150 [(set_attr "type" "str")
18151 (set_attr "mode" "QI")
18152 (set_attr "prefix_rep" "1")])
18154 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18155 ;; handled in combine, but it is not currently up to the task.
18156 ;; When used for their truth value, the cmpstrn* expanders generate
18165 ;; The intermediate three instructions are unnecessary.
18167 ;; This one handles cmpstrn*_nz_1...
18170 (set (reg:CC FLAGS_REG)
18171 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18172 (mem:BLK (match_operand 5 "register_operand" ""))))
18173 (use (match_operand 6 "register_operand" ""))
18174 (use (match_operand:SI 3 "immediate_operand" ""))
18175 (use (reg:SI DIRFLAG_REG))
18176 (clobber (match_operand 0 "register_operand" ""))
18177 (clobber (match_operand 1 "register_operand" ""))
18178 (clobber (match_operand 2 "register_operand" ""))])
18179 (set (match_operand:QI 7 "register_operand" "")
18180 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18181 (set (match_operand:QI 8 "register_operand" "")
18182 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18183 (set (reg FLAGS_REG)
18184 (compare (match_dup 7) (match_dup 8)))
18186 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18188 (set (reg:CC FLAGS_REG)
18189 (compare:CC (mem:BLK (match_dup 4))
18190 (mem:BLK (match_dup 5))))
18191 (use (match_dup 6))
18192 (use (match_dup 3))
18193 (use (reg:SI DIRFLAG_REG))
18194 (clobber (match_dup 0))
18195 (clobber (match_dup 1))
18196 (clobber (match_dup 2))])]
18199 ;; ...and this one handles cmpstrn*_1.
18202 (set (reg:CC FLAGS_REG)
18203 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18205 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18206 (mem:BLK (match_operand 5 "register_operand" "")))
18208 (use (match_operand:SI 3 "immediate_operand" ""))
18209 (use (reg:CC FLAGS_REG))
18210 (use (reg:SI DIRFLAG_REG))
18211 (clobber (match_operand 0 "register_operand" ""))
18212 (clobber (match_operand 1 "register_operand" ""))
18213 (clobber (match_operand 2 "register_operand" ""))])
18214 (set (match_operand:QI 7 "register_operand" "")
18215 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18216 (set (match_operand:QI 8 "register_operand" "")
18217 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18218 (set (reg FLAGS_REG)
18219 (compare (match_dup 7) (match_dup 8)))
18221 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18223 (set (reg:CC FLAGS_REG)
18224 (if_then_else:CC (ne (match_dup 6)
18226 (compare:CC (mem:BLK (match_dup 4))
18227 (mem:BLK (match_dup 5)))
18229 (use (match_dup 3))
18230 (use (reg:CC FLAGS_REG))
18231 (use (reg:SI DIRFLAG_REG))
18232 (clobber (match_dup 0))
18233 (clobber (match_dup 1))
18234 (clobber (match_dup 2))])]
18239 ;; Conditional move instructions.
18241 (define_expand "movdicc"
18242 [(set (match_operand:DI 0 "register_operand" "")
18243 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18244 (match_operand:DI 2 "general_operand" "")
18245 (match_operand:DI 3 "general_operand" "")))]
18247 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18249 (define_insn "x86_movdicc_0_m1_rex64"
18250 [(set (match_operand:DI 0 "register_operand" "=r")
18251 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18254 (clobber (reg:CC FLAGS_REG))]
18257 ; Since we don't have the proper number of operands for an alu insn,
18258 ; fill in all the blanks.
18259 [(set_attr "type" "alu")
18260 (set_attr "pent_pair" "pu")
18261 (set_attr "memory" "none")
18262 (set_attr "imm_disp" "false")
18263 (set_attr "mode" "DI")
18264 (set_attr "length_immediate" "0")])
18266 (define_insn "*movdicc_c_rex64"
18267 [(set (match_operand:DI 0 "register_operand" "=r,r")
18268 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18269 [(reg FLAGS_REG) (const_int 0)])
18270 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18271 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18272 "TARGET_64BIT && TARGET_CMOVE
18273 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18275 cmov%O2%C1\t{%2, %0|%0, %2}
18276 cmov%O2%c1\t{%3, %0|%0, %3}"
18277 [(set_attr "type" "icmov")
18278 (set_attr "mode" "DI")])
18280 (define_expand "movsicc"
18281 [(set (match_operand:SI 0 "register_operand" "")
18282 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18283 (match_operand:SI 2 "general_operand" "")
18284 (match_operand:SI 3 "general_operand" "")))]
18286 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18288 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18289 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18290 ;; So just document what we're doing explicitly.
18292 (define_insn "x86_movsicc_0_m1"
18293 [(set (match_operand:SI 0 "register_operand" "=r")
18294 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18297 (clobber (reg:CC FLAGS_REG))]
18300 ; Since we don't have the proper number of operands for an alu insn,
18301 ; fill in all the blanks.
18302 [(set_attr "type" "alu")
18303 (set_attr "pent_pair" "pu")
18304 (set_attr "memory" "none")
18305 (set_attr "imm_disp" "false")
18306 (set_attr "mode" "SI")
18307 (set_attr "length_immediate" "0")])
18309 (define_insn "*movsicc_noc"
18310 [(set (match_operand:SI 0 "register_operand" "=r,r")
18311 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18312 [(reg FLAGS_REG) (const_int 0)])
18313 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18314 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18316 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18318 cmov%O2%C1\t{%2, %0|%0, %2}
18319 cmov%O2%c1\t{%3, %0|%0, %3}"
18320 [(set_attr "type" "icmov")
18321 (set_attr "mode" "SI")])
18323 (define_expand "movhicc"
18324 [(set (match_operand:HI 0 "register_operand" "")
18325 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18326 (match_operand:HI 2 "general_operand" "")
18327 (match_operand:HI 3 "general_operand" "")))]
18328 "TARGET_HIMODE_MATH"
18329 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18331 (define_insn "*movhicc_noc"
18332 [(set (match_operand:HI 0 "register_operand" "=r,r")
18333 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18334 [(reg FLAGS_REG) (const_int 0)])
18335 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18336 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18338 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18340 cmov%O2%C1\t{%2, %0|%0, %2}
18341 cmov%O2%c1\t{%3, %0|%0, %3}"
18342 [(set_attr "type" "icmov")
18343 (set_attr "mode" "HI")])
18345 (define_expand "movqicc"
18346 [(set (match_operand:QI 0 "register_operand" "")
18347 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18348 (match_operand:QI 2 "general_operand" "")
18349 (match_operand:QI 3 "general_operand" "")))]
18350 "TARGET_QIMODE_MATH"
18351 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18353 (define_insn_and_split "*movqicc_noc"
18354 [(set (match_operand:QI 0 "register_operand" "=r,r")
18355 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18356 [(match_operand 4 "flags_reg_operand" "")
18358 (match_operand:QI 2 "register_operand" "r,0")
18359 (match_operand:QI 3 "register_operand" "0,r")))]
18360 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18362 "&& reload_completed"
18363 [(set (match_dup 0)
18364 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18367 "operands[0] = gen_lowpart (SImode, operands[0]);
18368 operands[2] = gen_lowpart (SImode, operands[2]);
18369 operands[3] = gen_lowpart (SImode, operands[3]);"
18370 [(set_attr "type" "icmov")
18371 (set_attr "mode" "SI")])
18373 (define_expand "movsfcc"
18374 [(set (match_operand:SF 0 "register_operand" "")
18375 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18376 (match_operand:SF 2 "register_operand" "")
18377 (match_operand:SF 3 "register_operand" "")))]
18378 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18379 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18381 (define_insn "*movsfcc_1_387"
18382 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18383 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18384 [(reg FLAGS_REG) (const_int 0)])
18385 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18386 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18387 "TARGET_80387 && TARGET_CMOVE
18388 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18390 fcmov%F1\t{%2, %0|%0, %2}
18391 fcmov%f1\t{%3, %0|%0, %3}
18392 cmov%O2%C1\t{%2, %0|%0, %2}
18393 cmov%O2%c1\t{%3, %0|%0, %3}"
18394 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18395 (set_attr "mode" "SF,SF,SI,SI")])
18397 (define_expand "movdfcc"
18398 [(set (match_operand:DF 0 "register_operand" "")
18399 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18400 (match_operand:DF 2 "register_operand" "")
18401 (match_operand:DF 3 "register_operand" "")))]
18402 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18403 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18405 (define_insn "*movdfcc_1"
18406 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18407 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18408 [(reg FLAGS_REG) (const_int 0)])
18409 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18410 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18411 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18412 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18414 fcmov%F1\t{%2, %0|%0, %2}
18415 fcmov%f1\t{%3, %0|%0, %3}
18418 [(set_attr "type" "fcmov,fcmov,multi,multi")
18419 (set_attr "mode" "DF")])
18421 (define_insn "*movdfcc_1_rex64"
18422 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18423 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18424 [(reg FLAGS_REG) (const_int 0)])
18425 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18426 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18427 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18428 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18430 fcmov%F1\t{%2, %0|%0, %2}
18431 fcmov%f1\t{%3, %0|%0, %3}
18432 cmov%O2%C1\t{%2, %0|%0, %2}
18433 cmov%O2%c1\t{%3, %0|%0, %3}"
18434 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18435 (set_attr "mode" "DF")])
18438 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18439 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18440 [(match_operand 4 "flags_reg_operand" "")
18442 (match_operand:DF 2 "nonimmediate_operand" "")
18443 (match_operand:DF 3 "nonimmediate_operand" "")))]
18444 "!TARGET_64BIT && reload_completed"
18445 [(set (match_dup 2)
18446 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18450 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18453 "split_di (operands+2, 1, operands+5, operands+6);
18454 split_di (operands+3, 1, operands+7, operands+8);
18455 split_di (operands, 1, operands+2, operands+3);")
18457 (define_expand "movxfcc"
18458 [(set (match_operand:XF 0 "register_operand" "")
18459 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18460 (match_operand:XF 2 "register_operand" "")
18461 (match_operand:XF 3 "register_operand" "")))]
18462 "TARGET_80387 && TARGET_CMOVE"
18463 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18465 (define_insn "*movxfcc_1"
18466 [(set (match_operand:XF 0 "register_operand" "=f,f")
18467 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18468 [(reg FLAGS_REG) (const_int 0)])
18469 (match_operand:XF 2 "register_operand" "f,0")
18470 (match_operand:XF 3 "register_operand" "0,f")))]
18471 "TARGET_80387 && TARGET_CMOVE"
18473 fcmov%F1\t{%2, %0|%0, %2}
18474 fcmov%f1\t{%3, %0|%0, %3}"
18475 [(set_attr "type" "fcmov")
18476 (set_attr "mode" "XF")])
18478 ;; These versions of the min/max patterns are intentionally ignorant of
18479 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18480 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18481 ;; are undefined in this condition, we're certain this is correct.
18483 (define_insn "sminsf3"
18484 [(set (match_operand:SF 0 "register_operand" "=x")
18485 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18486 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18488 "minss\t{%2, %0|%0, %2}"
18489 [(set_attr "type" "sseadd")
18490 (set_attr "mode" "SF")])
18492 (define_insn "smaxsf3"
18493 [(set (match_operand:SF 0 "register_operand" "=x")
18494 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18495 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18497 "maxss\t{%2, %0|%0, %2}"
18498 [(set_attr "type" "sseadd")
18499 (set_attr "mode" "SF")])
18501 (define_insn "smindf3"
18502 [(set (match_operand:DF 0 "register_operand" "=x")
18503 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18504 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18505 "TARGET_SSE2 && TARGET_SSE_MATH"
18506 "minsd\t{%2, %0|%0, %2}"
18507 [(set_attr "type" "sseadd")
18508 (set_attr "mode" "DF")])
18510 (define_insn "smaxdf3"
18511 [(set (match_operand:DF 0 "register_operand" "=x")
18512 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18513 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18514 "TARGET_SSE2 && TARGET_SSE_MATH"
18515 "maxsd\t{%2, %0|%0, %2}"
18516 [(set_attr "type" "sseadd")
18517 (set_attr "mode" "DF")])
18519 ;; These versions of the min/max patterns implement exactly the operations
18520 ;; min = (op1 < op2 ? op1 : op2)
18521 ;; max = (!(op1 < op2) ? op1 : op2)
18522 ;; Their operands are not commutative, and thus they may be used in the
18523 ;; presence of -0.0 and NaN.
18525 (define_insn "*ieee_sminsf3"
18526 [(set (match_operand:SF 0 "register_operand" "=x")
18527 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18528 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18531 "minss\t{%2, %0|%0, %2}"
18532 [(set_attr "type" "sseadd")
18533 (set_attr "mode" "SF")])
18535 (define_insn "*ieee_smaxsf3"
18536 [(set (match_operand:SF 0 "register_operand" "=x")
18537 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18538 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18541 "maxss\t{%2, %0|%0, %2}"
18542 [(set_attr "type" "sseadd")
18543 (set_attr "mode" "SF")])
18545 (define_insn "*ieee_smindf3"
18546 [(set (match_operand:DF 0 "register_operand" "=x")
18547 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18548 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18550 "TARGET_SSE2 && TARGET_SSE_MATH"
18551 "minsd\t{%2, %0|%0, %2}"
18552 [(set_attr "type" "sseadd")
18553 (set_attr "mode" "DF")])
18555 (define_insn "*ieee_smaxdf3"
18556 [(set (match_operand:DF 0 "register_operand" "=x")
18557 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18558 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18560 "TARGET_SSE2 && TARGET_SSE_MATH"
18561 "maxsd\t{%2, %0|%0, %2}"
18562 [(set_attr "type" "sseadd")
18563 (set_attr "mode" "DF")])
18565 ;; Conditional addition patterns
18566 (define_expand "addqicc"
18567 [(match_operand:QI 0 "register_operand" "")
18568 (match_operand 1 "comparison_operator" "")
18569 (match_operand:QI 2 "register_operand" "")
18570 (match_operand:QI 3 "const_int_operand" "")]
18572 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18574 (define_expand "addhicc"
18575 [(match_operand:HI 0 "register_operand" "")
18576 (match_operand 1 "comparison_operator" "")
18577 (match_operand:HI 2 "register_operand" "")
18578 (match_operand:HI 3 "const_int_operand" "")]
18580 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18582 (define_expand "addsicc"
18583 [(match_operand:SI 0 "register_operand" "")
18584 (match_operand 1 "comparison_operator" "")
18585 (match_operand:SI 2 "register_operand" "")
18586 (match_operand:SI 3 "const_int_operand" "")]
18588 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18590 (define_expand "adddicc"
18591 [(match_operand:DI 0 "register_operand" "")
18592 (match_operand 1 "comparison_operator" "")
18593 (match_operand:DI 2 "register_operand" "")
18594 (match_operand:DI 3 "const_int_operand" "")]
18596 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18599 ;; Misc patterns (?)
18601 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18602 ;; Otherwise there will be nothing to keep
18604 ;; [(set (reg ebp) (reg esp))]
18605 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18606 ;; (clobber (eflags)]
18607 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18609 ;; in proper program order.
18610 (define_insn "pro_epilogue_adjust_stack_1"
18611 [(set (match_operand:SI 0 "register_operand" "=r,r")
18612 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18613 (match_operand:SI 2 "immediate_operand" "i,i")))
18614 (clobber (reg:CC FLAGS_REG))
18615 (clobber (mem:BLK (scratch)))]
18618 switch (get_attr_type (insn))
18621 return "mov{l}\t{%1, %0|%0, %1}";
18624 if (GET_CODE (operands[2]) == CONST_INT
18625 && (INTVAL (operands[2]) == 128
18626 || (INTVAL (operands[2]) < 0
18627 && INTVAL (operands[2]) != -128)))
18629 operands[2] = GEN_INT (-INTVAL (operands[2]));
18630 return "sub{l}\t{%2, %0|%0, %2}";
18632 return "add{l}\t{%2, %0|%0, %2}";
18635 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18636 return "lea{l}\t{%a2, %0|%0, %a2}";
18639 gcc_unreachable ();
18642 [(set (attr "type")
18643 (cond [(eq_attr "alternative" "0")
18644 (const_string "alu")
18645 (match_operand:SI 2 "const0_operand" "")
18646 (const_string "imov")
18648 (const_string "lea")))
18649 (set_attr "mode" "SI")])
18651 (define_insn "pro_epilogue_adjust_stack_rex64"
18652 [(set (match_operand:DI 0 "register_operand" "=r,r")
18653 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18654 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18655 (clobber (reg:CC FLAGS_REG))
18656 (clobber (mem:BLK (scratch)))]
18659 switch (get_attr_type (insn))
18662 return "mov{q}\t{%1, %0|%0, %1}";
18665 if (GET_CODE (operands[2]) == CONST_INT
18666 /* Avoid overflows. */
18667 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18668 && (INTVAL (operands[2]) == 128
18669 || (INTVAL (operands[2]) < 0
18670 && INTVAL (operands[2]) != -128)))
18672 operands[2] = GEN_INT (-INTVAL (operands[2]));
18673 return "sub{q}\t{%2, %0|%0, %2}";
18675 return "add{q}\t{%2, %0|%0, %2}";
18678 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18679 return "lea{q}\t{%a2, %0|%0, %a2}";
18682 gcc_unreachable ();
18685 [(set (attr "type")
18686 (cond [(eq_attr "alternative" "0")
18687 (const_string "alu")
18688 (match_operand:DI 2 "const0_operand" "")
18689 (const_string "imov")
18691 (const_string "lea")))
18692 (set_attr "mode" "DI")])
18694 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18695 [(set (match_operand:DI 0 "register_operand" "=r,r")
18696 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18697 (match_operand:DI 3 "immediate_operand" "i,i")))
18698 (use (match_operand:DI 2 "register_operand" "r,r"))
18699 (clobber (reg:CC FLAGS_REG))
18700 (clobber (mem:BLK (scratch)))]
18703 switch (get_attr_type (insn))
18706 return "add{q}\t{%2, %0|%0, %2}";
18709 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18710 return "lea{q}\t{%a2, %0|%0, %a2}";
18713 gcc_unreachable ();
18716 [(set_attr "type" "alu,lea")
18717 (set_attr "mode" "DI")])
18719 (define_expand "allocate_stack_worker"
18720 [(match_operand:SI 0 "register_operand" "")]
18721 "TARGET_STACK_PROBE"
18723 if (reload_completed)
18726 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18728 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18733 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18735 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18740 (define_insn "allocate_stack_worker_1"
18741 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18742 UNSPECV_STACK_PROBE)
18743 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18744 (clobber (match_scratch:SI 1 "=0"))
18745 (clobber (reg:CC FLAGS_REG))]
18746 "!TARGET_64BIT && TARGET_STACK_PROBE"
18748 [(set_attr "type" "multi")
18749 (set_attr "length" "5")])
18751 (define_expand "allocate_stack_worker_postreload"
18752 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18753 UNSPECV_STACK_PROBE)
18754 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18755 (clobber (match_dup 0))
18756 (clobber (reg:CC FLAGS_REG))])]
18760 (define_insn "allocate_stack_worker_rex64"
18761 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18762 UNSPECV_STACK_PROBE)
18763 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18764 (clobber (match_scratch:DI 1 "=0"))
18765 (clobber (reg:CC FLAGS_REG))]
18766 "TARGET_64BIT && TARGET_STACK_PROBE"
18768 [(set_attr "type" "multi")
18769 (set_attr "length" "5")])
18771 (define_expand "allocate_stack_worker_rex64_postreload"
18772 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18773 UNSPECV_STACK_PROBE)
18774 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18775 (clobber (match_dup 0))
18776 (clobber (reg:CC FLAGS_REG))])]
18780 (define_expand "allocate_stack"
18781 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18782 (minus:SI (reg:SI SP_REG)
18783 (match_operand:SI 1 "general_operand" "")))
18784 (clobber (reg:CC FLAGS_REG))])
18785 (parallel [(set (reg:SI SP_REG)
18786 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18787 (clobber (reg:CC FLAGS_REG))])]
18788 "TARGET_STACK_PROBE"
18790 #ifdef CHECK_STACK_LIMIT
18791 if (GET_CODE (operands[1]) == CONST_INT
18792 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18793 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18797 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18800 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18804 (define_expand "builtin_setjmp_receiver"
18805 [(label_ref (match_operand 0 "" ""))]
18806 "!TARGET_64BIT && flag_pic"
18808 emit_insn (gen_set_got (pic_offset_table_rtx));
18812 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18815 [(set (match_operand 0 "register_operand" "")
18816 (match_operator 3 "promotable_binary_operator"
18817 [(match_operand 1 "register_operand" "")
18818 (match_operand 2 "aligned_operand" "")]))
18819 (clobber (reg:CC FLAGS_REG))]
18820 "! TARGET_PARTIAL_REG_STALL && reload_completed
18821 && ((GET_MODE (operands[0]) == HImode
18822 && ((!optimize_size && !TARGET_FAST_PREFIX)
18823 || GET_CODE (operands[2]) != CONST_INT
18824 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18825 || (GET_MODE (operands[0]) == QImode
18826 && (TARGET_PROMOTE_QImode || optimize_size)))"
18827 [(parallel [(set (match_dup 0)
18828 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18829 (clobber (reg:CC FLAGS_REG))])]
18830 "operands[0] = gen_lowpart (SImode, operands[0]);
18831 operands[1] = gen_lowpart (SImode, operands[1]);
18832 if (GET_CODE (operands[3]) != ASHIFT)
18833 operands[2] = gen_lowpart (SImode, operands[2]);
18834 PUT_MODE (operands[3], SImode);")
18836 ; Promote the QImode tests, as i386 has encoding of the AND
18837 ; instruction with 32-bit sign-extended immediate and thus the
18838 ; instruction size is unchanged, except in the %eax case for
18839 ; which it is increased by one byte, hence the ! optimize_size.
18841 [(set (match_operand 0 "flags_reg_operand" "")
18842 (match_operator 2 "compare_operator"
18843 [(and (match_operand 3 "aligned_operand" "")
18844 (match_operand 4 "const_int_operand" ""))
18846 (set (match_operand 1 "register_operand" "")
18847 (and (match_dup 3) (match_dup 4)))]
18848 "! TARGET_PARTIAL_REG_STALL && reload_completed
18849 /* Ensure that the operand will remain sign-extended immediate. */
18850 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18852 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18853 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18854 [(parallel [(set (match_dup 0)
18855 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18858 (and:SI (match_dup 3) (match_dup 4)))])]
18861 = gen_int_mode (INTVAL (operands[4])
18862 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18863 operands[1] = gen_lowpart (SImode, operands[1]);
18864 operands[3] = gen_lowpart (SImode, operands[3]);
18867 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18868 ; the TEST instruction with 32-bit sign-extended immediate and thus
18869 ; the instruction size would at least double, which is not what we
18870 ; want even with ! optimize_size.
18872 [(set (match_operand 0 "flags_reg_operand" "")
18873 (match_operator 1 "compare_operator"
18874 [(and (match_operand:HI 2 "aligned_operand" "")
18875 (match_operand:HI 3 "const_int_operand" ""))
18877 "! TARGET_PARTIAL_REG_STALL && reload_completed
18878 /* Ensure that the operand will remain sign-extended immediate. */
18879 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18880 && ! TARGET_FAST_PREFIX
18881 && ! optimize_size"
18882 [(set (match_dup 0)
18883 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18887 = gen_int_mode (INTVAL (operands[3])
18888 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18889 operands[2] = gen_lowpart (SImode, operands[2]);
18893 [(set (match_operand 0 "register_operand" "")
18894 (neg (match_operand 1 "register_operand" "")))
18895 (clobber (reg:CC FLAGS_REG))]
18896 "! TARGET_PARTIAL_REG_STALL && reload_completed
18897 && (GET_MODE (operands[0]) == HImode
18898 || (GET_MODE (operands[0]) == QImode
18899 && (TARGET_PROMOTE_QImode || optimize_size)))"
18900 [(parallel [(set (match_dup 0)
18901 (neg:SI (match_dup 1)))
18902 (clobber (reg:CC FLAGS_REG))])]
18903 "operands[0] = gen_lowpart (SImode, operands[0]);
18904 operands[1] = gen_lowpart (SImode, operands[1]);")
18907 [(set (match_operand 0 "register_operand" "")
18908 (not (match_operand 1 "register_operand" "")))]
18909 "! TARGET_PARTIAL_REG_STALL && reload_completed
18910 && (GET_MODE (operands[0]) == HImode
18911 || (GET_MODE (operands[0]) == QImode
18912 && (TARGET_PROMOTE_QImode || optimize_size)))"
18913 [(set (match_dup 0)
18914 (not:SI (match_dup 1)))]
18915 "operands[0] = gen_lowpart (SImode, operands[0]);
18916 operands[1] = gen_lowpart (SImode, operands[1]);")
18919 [(set (match_operand 0 "register_operand" "")
18920 (if_then_else (match_operator 1 "comparison_operator"
18921 [(reg FLAGS_REG) (const_int 0)])
18922 (match_operand 2 "register_operand" "")
18923 (match_operand 3 "register_operand" "")))]
18924 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18925 && (GET_MODE (operands[0]) == HImode
18926 || (GET_MODE (operands[0]) == QImode
18927 && (TARGET_PROMOTE_QImode || optimize_size)))"
18928 [(set (match_dup 0)
18929 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18930 "operands[0] = gen_lowpart (SImode, operands[0]);
18931 operands[2] = gen_lowpart (SImode, operands[2]);
18932 operands[3] = gen_lowpart (SImode, operands[3]);")
18935 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18936 ;; transform a complex memory operation into two memory to register operations.
18938 ;; Don't push memory operands
18940 [(set (match_operand:SI 0 "push_operand" "")
18941 (match_operand:SI 1 "memory_operand" ""))
18942 (match_scratch:SI 2 "r")]
18943 "!optimize_size && !TARGET_PUSH_MEMORY
18944 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18945 [(set (match_dup 2) (match_dup 1))
18946 (set (match_dup 0) (match_dup 2))]
18950 [(set (match_operand:DI 0 "push_operand" "")
18951 (match_operand:DI 1 "memory_operand" ""))
18952 (match_scratch:DI 2 "r")]
18953 "!optimize_size && !TARGET_PUSH_MEMORY
18954 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18955 [(set (match_dup 2) (match_dup 1))
18956 (set (match_dup 0) (match_dup 2))]
18959 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18962 [(set (match_operand:SF 0 "push_operand" "")
18963 (match_operand:SF 1 "memory_operand" ""))
18964 (match_scratch:SF 2 "r")]
18965 "!optimize_size && !TARGET_PUSH_MEMORY
18966 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18967 [(set (match_dup 2) (match_dup 1))
18968 (set (match_dup 0) (match_dup 2))]
18972 [(set (match_operand:HI 0 "push_operand" "")
18973 (match_operand:HI 1 "memory_operand" ""))
18974 (match_scratch:HI 2 "r")]
18975 "!optimize_size && !TARGET_PUSH_MEMORY
18976 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18977 [(set (match_dup 2) (match_dup 1))
18978 (set (match_dup 0) (match_dup 2))]
18982 [(set (match_operand:QI 0 "push_operand" "")
18983 (match_operand:QI 1 "memory_operand" ""))
18984 (match_scratch:QI 2 "q")]
18985 "!optimize_size && !TARGET_PUSH_MEMORY
18986 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18987 [(set (match_dup 2) (match_dup 1))
18988 (set (match_dup 0) (match_dup 2))]
18991 ;; Don't move an immediate directly to memory when the instruction
18994 [(match_scratch:SI 1 "r")
18995 (set (match_operand:SI 0 "memory_operand" "")
18998 && ! TARGET_USE_MOV0
18999 && TARGET_SPLIT_LONG_MOVES
19000 && get_attr_length (insn) >= ix86_cost->large_insn
19001 && peep2_regno_dead_p (0, FLAGS_REG)"
19002 [(parallel [(set (match_dup 1) (const_int 0))
19003 (clobber (reg:CC FLAGS_REG))])
19004 (set (match_dup 0) (match_dup 1))]
19008 [(match_scratch:HI 1 "r")
19009 (set (match_operand:HI 0 "memory_operand" "")
19012 && ! TARGET_USE_MOV0
19013 && TARGET_SPLIT_LONG_MOVES
19014 && get_attr_length (insn) >= ix86_cost->large_insn
19015 && peep2_regno_dead_p (0, FLAGS_REG)"
19016 [(parallel [(set (match_dup 2) (const_int 0))
19017 (clobber (reg:CC FLAGS_REG))])
19018 (set (match_dup 0) (match_dup 1))]
19019 "operands[2] = gen_lowpart (SImode, operands[1]);")
19022 [(match_scratch:QI 1 "q")
19023 (set (match_operand:QI 0 "memory_operand" "")
19026 && ! TARGET_USE_MOV0
19027 && TARGET_SPLIT_LONG_MOVES
19028 && get_attr_length (insn) >= ix86_cost->large_insn
19029 && peep2_regno_dead_p (0, FLAGS_REG)"
19030 [(parallel [(set (match_dup 2) (const_int 0))
19031 (clobber (reg:CC FLAGS_REG))])
19032 (set (match_dup 0) (match_dup 1))]
19033 "operands[2] = gen_lowpart (SImode, operands[1]);")
19036 [(match_scratch:SI 2 "r")
19037 (set (match_operand:SI 0 "memory_operand" "")
19038 (match_operand:SI 1 "immediate_operand" ""))]
19040 && get_attr_length (insn) >= ix86_cost->large_insn
19041 && TARGET_SPLIT_LONG_MOVES"
19042 [(set (match_dup 2) (match_dup 1))
19043 (set (match_dup 0) (match_dup 2))]
19047 [(match_scratch:HI 2 "r")
19048 (set (match_operand:HI 0 "memory_operand" "")
19049 (match_operand:HI 1 "immediate_operand" ""))]
19050 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19051 && TARGET_SPLIT_LONG_MOVES"
19052 [(set (match_dup 2) (match_dup 1))
19053 (set (match_dup 0) (match_dup 2))]
19057 [(match_scratch:QI 2 "q")
19058 (set (match_operand:QI 0 "memory_operand" "")
19059 (match_operand:QI 1 "immediate_operand" ""))]
19060 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19061 && TARGET_SPLIT_LONG_MOVES"
19062 [(set (match_dup 2) (match_dup 1))
19063 (set (match_dup 0) (match_dup 2))]
19066 ;; Don't compare memory with zero, load and use a test instead.
19068 [(set (match_operand 0 "flags_reg_operand" "")
19069 (match_operator 1 "compare_operator"
19070 [(match_operand:SI 2 "memory_operand" "")
19072 (match_scratch:SI 3 "r")]
19073 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19074 [(set (match_dup 3) (match_dup 2))
19075 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19078 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19079 ;; Don't split NOTs with a displacement operand, because resulting XOR
19080 ;; will not be pairable anyway.
19082 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19083 ;; represented using a modRM byte. The XOR replacement is long decoded,
19084 ;; so this split helps here as well.
19086 ;; Note: Can't do this as a regular split because we can't get proper
19087 ;; lifetime information then.
19090 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19091 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19093 && peep2_regno_dead_p (0, FLAGS_REG)
19094 && ((TARGET_PENTIUM
19095 && (GET_CODE (operands[0]) != MEM
19096 || !memory_displacement_operand (operands[0], SImode)))
19097 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19098 [(parallel [(set (match_dup 0)
19099 (xor:SI (match_dup 1) (const_int -1)))
19100 (clobber (reg:CC FLAGS_REG))])]
19104 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19105 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19107 && peep2_regno_dead_p (0, FLAGS_REG)
19108 && ((TARGET_PENTIUM
19109 && (GET_CODE (operands[0]) != MEM
19110 || !memory_displacement_operand (operands[0], HImode)))
19111 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19112 [(parallel [(set (match_dup 0)
19113 (xor:HI (match_dup 1) (const_int -1)))
19114 (clobber (reg:CC FLAGS_REG))])]
19118 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19119 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19121 && peep2_regno_dead_p (0, FLAGS_REG)
19122 && ((TARGET_PENTIUM
19123 && (GET_CODE (operands[0]) != MEM
19124 || !memory_displacement_operand (operands[0], QImode)))
19125 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19126 [(parallel [(set (match_dup 0)
19127 (xor:QI (match_dup 1) (const_int -1)))
19128 (clobber (reg:CC FLAGS_REG))])]
19131 ;; Non pairable "test imm, reg" instructions can be translated to
19132 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19133 ;; byte opcode instead of two, have a short form for byte operands),
19134 ;; so do it for other CPUs as well. Given that the value was dead,
19135 ;; this should not create any new dependencies. Pass on the sub-word
19136 ;; versions if we're concerned about partial register stalls.
19139 [(set (match_operand 0 "flags_reg_operand" "")
19140 (match_operator 1 "compare_operator"
19141 [(and:SI (match_operand:SI 2 "register_operand" "")
19142 (match_operand:SI 3 "immediate_operand" ""))
19144 "ix86_match_ccmode (insn, CCNOmode)
19145 && (true_regnum (operands[2]) != 0
19146 || (GET_CODE (operands[3]) == CONST_INT
19147 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
19148 && peep2_reg_dead_p (1, operands[2])"
19150 [(set (match_dup 0)
19151 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19154 (and:SI (match_dup 2) (match_dup 3)))])]
19157 ;; We don't need to handle HImode case, because it will be promoted to SImode
19158 ;; on ! TARGET_PARTIAL_REG_STALL
19161 [(set (match_operand 0 "flags_reg_operand" "")
19162 (match_operator 1 "compare_operator"
19163 [(and:QI (match_operand:QI 2 "register_operand" "")
19164 (match_operand:QI 3 "immediate_operand" ""))
19166 "! TARGET_PARTIAL_REG_STALL
19167 && ix86_match_ccmode (insn, CCNOmode)
19168 && true_regnum (operands[2]) != 0
19169 && peep2_reg_dead_p (1, operands[2])"
19171 [(set (match_dup 0)
19172 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19175 (and:QI (match_dup 2) (match_dup 3)))])]
19179 [(set (match_operand 0 "flags_reg_operand" "")
19180 (match_operator 1 "compare_operator"
19183 (match_operand 2 "ext_register_operand" "")
19186 (match_operand 3 "const_int_operand" ""))
19188 "! TARGET_PARTIAL_REG_STALL
19189 && ix86_match_ccmode (insn, CCNOmode)
19190 && true_regnum (operands[2]) != 0
19191 && peep2_reg_dead_p (1, operands[2])"
19192 [(parallel [(set (match_dup 0)
19201 (set (zero_extract:SI (match_dup 2)
19212 ;; Don't do logical operations with memory inputs.
19214 [(match_scratch:SI 2 "r")
19215 (parallel [(set (match_operand:SI 0 "register_operand" "")
19216 (match_operator:SI 3 "arith_or_logical_operator"
19218 (match_operand:SI 1 "memory_operand" "")]))
19219 (clobber (reg:CC FLAGS_REG))])]
19220 "! optimize_size && ! TARGET_READ_MODIFY"
19221 [(set (match_dup 2) (match_dup 1))
19222 (parallel [(set (match_dup 0)
19223 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19224 (clobber (reg:CC FLAGS_REG))])]
19228 [(match_scratch:SI 2 "r")
19229 (parallel [(set (match_operand:SI 0 "register_operand" "")
19230 (match_operator:SI 3 "arith_or_logical_operator"
19231 [(match_operand:SI 1 "memory_operand" "")
19233 (clobber (reg:CC FLAGS_REG))])]
19234 "! optimize_size && ! TARGET_READ_MODIFY"
19235 [(set (match_dup 2) (match_dup 1))
19236 (parallel [(set (match_dup 0)
19237 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19238 (clobber (reg:CC FLAGS_REG))])]
19241 ; Don't do logical operations with memory outputs
19243 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19244 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19245 ; the same decoder scheduling characteristics as the original.
19248 [(match_scratch:SI 2 "r")
19249 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19250 (match_operator:SI 3 "arith_or_logical_operator"
19252 (match_operand:SI 1 "nonmemory_operand" "")]))
19253 (clobber (reg:CC FLAGS_REG))])]
19254 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19255 [(set (match_dup 2) (match_dup 0))
19256 (parallel [(set (match_dup 2)
19257 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19258 (clobber (reg:CC FLAGS_REG))])
19259 (set (match_dup 0) (match_dup 2))]
19263 [(match_scratch:SI 2 "r")
19264 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19265 (match_operator:SI 3 "arith_or_logical_operator"
19266 [(match_operand:SI 1 "nonmemory_operand" "")
19268 (clobber (reg:CC FLAGS_REG))])]
19269 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19270 [(set (match_dup 2) (match_dup 0))
19271 (parallel [(set (match_dup 2)
19272 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19273 (clobber (reg:CC FLAGS_REG))])
19274 (set (match_dup 0) (match_dup 2))]
19277 ;; Attempt to always use XOR for zeroing registers.
19279 [(set (match_operand 0 "register_operand" "")
19280 (match_operand 1 "const0_operand" ""))]
19281 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19282 && (! TARGET_USE_MOV0 || optimize_size)
19283 && GENERAL_REG_P (operands[0])
19284 && peep2_regno_dead_p (0, FLAGS_REG)"
19285 [(parallel [(set (match_dup 0) (const_int 0))
19286 (clobber (reg:CC FLAGS_REG))])]
19288 operands[0] = gen_lowpart (word_mode, operands[0]);
19292 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19294 "(GET_MODE (operands[0]) == QImode
19295 || GET_MODE (operands[0]) == HImode)
19296 && (! TARGET_USE_MOV0 || optimize_size)
19297 && peep2_regno_dead_p (0, FLAGS_REG)"
19298 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19299 (clobber (reg:CC FLAGS_REG))])])
19301 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19303 [(set (match_operand 0 "register_operand" "")
19305 "(GET_MODE (operands[0]) == HImode
19306 || GET_MODE (operands[0]) == SImode
19307 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19308 && (optimize_size || TARGET_PENTIUM)
19309 && peep2_regno_dead_p (0, FLAGS_REG)"
19310 [(parallel [(set (match_dup 0) (const_int -1))
19311 (clobber (reg:CC FLAGS_REG))])]
19312 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19315 ;; Attempt to convert simple leas to adds. These can be created by
19318 [(set (match_operand:SI 0 "register_operand" "")
19319 (plus:SI (match_dup 0)
19320 (match_operand:SI 1 "nonmemory_operand" "")))]
19321 "peep2_regno_dead_p (0, FLAGS_REG)"
19322 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19323 (clobber (reg:CC FLAGS_REG))])]
19327 [(set (match_operand:SI 0 "register_operand" "")
19328 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19329 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19330 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19331 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19332 (clobber (reg:CC FLAGS_REG))])]
19333 "operands[2] = gen_lowpart (SImode, operands[2]);")
19336 [(set (match_operand:DI 0 "register_operand" "")
19337 (plus:DI (match_dup 0)
19338 (match_operand:DI 1 "x86_64_general_operand" "")))]
19339 "peep2_regno_dead_p (0, FLAGS_REG)"
19340 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19341 (clobber (reg:CC FLAGS_REG))])]
19345 [(set (match_operand:SI 0 "register_operand" "")
19346 (mult:SI (match_dup 0)
19347 (match_operand:SI 1 "const_int_operand" "")))]
19348 "exact_log2 (INTVAL (operands[1])) >= 0
19349 && peep2_regno_dead_p (0, FLAGS_REG)"
19350 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19351 (clobber (reg:CC FLAGS_REG))])]
19352 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19355 [(set (match_operand:DI 0 "register_operand" "")
19356 (mult:DI (match_dup 0)
19357 (match_operand:DI 1 "const_int_operand" "")))]
19358 "exact_log2 (INTVAL (operands[1])) >= 0
19359 && peep2_regno_dead_p (0, FLAGS_REG)"
19360 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19361 (clobber (reg:CC FLAGS_REG))])]
19362 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19365 [(set (match_operand:SI 0 "register_operand" "")
19366 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19367 (match_operand:DI 2 "const_int_operand" "")) 0))]
19368 "exact_log2 (INTVAL (operands[2])) >= 0
19369 && REGNO (operands[0]) == REGNO (operands[1])
19370 && peep2_regno_dead_p (0, FLAGS_REG)"
19371 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19372 (clobber (reg:CC FLAGS_REG))])]
19373 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19375 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19376 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19377 ;; many CPUs it is also faster, since special hardware to avoid esp
19378 ;; dependencies is present.
19380 ;; While some of these conversions may be done using splitters, we use peepholes
19381 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19383 ;; Convert prologue esp subtractions to push.
19384 ;; We need register to push. In order to keep verify_flow_info happy we have
19386 ;; - use scratch and clobber it in order to avoid dependencies
19387 ;; - use already live register
19388 ;; We can't use the second way right now, since there is no reliable way how to
19389 ;; verify that given register is live. First choice will also most likely in
19390 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19391 ;; call clobbered registers are dead. We may want to use base pointer as an
19392 ;; alternative when no register is available later.
19395 [(match_scratch:SI 0 "r")
19396 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19397 (clobber (reg:CC FLAGS_REG))
19398 (clobber (mem:BLK (scratch)))])]
19399 "optimize_size || !TARGET_SUB_ESP_4"
19400 [(clobber (match_dup 0))
19401 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19402 (clobber (mem:BLK (scratch)))])])
19405 [(match_scratch:SI 0 "r")
19406 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19407 (clobber (reg:CC FLAGS_REG))
19408 (clobber (mem:BLK (scratch)))])]
19409 "optimize_size || !TARGET_SUB_ESP_8"
19410 [(clobber (match_dup 0))
19411 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19412 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19413 (clobber (mem:BLK (scratch)))])])
19415 ;; Convert esp subtractions to push.
19417 [(match_scratch:SI 0 "r")
19418 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19419 (clobber (reg:CC FLAGS_REG))])]
19420 "optimize_size || !TARGET_SUB_ESP_4"
19421 [(clobber (match_dup 0))
19422 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19425 [(match_scratch:SI 0 "r")
19426 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19427 (clobber (reg:CC FLAGS_REG))])]
19428 "optimize_size || !TARGET_SUB_ESP_8"
19429 [(clobber (match_dup 0))
19430 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19431 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19433 ;; Convert epilogue deallocator to pop.
19435 [(match_scratch:SI 0 "r")
19436 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19437 (clobber (reg:CC FLAGS_REG))
19438 (clobber (mem:BLK (scratch)))])]
19439 "optimize_size || !TARGET_ADD_ESP_4"
19440 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19441 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19442 (clobber (mem:BLK (scratch)))])]
19445 ;; Two pops case is tricky, since pop causes dependency on destination register.
19446 ;; We use two registers if available.
19448 [(match_scratch:SI 0 "r")
19449 (match_scratch:SI 1 "r")
19450 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19451 (clobber (reg:CC FLAGS_REG))
19452 (clobber (mem:BLK (scratch)))])]
19453 "optimize_size || !TARGET_ADD_ESP_8"
19454 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19455 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19456 (clobber (mem:BLK (scratch)))])
19457 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19458 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19462 [(match_scratch:SI 0 "r")
19463 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19464 (clobber (reg:CC FLAGS_REG))
19465 (clobber (mem:BLK (scratch)))])]
19467 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19468 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19469 (clobber (mem:BLK (scratch)))])
19470 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19471 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19474 ;; Convert esp additions to pop.
19476 [(match_scratch:SI 0 "r")
19477 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19478 (clobber (reg:CC FLAGS_REG))])]
19480 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19481 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19484 ;; Two pops case is tricky, since pop causes dependency on destination register.
19485 ;; We use two registers if available.
19487 [(match_scratch:SI 0 "r")
19488 (match_scratch:SI 1 "r")
19489 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19490 (clobber (reg:CC FLAGS_REG))])]
19492 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19493 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19494 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19495 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19499 [(match_scratch:SI 0 "r")
19500 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19501 (clobber (reg:CC FLAGS_REG))])]
19503 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19504 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19505 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19506 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19509 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19510 ;; required and register dies. Similarly for 128 to plus -128.
19512 [(set (match_operand 0 "flags_reg_operand" "")
19513 (match_operator 1 "compare_operator"
19514 [(match_operand 2 "register_operand" "")
19515 (match_operand 3 "const_int_operand" "")]))]
19516 "(INTVAL (operands[3]) == -1
19517 || INTVAL (operands[3]) == 1
19518 || INTVAL (operands[3]) == 128)
19519 && ix86_match_ccmode (insn, CCGCmode)
19520 && peep2_reg_dead_p (1, operands[2])"
19521 [(parallel [(set (match_dup 0)
19522 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19523 (clobber (match_dup 2))])]
19527 [(match_scratch:DI 0 "r")
19528 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19529 (clobber (reg:CC FLAGS_REG))
19530 (clobber (mem:BLK (scratch)))])]
19531 "optimize_size || !TARGET_SUB_ESP_4"
19532 [(clobber (match_dup 0))
19533 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19534 (clobber (mem:BLK (scratch)))])])
19537 [(match_scratch:DI 0 "r")
19538 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19539 (clobber (reg:CC FLAGS_REG))
19540 (clobber (mem:BLK (scratch)))])]
19541 "optimize_size || !TARGET_SUB_ESP_8"
19542 [(clobber (match_dup 0))
19543 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19544 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19545 (clobber (mem:BLK (scratch)))])])
19547 ;; Convert esp subtractions to push.
19549 [(match_scratch:DI 0 "r")
19550 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19551 (clobber (reg:CC FLAGS_REG))])]
19552 "optimize_size || !TARGET_SUB_ESP_4"
19553 [(clobber (match_dup 0))
19554 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19557 [(match_scratch:DI 0 "r")
19558 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19559 (clobber (reg:CC FLAGS_REG))])]
19560 "optimize_size || !TARGET_SUB_ESP_8"
19561 [(clobber (match_dup 0))
19562 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19563 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19565 ;; Convert epilogue deallocator to pop.
19567 [(match_scratch:DI 0 "r")
19568 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19569 (clobber (reg:CC FLAGS_REG))
19570 (clobber (mem:BLK (scratch)))])]
19571 "optimize_size || !TARGET_ADD_ESP_4"
19572 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19573 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19574 (clobber (mem:BLK (scratch)))])]
19577 ;; Two pops case is tricky, since pop causes dependency on destination register.
19578 ;; We use two registers if available.
19580 [(match_scratch:DI 0 "r")
19581 (match_scratch:DI 1 "r")
19582 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19583 (clobber (reg:CC FLAGS_REG))
19584 (clobber (mem:BLK (scratch)))])]
19585 "optimize_size || !TARGET_ADD_ESP_8"
19586 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19587 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19588 (clobber (mem:BLK (scratch)))])
19589 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19590 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19594 [(match_scratch:DI 0 "r")
19595 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19596 (clobber (reg:CC FLAGS_REG))
19597 (clobber (mem:BLK (scratch)))])]
19599 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19600 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19601 (clobber (mem:BLK (scratch)))])
19602 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19603 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19606 ;; Convert esp additions to pop.
19608 [(match_scratch:DI 0 "r")
19609 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19610 (clobber (reg:CC FLAGS_REG))])]
19612 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19613 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19616 ;; Two pops case is tricky, since pop causes dependency on destination register.
19617 ;; We use two registers if available.
19619 [(match_scratch:DI 0 "r")
19620 (match_scratch:DI 1 "r")
19621 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19622 (clobber (reg:CC FLAGS_REG))])]
19624 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19625 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19626 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19627 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19631 [(match_scratch:DI 0 "r")
19632 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19633 (clobber (reg:CC FLAGS_REG))])]
19635 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19636 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19637 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19638 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19641 ;; Convert imul by three, five and nine into lea
19644 [(set (match_operand:SI 0 "register_operand" "")
19645 (mult:SI (match_operand:SI 1 "register_operand" "")
19646 (match_operand:SI 2 "const_int_operand" "")))
19647 (clobber (reg:CC FLAGS_REG))])]
19648 "INTVAL (operands[2]) == 3
19649 || INTVAL (operands[2]) == 5
19650 || INTVAL (operands[2]) == 9"
19651 [(set (match_dup 0)
19652 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19654 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19658 [(set (match_operand:SI 0 "register_operand" "")
19659 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19660 (match_operand:SI 2 "const_int_operand" "")))
19661 (clobber (reg:CC FLAGS_REG))])]
19663 && (INTVAL (operands[2]) == 3
19664 || INTVAL (operands[2]) == 5
19665 || INTVAL (operands[2]) == 9)"
19666 [(set (match_dup 0) (match_dup 1))
19668 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19670 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19674 [(set (match_operand:DI 0 "register_operand" "")
19675 (mult:DI (match_operand:DI 1 "register_operand" "")
19676 (match_operand:DI 2 "const_int_operand" "")))
19677 (clobber (reg:CC FLAGS_REG))])]
19679 && (INTVAL (operands[2]) == 3
19680 || INTVAL (operands[2]) == 5
19681 || INTVAL (operands[2]) == 9)"
19682 [(set (match_dup 0)
19683 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19685 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19689 [(set (match_operand:DI 0 "register_operand" "")
19690 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19691 (match_operand:DI 2 "const_int_operand" "")))
19692 (clobber (reg:CC FLAGS_REG))])]
19695 && (INTVAL (operands[2]) == 3
19696 || INTVAL (operands[2]) == 5
19697 || INTVAL (operands[2]) == 9)"
19698 [(set (match_dup 0) (match_dup 1))
19700 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19702 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19704 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19705 ;; imul $32bit_imm, reg, reg is direct decoded.
19707 [(match_scratch:DI 3 "r")
19708 (parallel [(set (match_operand:DI 0 "register_operand" "")
19709 (mult:DI (match_operand:DI 1 "memory_operand" "")
19710 (match_operand:DI 2 "immediate_operand" "")))
19711 (clobber (reg:CC FLAGS_REG))])]
19712 "TARGET_K8 && !optimize_size
19713 && (GET_CODE (operands[2]) != CONST_INT
19714 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19715 [(set (match_dup 3) (match_dup 1))
19716 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19717 (clobber (reg:CC FLAGS_REG))])]
19721 [(match_scratch:SI 3 "r")
19722 (parallel [(set (match_operand:SI 0 "register_operand" "")
19723 (mult:SI (match_operand:SI 1 "memory_operand" "")
19724 (match_operand:SI 2 "immediate_operand" "")))
19725 (clobber (reg:CC FLAGS_REG))])]
19726 "TARGET_K8 && !optimize_size
19727 && (GET_CODE (operands[2]) != CONST_INT
19728 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19729 [(set (match_dup 3) (match_dup 1))
19730 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19731 (clobber (reg:CC FLAGS_REG))])]
19735 [(match_scratch:SI 3 "r")
19736 (parallel [(set (match_operand:DI 0 "register_operand" "")
19738 (mult:SI (match_operand:SI 1 "memory_operand" "")
19739 (match_operand:SI 2 "immediate_operand" ""))))
19740 (clobber (reg:CC FLAGS_REG))])]
19741 "TARGET_K8 && !optimize_size
19742 && (GET_CODE (operands[2]) != CONST_INT
19743 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19744 [(set (match_dup 3) (match_dup 1))
19745 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19746 (clobber (reg:CC FLAGS_REG))])]
19749 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19750 ;; Convert it into imul reg, reg
19751 ;; It would be better to force assembler to encode instruction using long
19752 ;; immediate, but there is apparently no way to do so.
19754 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19755 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19756 (match_operand:DI 2 "const_int_operand" "")))
19757 (clobber (reg:CC FLAGS_REG))])
19758 (match_scratch:DI 3 "r")]
19759 "TARGET_K8 && !optimize_size
19760 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19761 [(set (match_dup 3) (match_dup 2))
19762 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19763 (clobber (reg:CC FLAGS_REG))])]
19765 if (!rtx_equal_p (operands[0], operands[1]))
19766 emit_move_insn (operands[0], operands[1]);
19770 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19771 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19772 (match_operand:SI 2 "const_int_operand" "")))
19773 (clobber (reg:CC FLAGS_REG))])
19774 (match_scratch:SI 3 "r")]
19775 "TARGET_K8 && !optimize_size
19776 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19777 [(set (match_dup 3) (match_dup 2))
19778 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19779 (clobber (reg:CC FLAGS_REG))])]
19781 if (!rtx_equal_p (operands[0], operands[1]))
19782 emit_move_insn (operands[0], operands[1]);
19786 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19787 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19788 (match_operand:HI 2 "immediate_operand" "")))
19789 (clobber (reg:CC FLAGS_REG))])
19790 (match_scratch:HI 3 "r")]
19791 "TARGET_K8 && !optimize_size"
19792 [(set (match_dup 3) (match_dup 2))
19793 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19794 (clobber (reg:CC FLAGS_REG))])]
19796 if (!rtx_equal_p (operands[0], operands[1]))
19797 emit_move_insn (operands[0], operands[1]);
19800 ;; After splitting up read-modify operations, array accesses with memory
19801 ;; operands might end up in form:
19803 ;; movl 4(%esp), %edx
19805 ;; instead of pre-splitting:
19807 ;; addl 4(%esp), %eax
19809 ;; movl 4(%esp), %edx
19810 ;; leal (%edx,%eax,4), %eax
19813 [(parallel [(set (match_operand 0 "register_operand" "")
19814 (ashift (match_operand 1 "register_operand" "")
19815 (match_operand 2 "const_int_operand" "")))
19816 (clobber (reg:CC FLAGS_REG))])
19817 (set (match_operand 3 "register_operand")
19818 (match_operand 4 "x86_64_general_operand" ""))
19819 (parallel [(set (match_operand 5 "register_operand" "")
19820 (plus (match_operand 6 "register_operand" "")
19821 (match_operand 7 "register_operand" "")))
19822 (clobber (reg:CC FLAGS_REG))])]
19823 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19824 /* Validate MODE for lea. */
19825 && ((!TARGET_PARTIAL_REG_STALL
19826 && (GET_MODE (operands[0]) == QImode
19827 || GET_MODE (operands[0]) == HImode))
19828 || GET_MODE (operands[0]) == SImode
19829 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19830 /* We reorder load and the shift. */
19831 && !rtx_equal_p (operands[1], operands[3])
19832 && !reg_overlap_mentioned_p (operands[0], operands[4])
19833 /* Last PLUS must consist of operand 0 and 3. */
19834 && !rtx_equal_p (operands[0], operands[3])
19835 && (rtx_equal_p (operands[3], operands[6])
19836 || rtx_equal_p (operands[3], operands[7]))
19837 && (rtx_equal_p (operands[0], operands[6])
19838 || rtx_equal_p (operands[0], operands[7]))
19839 /* The intermediate operand 0 must die or be same as output. */
19840 && (rtx_equal_p (operands[0], operands[5])
19841 || peep2_reg_dead_p (3, operands[0]))"
19842 [(set (match_dup 3) (match_dup 4))
19843 (set (match_dup 0) (match_dup 1))]
19845 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19846 int scale = 1 << INTVAL (operands[2]);
19847 rtx index = gen_lowpart (Pmode, operands[1]);
19848 rtx base = gen_lowpart (Pmode, operands[3]);
19849 rtx dest = gen_lowpart (mode, operands[5]);
19851 operands[1] = gen_rtx_PLUS (Pmode, base,
19852 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19854 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19855 operands[0] = dest;
19858 ;; Call-value patterns last so that the wildcard operand does not
19859 ;; disrupt insn-recog's switch tables.
19861 (define_insn "*call_value_pop_0"
19862 [(set (match_operand 0 "" "")
19863 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19864 (match_operand:SI 2 "" "")))
19865 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19866 (match_operand:SI 3 "immediate_operand" "")))]
19869 if (SIBLING_CALL_P (insn))
19872 return "call\t%P1";
19874 [(set_attr "type" "callv")])
19876 (define_insn "*call_value_pop_1"
19877 [(set (match_operand 0 "" "")
19878 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19879 (match_operand:SI 2 "" "")))
19880 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19881 (match_operand:SI 3 "immediate_operand" "i")))]
19884 if (constant_call_address_operand (operands[1], Pmode))
19886 if (SIBLING_CALL_P (insn))
19889 return "call\t%P1";
19891 if (SIBLING_CALL_P (insn))
19894 return "call\t%A1";
19896 [(set_attr "type" "callv")])
19898 (define_insn "*call_value_0"
19899 [(set (match_operand 0 "" "")
19900 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19901 (match_operand:SI 2 "" "")))]
19904 if (SIBLING_CALL_P (insn))
19907 return "call\t%P1";
19909 [(set_attr "type" "callv")])
19911 (define_insn "*call_value_0_rex64"
19912 [(set (match_operand 0 "" "")
19913 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19914 (match_operand:DI 2 "const_int_operand" "")))]
19917 if (SIBLING_CALL_P (insn))
19920 return "call\t%P1";
19922 [(set_attr "type" "callv")])
19924 (define_insn "*call_value_1"
19925 [(set (match_operand 0 "" "")
19926 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19927 (match_operand:SI 2 "" "")))]
19928 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19930 if (constant_call_address_operand (operands[1], Pmode))
19931 return "call\t%P1";
19932 return "call\t%A1";
19934 [(set_attr "type" "callv")])
19936 (define_insn "*sibcall_value_1"
19937 [(set (match_operand 0 "" "")
19938 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19939 (match_operand:SI 2 "" "")))]
19940 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19942 if (constant_call_address_operand (operands[1], Pmode))
19946 [(set_attr "type" "callv")])
19948 (define_insn "*call_value_1_rex64"
19949 [(set (match_operand 0 "" "")
19950 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19951 (match_operand:DI 2 "" "")))]
19952 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19954 if (constant_call_address_operand (operands[1], Pmode))
19955 return "call\t%P1";
19956 return "call\t%A1";
19958 [(set_attr "type" "callv")])
19960 (define_insn "*sibcall_value_1_rex64"
19961 [(set (match_operand 0 "" "")
19962 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19963 (match_operand:DI 2 "" "")))]
19964 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19966 [(set_attr "type" "callv")])
19968 (define_insn "*sibcall_value_1_rex64_v"
19969 [(set (match_operand 0 "" "")
19970 (call (mem:QI (reg:DI 40))
19971 (match_operand:DI 1 "" "")))]
19972 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19974 [(set_attr "type" "callv")])
19976 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19977 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19978 ;; caught for use by garbage collectors and the like. Using an insn that
19979 ;; maps to SIGILL makes it more likely the program will rightfully die.
19980 ;; Keeping with tradition, "6" is in honor of #UD.
19981 (define_insn "trap"
19982 [(trap_if (const_int 1) (const_int 6))]
19985 [(set_attr "length" "2")])
19987 (define_expand "sse_prologue_save"
19988 [(parallel [(set (match_operand:BLK 0 "" "")
19989 (unspec:BLK [(reg:DI 21)
19996 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19997 (use (match_operand:DI 1 "register_operand" ""))
19998 (use (match_operand:DI 2 "immediate_operand" ""))
19999 (use (label_ref:DI (match_operand 3 "" "")))])]
20003 (define_insn "*sse_prologue_save_insn"
20004 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20005 (match_operand:DI 4 "const_int_operand" "n")))
20006 (unspec:BLK [(reg:DI 21)
20013 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20014 (use (match_operand:DI 1 "register_operand" "r"))
20015 (use (match_operand:DI 2 "const_int_operand" "i"))
20016 (use (label_ref:DI (match_operand 3 "" "X")))]
20018 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20019 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20023 operands[0] = gen_rtx_MEM (Pmode,
20024 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20025 output_asm_insn (\"jmp\\t%A1\", operands);
20026 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20028 operands[4] = adjust_address (operands[0], DImode, i*16);
20029 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20030 PUT_MODE (operands[4], TImode);
20031 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20032 output_asm_insn (\"rex\", operands);
20033 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20035 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20036 CODE_LABEL_NUMBER (operands[3]));
20040 [(set_attr "type" "other")
20041 (set_attr "length_immediate" "0")
20042 (set_attr "length_address" "0")
20043 (set_attr "length" "135")
20044 (set_attr "memory" "store")
20045 (set_attr "modrm" "0")
20046 (set_attr "mode" "DI")])
20048 (define_expand "prefetch"
20049 [(prefetch (match_operand 0 "address_operand" "")
20050 (match_operand:SI 1 "const_int_operand" "")
20051 (match_operand:SI 2 "const_int_operand" ""))]
20052 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20054 int rw = INTVAL (operands[1]);
20055 int locality = INTVAL (operands[2]);
20057 gcc_assert (rw == 0 || rw == 1);
20058 gcc_assert (locality >= 0 && locality <= 3);
20059 gcc_assert (GET_MODE (operands[0]) == Pmode
20060 || GET_MODE (operands[0]) == VOIDmode);
20062 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20063 supported by SSE counterpart or the SSE prefetch is not available
20064 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20066 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20067 operands[2] = GEN_INT (3);
20069 operands[1] = const0_rtx;
20072 (define_insn "*prefetch_sse"
20073 [(prefetch (match_operand:SI 0 "address_operand" "p")
20075 (match_operand:SI 1 "const_int_operand" ""))]
20076 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20078 static const char * const patterns[4] = {
20079 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20082 int locality = INTVAL (operands[1]);
20083 gcc_assert (locality >= 0 && locality <= 3);
20085 return patterns[locality];
20087 [(set_attr "type" "sse")
20088 (set_attr "memory" "none")])
20090 (define_insn "*prefetch_sse_rex"
20091 [(prefetch (match_operand:DI 0 "address_operand" "p")
20093 (match_operand:SI 1 "const_int_operand" ""))]
20094 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20096 static const char * const patterns[4] = {
20097 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20100 int locality = INTVAL (operands[1]);
20101 gcc_assert (locality >= 0 && locality <= 3);
20103 return patterns[locality];
20105 [(set_attr "type" "sse")
20106 (set_attr "memory" "none")])
20108 (define_insn "*prefetch_3dnow"
20109 [(prefetch (match_operand:SI 0 "address_operand" "p")
20110 (match_operand:SI 1 "const_int_operand" "n")
20112 "TARGET_3DNOW && !TARGET_64BIT"
20114 if (INTVAL (operands[1]) == 0)
20115 return "prefetch\t%a0";
20117 return "prefetchw\t%a0";
20119 [(set_attr "type" "mmx")
20120 (set_attr "memory" "none")])
20122 (define_insn "*prefetch_3dnow_rex"
20123 [(prefetch (match_operand:DI 0 "address_operand" "p")
20124 (match_operand:SI 1 "const_int_operand" "n")
20126 "TARGET_3DNOW && TARGET_64BIT"
20128 if (INTVAL (operands[1]) == 0)
20129 return "prefetch\t%a0";
20131 return "prefetchw\t%a0";
20133 [(set_attr "type" "mmx")
20134 (set_attr "memory" "none")])
20136 (define_expand "stack_protect_set"
20137 [(match_operand 0 "memory_operand" "")
20138 (match_operand 1 "memory_operand" "")]
20141 #ifdef TARGET_THREAD_SSP_OFFSET
20143 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20144 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20146 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20147 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20150 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20152 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20157 (define_insn "stack_protect_set_si"
20158 [(set (match_operand:SI 0 "memory_operand" "=m")
20159 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20160 (set (match_scratch:SI 2 "=&r") (const_int 0))
20161 (clobber (reg:CC FLAGS_REG))]
20163 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20164 [(set_attr "type" "multi")])
20166 (define_insn "stack_protect_set_di"
20167 [(set (match_operand:DI 0 "memory_operand" "=m")
20168 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20169 (set (match_scratch:DI 2 "=&r") (const_int 0))
20170 (clobber (reg:CC FLAGS_REG))]
20172 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20173 [(set_attr "type" "multi")])
20175 (define_insn "stack_tls_protect_set_si"
20176 [(set (match_operand:SI 0 "memory_operand" "=m")
20177 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20178 (set (match_scratch:SI 2 "=&r") (const_int 0))
20179 (clobber (reg:CC FLAGS_REG))]
20181 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20182 [(set_attr "type" "multi")])
20184 (define_insn "stack_tls_protect_set_di"
20185 [(set (match_operand:DI 0 "memory_operand" "=m")
20186 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20187 (set (match_scratch:DI 2 "=&r") (const_int 0))
20188 (clobber (reg:CC FLAGS_REG))]
20190 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20191 [(set_attr "type" "multi")])
20193 (define_expand "stack_protect_test"
20194 [(match_operand 0 "memory_operand" "")
20195 (match_operand 1 "memory_operand" "")
20196 (match_operand 2 "" "")]
20199 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20200 ix86_compare_op0 = operands[0];
20201 ix86_compare_op1 = operands[1];
20202 ix86_compare_emitted = flags;
20204 #ifdef TARGET_THREAD_SSP_OFFSET
20206 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20207 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20209 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20210 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20213 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20215 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20217 emit_jump_insn (gen_beq (operands[2]));
20221 (define_insn "stack_protect_test_si"
20222 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20223 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20224 (match_operand:SI 2 "memory_operand" "m")]
20226 (clobber (match_scratch:SI 3 "=&r"))]
20228 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20229 [(set_attr "type" "multi")])
20231 (define_insn "stack_protect_test_di"
20232 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20233 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20234 (match_operand:DI 2 "memory_operand" "m")]
20236 (clobber (match_scratch:DI 3 "=&r"))]
20238 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20239 [(set_attr "type" "multi")])
20241 (define_insn "stack_tls_protect_test_si"
20242 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20243 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20244 (match_operand:SI 2 "const_int_operand" "i")]
20245 UNSPEC_SP_TLS_TEST))
20246 (clobber (match_scratch:SI 3 "=r"))]
20248 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20249 [(set_attr "type" "multi")])
20251 (define_insn "stack_tls_protect_test_di"
20252 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20253 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20254 (match_operand:DI 2 "const_int_operand" "i")]
20255 UNSPEC_SP_TLS_TEST))
20256 (clobber (match_scratch:DI 3 "=r"))]
20258 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"
20259 [(set_attr "type" "multi")])
20263 (include "sync.md")