1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 29)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 30)
99 (UNSPEC_NOP 38) ; prevents combiner cleverness
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
126 (UNSPEC_FRNDINT_FLOOR 70)
127 (UNSPEC_FRNDINT_CEIL 71)
128 (UNSPEC_FRNDINT_TRUNC 72)
129 (UNSPEC_FRNDINT_MASK_PM 73)
130 (UNSPEC_FIST_FLOOR 74)
131 (UNSPEC_FIST_CEIL 75)
133 ; x87 Double output FP
134 (UNSPEC_SINCOS_COS 80)
135 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
160 [(UNSPECV_BLOCKAGE 0)
161 (UNSPECV_STACK_PROBE 1)
170 (UNSPECV_CMPXCHG_1 10)
171 (UNSPECV_CMPXCHG_2 11)
176 ;; Registers by name.
187 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
190 ;; In C guard expressions, put expressions which may be compile-time
191 ;; constants first. This allows for better optimization. For
192 ;; example, write "TARGET_64BIT && reload_completed", not
193 ;; "reload_completed && TARGET_64BIT".
196 ;; Processor type. This attribute must exactly match the processor_type
197 ;; enumeration in i386.h.
198 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
199 (const (symbol_ref "ix86_tune")))
201 ;; A basic instruction type. Refinements due to arguments to be
202 ;; provided in other attributes.
205 alu,alu1,negnot,imov,imovx,lea,
206 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
207 icmp,test,ibr,setcc,icmov,
208 push,pop,call,callv,leave,
210 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
211 sselog,sselog1,sseiadd,sseishft,sseimul,
212 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
213 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
214 (const_string "other"))
216 ;; Main data type used by the insn
218 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
219 (const_string "unknown"))
221 ;; The CPU unit operations uses.
222 (define_attr "unit" "integer,i387,sse,mmx,unknown"
223 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
224 (const_string "i387")
225 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
226 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
228 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
230 (eq_attr "type" "other")
231 (const_string "unknown")]
232 (const_string "integer")))
234 ;; The (bounding maximum) length of an instruction immediate.
235 (define_attr "length_immediate" ""
236 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
238 (eq_attr "unit" "i387,sse,mmx")
240 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
242 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
243 (eq_attr "type" "imov,test")
244 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
245 (eq_attr "type" "call")
246 (if_then_else (match_operand 0 "constant_call_address_operand" "")
249 (eq_attr "type" "callv")
250 (if_then_else (match_operand 1 "constant_call_address_operand" "")
253 ;; We don't know the size before shorten_branches. Expect
254 ;; the instruction to fit for better scheduling.
255 (eq_attr "type" "ibr")
258 (symbol_ref "/* Update immediate_length and other attributes! */
259 gcc_unreachable (),1")))
261 ;; The (bounding maximum) length of an instruction address.
262 (define_attr "length_address" ""
263 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
265 (and (eq_attr "type" "call")
266 (match_operand 0 "constant_call_address_operand" ""))
268 (and (eq_attr "type" "callv")
269 (match_operand 1 "constant_call_address_operand" ""))
272 (symbol_ref "ix86_attr_length_address_default (insn)")))
274 ;; Set when length prefix is used.
275 (define_attr "prefix_data16" ""
276 (if_then_else (ior (eq_attr "mode" "HI")
277 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
281 ;; Set when string REP prefix is used.
282 (define_attr "prefix_rep" ""
283 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
287 ;; Set when 0f opcode prefix is used.
288 (define_attr "prefix_0f" ""
290 (ior (eq_attr "type" "imovx,setcc,icmov")
291 (eq_attr "unit" "sse,mmx"))
295 ;; Set when REX opcode prefix is used.
296 (define_attr "prefix_rex" ""
297 (cond [(and (eq_attr "mode" "DI")
298 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
300 (and (eq_attr "mode" "QI")
301 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
304 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
310 ;; Set when modrm byte is used.
311 (define_attr "modrm" ""
312 (cond [(eq_attr "type" "str,cld,leave")
314 (eq_attr "unit" "i387")
316 (and (eq_attr "type" "incdec")
317 (ior (match_operand:SI 1 "register_operand" "")
318 (match_operand:HI 1 "register_operand" "")))
320 (and (eq_attr "type" "push")
321 (not (match_operand 1 "memory_operand" "")))
323 (and (eq_attr "type" "pop")
324 (not (match_operand 0 "memory_operand" "")))
326 (and (eq_attr "type" "imov")
327 (ior (and (match_operand 0 "register_operand" "")
328 (match_operand 1 "immediate_operand" ""))
329 (ior (and (match_operand 0 "ax_reg_operand" "")
330 (match_operand 1 "memory_displacement_only_operand" ""))
331 (and (match_operand 0 "memory_displacement_only_operand" "")
332 (match_operand 1 "ax_reg_operand" "")))))
334 (and (eq_attr "type" "call")
335 (match_operand 0 "constant_call_address_operand" ""))
337 (and (eq_attr "type" "callv")
338 (match_operand 1 "constant_call_address_operand" ""))
343 ;; The (bounding maximum) length of an instruction in bytes.
344 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
345 ;; Later we may want to split them and compute proper length as for
347 (define_attr "length" ""
348 (cond [(eq_attr "type" "other,multi,fistp,frndint")
350 (eq_attr "type" "fcmp")
352 (eq_attr "unit" "i387")
354 (plus (attr "prefix_data16")
355 (attr "length_address")))]
356 (plus (plus (attr "modrm")
357 (plus (attr "prefix_0f")
358 (plus (attr "prefix_rex")
360 (plus (attr "prefix_rep")
361 (plus (attr "prefix_data16")
362 (plus (attr "length_immediate")
363 (attr "length_address")))))))
365 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
366 ;; `store' if there is a simple memory reference therein, or `unknown'
367 ;; if the instruction is complex.
369 (define_attr "memory" "none,load,store,both,unknown"
370 (cond [(eq_attr "type" "other,multi,str")
371 (const_string "unknown")
372 (eq_attr "type" "lea,fcmov,fpspc,cld")
373 (const_string "none")
374 (eq_attr "type" "fistp,leave")
375 (const_string "both")
376 (eq_attr "type" "frndint")
377 (const_string "load")
378 (eq_attr "type" "push")
379 (if_then_else (match_operand 1 "memory_operand" "")
380 (const_string "both")
381 (const_string "store"))
382 (eq_attr "type" "pop")
383 (if_then_else (match_operand 0 "memory_operand" "")
384 (const_string "both")
385 (const_string "load"))
386 (eq_attr "type" "setcc")
387 (if_then_else (match_operand 0 "memory_operand" "")
388 (const_string "store")
389 (const_string "none"))
390 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
391 (if_then_else (ior (match_operand 0 "memory_operand" "")
392 (match_operand 1 "memory_operand" ""))
393 (const_string "load")
394 (const_string "none"))
395 (eq_attr "type" "ibr")
396 (if_then_else (match_operand 0 "memory_operand" "")
397 (const_string "load")
398 (const_string "none"))
399 (eq_attr "type" "call")
400 (if_then_else (match_operand 0 "constant_call_address_operand" "")
401 (const_string "none")
402 (const_string "load"))
403 (eq_attr "type" "callv")
404 (if_then_else (match_operand 1 "constant_call_address_operand" "")
405 (const_string "none")
406 (const_string "load"))
407 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
408 (match_operand 1 "memory_operand" ""))
409 (const_string "both")
410 (and (match_operand 0 "memory_operand" "")
411 (match_operand 1 "memory_operand" ""))
412 (const_string "both")
413 (match_operand 0 "memory_operand" "")
414 (const_string "store")
415 (match_operand 1 "memory_operand" "")
416 (const_string "load")
418 "!alu1,negnot,ishift1,
419 imov,imovx,icmp,test,
421 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
422 mmx,mmxmov,mmxcmp,mmxcvt")
423 (match_operand 2 "memory_operand" ""))
424 (const_string "load")
425 (and (eq_attr "type" "icmov")
426 (match_operand 3 "memory_operand" ""))
427 (const_string "load")
429 (const_string "none")))
431 ;; Indicates if an instruction has both an immediate and a displacement.
433 (define_attr "imm_disp" "false,true,unknown"
434 (cond [(eq_attr "type" "other,multi")
435 (const_string "unknown")
436 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
437 (and (match_operand 0 "memory_displacement_operand" "")
438 (match_operand 1 "immediate_operand" "")))
439 (const_string "true")
440 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
441 (and (match_operand 0 "memory_displacement_operand" "")
442 (match_operand 2 "immediate_operand" "")))
443 (const_string "true")
445 (const_string "false")))
447 ;; Indicates if an FP operation has an integer source.
449 (define_attr "fp_int_src" "false,true"
450 (const_string "false"))
452 ;; Defines rounding mode of an FP operation.
454 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
455 (const_string "any"))
457 ;; Describe a user's asm statement.
458 (define_asm_attributes
459 [(set_attr "length" "128")
460 (set_attr "type" "multi")])
462 ;; All x87 floating point modes
463 (define_mode_macro X87MODEF [SF DF XF])
465 ;; x87 SFmode and DFMode floating point modes
466 (define_mode_macro X87MODEF12 [SF DF])
468 ;; All integer modes handled by x87 fisttp operator.
469 (define_mode_macro X87MODEI [HI SI DI])
471 ;; All integer modes handled by integer x87 operators.
472 (define_mode_macro X87MODEI12 [HI SI])
474 ;; All SSE floating point modes
475 (define_mode_macro SSEMODEF [SF DF])
477 ;; All integer modes handled by SSE cvtts?2si* operators.
478 (define_mode_macro SSEMODEI24 [SI DI])
480 ;; SSE asm suffix for floating point modes
481 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
484 ;; Scheduling descriptions
486 (include "pentium.md")
489 (include "athlon.md")
493 ;; Operand and operator predicates and constraints
495 (include "predicates.md")
496 (include "constraints.md")
499 ;; Compare instructions.
501 ;; All compare insns have expanders that save the operands away without
502 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
503 ;; after the cmp) will actually emit the cmpM.
505 (define_expand "cmpti"
506 [(set (reg:CC FLAGS_REG)
507 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
508 (match_operand:TI 1 "x86_64_general_operand" "")))]
511 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
512 operands[0] = force_reg (TImode, operands[0]);
513 ix86_compare_op0 = operands[0];
514 ix86_compare_op1 = operands[1];
518 (define_expand "cmpdi"
519 [(set (reg:CC FLAGS_REG)
520 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
521 (match_operand:DI 1 "x86_64_general_operand" "")))]
524 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
525 operands[0] = force_reg (DImode, operands[0]);
526 ix86_compare_op0 = operands[0];
527 ix86_compare_op1 = operands[1];
531 (define_expand "cmpsi"
532 [(set (reg:CC FLAGS_REG)
533 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
534 (match_operand:SI 1 "general_operand" "")))]
537 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
538 operands[0] = force_reg (SImode, operands[0]);
539 ix86_compare_op0 = operands[0];
540 ix86_compare_op1 = operands[1];
544 (define_expand "cmphi"
545 [(set (reg:CC FLAGS_REG)
546 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
547 (match_operand:HI 1 "general_operand" "")))]
550 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
551 operands[0] = force_reg (HImode, operands[0]);
552 ix86_compare_op0 = operands[0];
553 ix86_compare_op1 = operands[1];
557 (define_expand "cmpqi"
558 [(set (reg:CC FLAGS_REG)
559 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
560 (match_operand:QI 1 "general_operand" "")))]
563 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
564 operands[0] = force_reg (QImode, operands[0]);
565 ix86_compare_op0 = operands[0];
566 ix86_compare_op1 = operands[1];
570 (define_insn "cmpdi_ccno_1_rex64"
571 [(set (reg FLAGS_REG)
572 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
573 (match_operand:DI 1 "const0_operand" "n,n")))]
574 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
576 test{q}\t{%0, %0|%0, %0}
577 cmp{q}\t{%1, %0|%0, %1}"
578 [(set_attr "type" "test,icmp")
579 (set_attr "length_immediate" "0,1")
580 (set_attr "mode" "DI")])
582 (define_insn "*cmpdi_minus_1_rex64"
583 [(set (reg FLAGS_REG)
584 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
585 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
587 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
588 "cmp{q}\t{%1, %0|%0, %1}"
589 [(set_attr "type" "icmp")
590 (set_attr "mode" "DI")])
592 (define_expand "cmpdi_1_rex64"
593 [(set (reg:CC FLAGS_REG)
594 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
595 (match_operand:DI 1 "general_operand" "")))]
599 (define_insn "cmpdi_1_insn_rex64"
600 [(set (reg FLAGS_REG)
601 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
602 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
603 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
604 "cmp{q}\t{%1, %0|%0, %1}"
605 [(set_attr "type" "icmp")
606 (set_attr "mode" "DI")])
609 (define_insn "*cmpsi_ccno_1"
610 [(set (reg FLAGS_REG)
611 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
612 (match_operand:SI 1 "const0_operand" "n,n")))]
613 "ix86_match_ccmode (insn, CCNOmode)"
615 test{l}\t{%0, %0|%0, %0}
616 cmp{l}\t{%1, %0|%0, %1}"
617 [(set_attr "type" "test,icmp")
618 (set_attr "length_immediate" "0,1")
619 (set_attr "mode" "SI")])
621 (define_insn "*cmpsi_minus_1"
622 [(set (reg FLAGS_REG)
623 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
624 (match_operand:SI 1 "general_operand" "ri,mr"))
626 "ix86_match_ccmode (insn, CCGOCmode)"
627 "cmp{l}\t{%1, %0|%0, %1}"
628 [(set_attr "type" "icmp")
629 (set_attr "mode" "SI")])
631 (define_expand "cmpsi_1"
632 [(set (reg:CC FLAGS_REG)
633 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
634 (match_operand:SI 1 "general_operand" "ri,mr")))]
638 (define_insn "*cmpsi_1_insn"
639 [(set (reg FLAGS_REG)
640 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
641 (match_operand:SI 1 "general_operand" "ri,mr")))]
642 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
643 && ix86_match_ccmode (insn, CCmode)"
644 "cmp{l}\t{%1, %0|%0, %1}"
645 [(set_attr "type" "icmp")
646 (set_attr "mode" "SI")])
648 (define_insn "*cmphi_ccno_1"
649 [(set (reg FLAGS_REG)
650 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
651 (match_operand:HI 1 "const0_operand" "n,n")))]
652 "ix86_match_ccmode (insn, CCNOmode)"
654 test{w}\t{%0, %0|%0, %0}
655 cmp{w}\t{%1, %0|%0, %1}"
656 [(set_attr "type" "test,icmp")
657 (set_attr "length_immediate" "0,1")
658 (set_attr "mode" "HI")])
660 (define_insn "*cmphi_minus_1"
661 [(set (reg FLAGS_REG)
662 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
663 (match_operand:HI 1 "general_operand" "ri,mr"))
665 "ix86_match_ccmode (insn, CCGOCmode)"
666 "cmp{w}\t{%1, %0|%0, %1}"
667 [(set_attr "type" "icmp")
668 (set_attr "mode" "HI")])
670 (define_insn "*cmphi_1"
671 [(set (reg FLAGS_REG)
672 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
673 (match_operand:HI 1 "general_operand" "ri,mr")))]
674 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
675 && ix86_match_ccmode (insn, CCmode)"
676 "cmp{w}\t{%1, %0|%0, %1}"
677 [(set_attr "type" "icmp")
678 (set_attr "mode" "HI")])
680 (define_insn "*cmpqi_ccno_1"
681 [(set (reg FLAGS_REG)
682 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
683 (match_operand:QI 1 "const0_operand" "n,n")))]
684 "ix86_match_ccmode (insn, CCNOmode)"
686 test{b}\t{%0, %0|%0, %0}
687 cmp{b}\t{$0, %0|%0, 0}"
688 [(set_attr "type" "test,icmp")
689 (set_attr "length_immediate" "0,1")
690 (set_attr "mode" "QI")])
692 (define_insn "*cmpqi_1"
693 [(set (reg FLAGS_REG)
694 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
695 (match_operand:QI 1 "general_operand" "qi,mq")))]
696 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
697 && ix86_match_ccmode (insn, CCmode)"
698 "cmp{b}\t{%1, %0|%0, %1}"
699 [(set_attr "type" "icmp")
700 (set_attr "mode" "QI")])
702 (define_insn "*cmpqi_minus_1"
703 [(set (reg FLAGS_REG)
704 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
705 (match_operand:QI 1 "general_operand" "qi,mq"))
707 "ix86_match_ccmode (insn, CCGOCmode)"
708 "cmp{b}\t{%1, %0|%0, %1}"
709 [(set_attr "type" "icmp")
710 (set_attr "mode" "QI")])
712 (define_insn "*cmpqi_ext_1"
713 [(set (reg FLAGS_REG)
715 (match_operand:QI 0 "general_operand" "Qm")
718 (match_operand 1 "ext_register_operand" "Q")
721 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
722 "cmp{b}\t{%h1, %0|%0, %h1}"
723 [(set_attr "type" "icmp")
724 (set_attr "mode" "QI")])
726 (define_insn "*cmpqi_ext_1_rex64"
727 [(set (reg FLAGS_REG)
729 (match_operand:QI 0 "register_operand" "Q")
732 (match_operand 1 "ext_register_operand" "Q")
735 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
736 "cmp{b}\t{%h1, %0|%0, %h1}"
737 [(set_attr "type" "icmp")
738 (set_attr "mode" "QI")])
740 (define_insn "*cmpqi_ext_2"
741 [(set (reg FLAGS_REG)
745 (match_operand 0 "ext_register_operand" "Q")
748 (match_operand:QI 1 "const0_operand" "n")))]
749 "ix86_match_ccmode (insn, CCNOmode)"
751 [(set_attr "type" "test")
752 (set_attr "length_immediate" "0")
753 (set_attr "mode" "QI")])
755 (define_expand "cmpqi_ext_3"
756 [(set (reg:CC FLAGS_REG)
760 (match_operand 0 "ext_register_operand" "")
763 (match_operand:QI 1 "general_operand" "")))]
767 (define_insn "cmpqi_ext_3_insn"
768 [(set (reg FLAGS_REG)
772 (match_operand 0 "ext_register_operand" "Q")
775 (match_operand:QI 1 "general_operand" "Qmn")))]
776 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
777 "cmp{b}\t{%1, %h0|%h0, %1}"
778 [(set_attr "type" "icmp")
779 (set_attr "mode" "QI")])
781 (define_insn "cmpqi_ext_3_insn_rex64"
782 [(set (reg FLAGS_REG)
786 (match_operand 0 "ext_register_operand" "Q")
789 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
790 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
791 "cmp{b}\t{%1, %h0|%h0, %1}"
792 [(set_attr "type" "icmp")
793 (set_attr "mode" "QI")])
795 (define_insn "*cmpqi_ext_4"
796 [(set (reg FLAGS_REG)
800 (match_operand 0 "ext_register_operand" "Q")
805 (match_operand 1 "ext_register_operand" "Q")
808 "ix86_match_ccmode (insn, CCmode)"
809 "cmp{b}\t{%h1, %h0|%h0, %h1}"
810 [(set_attr "type" "icmp")
811 (set_attr "mode" "QI")])
813 ;; These implement float point compares.
814 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
815 ;; which would allow mix and match FP modes on the compares. Which is what
816 ;; the old patterns did, but with many more of them.
818 (define_expand "cmpxf"
819 [(set (reg:CC FLAGS_REG)
820 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
821 (match_operand:XF 1 "nonmemory_operand" "")))]
824 ix86_compare_op0 = operands[0];
825 ix86_compare_op1 = operands[1];
829 (define_expand "cmpdf"
830 [(set (reg:CC FLAGS_REG)
831 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
832 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
833 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
835 ix86_compare_op0 = operands[0];
836 ix86_compare_op1 = operands[1];
840 (define_expand "cmpsf"
841 [(set (reg:CC FLAGS_REG)
842 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
843 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
844 "TARGET_80387 || TARGET_SSE_MATH"
846 ix86_compare_op0 = operands[0];
847 ix86_compare_op1 = operands[1];
851 ;; FP compares, step 1:
852 ;; Set the FP condition codes.
854 ;; CCFPmode compare with exceptions
855 ;; CCFPUmode compare with no exceptions
857 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
858 ;; used to manage the reg stack popping would not be preserved.
860 (define_insn "*cmpfp_0"
861 [(set (match_operand:HI 0 "register_operand" "=a")
864 (match_operand 1 "register_operand" "f")
865 (match_operand 2 "const0_operand" "X"))]
868 && FLOAT_MODE_P (GET_MODE (operands[1]))
869 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
870 "* return output_fp_compare (insn, operands, 0, 0);"
871 [(set_attr "type" "multi")
872 (set_attr "unit" "i387")
874 (cond [(match_operand:SF 1 "" "")
876 (match_operand:DF 1 "" "")
879 (const_string "XF")))])
881 (define_insn "*cmpfp_sf"
882 [(set (match_operand:HI 0 "register_operand" "=a")
885 (match_operand:SF 1 "register_operand" "f")
886 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
889 "* return output_fp_compare (insn, operands, 0, 0);"
890 [(set_attr "type" "multi")
891 (set_attr "unit" "i387")
892 (set_attr "mode" "SF")])
894 (define_insn "*cmpfp_df"
895 [(set (match_operand:HI 0 "register_operand" "=a")
898 (match_operand:DF 1 "register_operand" "f")
899 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
902 "* return output_fp_compare (insn, operands, 0, 0);"
903 [(set_attr "type" "multi")
904 (set_attr "unit" "i387")
905 (set_attr "mode" "DF")])
907 (define_insn "*cmpfp_xf"
908 [(set (match_operand:HI 0 "register_operand" "=a")
911 (match_operand:XF 1 "register_operand" "f")
912 (match_operand:XF 2 "register_operand" "f"))]
915 "* return output_fp_compare (insn, operands, 0, 0);"
916 [(set_attr "type" "multi")
917 (set_attr "unit" "i387")
918 (set_attr "mode" "XF")])
920 (define_insn "*cmpfp_u"
921 [(set (match_operand:HI 0 "register_operand" "=a")
924 (match_operand 1 "register_operand" "f")
925 (match_operand 2 "register_operand" "f"))]
928 && FLOAT_MODE_P (GET_MODE (operands[1]))
929 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
930 "* return output_fp_compare (insn, operands, 0, 1);"
931 [(set_attr "type" "multi")
932 (set_attr "unit" "i387")
934 (cond [(match_operand:SF 1 "" "")
936 (match_operand:DF 1 "" "")
939 (const_string "XF")))])
941 (define_insn "*cmpfp_<mode>"
942 [(set (match_operand:HI 0 "register_operand" "=a")
945 (match_operand 1 "register_operand" "f")
946 (match_operator 3 "float_operator"
947 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
949 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
950 && FLOAT_MODE_P (GET_MODE (operands[1]))
951 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
952 "* return output_fp_compare (insn, operands, 0, 0);"
953 [(set_attr "type" "multi")
954 (set_attr "unit" "i387")
955 (set_attr "fp_int_src" "true")
956 (set_attr "mode" "<MODE>")])
958 ;; FP compares, step 2
959 ;; Move the fpsw to ax.
961 (define_insn "x86_fnstsw_1"
962 [(set (match_operand:HI 0 "register_operand" "=a")
963 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
966 [(set_attr "length" "2")
967 (set_attr "mode" "SI")
968 (set_attr "unit" "i387")])
970 ;; FP compares, step 3
971 ;; Get ax into flags, general case.
973 (define_insn "x86_sahf_1"
974 [(set (reg:CC FLAGS_REG)
975 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
978 [(set_attr "length" "1")
979 (set_attr "athlon_decode" "vector")
980 (set_attr "mode" "SI")])
982 ;; Pentium Pro can do steps 1 through 3 in one go.
984 (define_insn "*cmpfp_i_mixed"
985 [(set (reg:CCFP FLAGS_REG)
986 (compare:CCFP (match_operand 0 "register_operand" "f,x")
987 (match_operand 1 "nonimmediate_operand" "f,xm")))]
989 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991 "* return output_fp_compare (insn, operands, 1, 0);"
992 [(set_attr "type" "fcmp,ssecomi")
994 (if_then_else (match_operand:SF 1 "" "")
996 (const_string "DF")))
997 (set_attr "athlon_decode" "vector")])
999 (define_insn "*cmpfp_i_sse"
1000 [(set (reg:CCFP FLAGS_REG)
1001 (compare:CCFP (match_operand 0 "register_operand" "x")
1002 (match_operand 1 "nonimmediate_operand" "xm")))]
1004 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006 "* return output_fp_compare (insn, operands, 1, 0);"
1007 [(set_attr "type" "ssecomi")
1009 (if_then_else (match_operand:SF 1 "" "")
1011 (const_string "DF")))
1012 (set_attr "athlon_decode" "vector")])
1014 (define_insn "*cmpfp_i_i387"
1015 [(set (reg:CCFP FLAGS_REG)
1016 (compare:CCFP (match_operand 0 "register_operand" "f")
1017 (match_operand 1 "register_operand" "f")))]
1018 "TARGET_80387 && TARGET_CMOVE
1019 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1020 && FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022 "* return output_fp_compare (insn, operands, 1, 0);"
1023 [(set_attr "type" "fcmp")
1025 (cond [(match_operand:SF 1 "" "")
1027 (match_operand:DF 1 "" "")
1030 (const_string "XF")))
1031 (set_attr "athlon_decode" "vector")])
1033 (define_insn "*cmpfp_iu_mixed"
1034 [(set (reg:CCFPU FLAGS_REG)
1035 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1036 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1037 "TARGET_MIX_SSE_I387
1038 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040 "* return output_fp_compare (insn, operands, 1, 1);"
1041 [(set_attr "type" "fcmp,ssecomi")
1043 (if_then_else (match_operand:SF 1 "" "")
1045 (const_string "DF")))
1046 (set_attr "athlon_decode" "vector")])
1048 (define_insn "*cmpfp_iu_sse"
1049 [(set (reg:CCFPU FLAGS_REG)
1050 (compare:CCFPU (match_operand 0 "register_operand" "x")
1051 (match_operand 1 "nonimmediate_operand" "xm")))]
1053 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1054 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055 "* return output_fp_compare (insn, operands, 1, 1);"
1056 [(set_attr "type" "ssecomi")
1058 (if_then_else (match_operand:SF 1 "" "")
1060 (const_string "DF")))
1061 (set_attr "athlon_decode" "vector")])
1063 (define_insn "*cmpfp_iu_387"
1064 [(set (reg:CCFPU FLAGS_REG)
1065 (compare:CCFPU (match_operand 0 "register_operand" "f")
1066 (match_operand 1 "register_operand" "f")))]
1067 "TARGET_80387 && TARGET_CMOVE
1068 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1069 && FLOAT_MODE_P (GET_MODE (operands[0]))
1070 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1071 "* return output_fp_compare (insn, operands, 1, 1);"
1072 [(set_attr "type" "fcmp")
1074 (cond [(match_operand:SF 1 "" "")
1076 (match_operand:DF 1 "" "")
1079 (const_string "XF")))
1080 (set_attr "athlon_decode" "vector")])
1082 ;; Move instructions.
1084 ;; General case of fullword move.
1086 (define_expand "movsi"
1087 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1088 (match_operand:SI 1 "general_operand" ""))]
1090 "ix86_expand_move (SImode, operands); DONE;")
1092 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1095 ;; %%% We don't use a post-inc memory reference because x86 is not a
1096 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1097 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1098 ;; targets without our curiosities, and it is just as easy to represent
1099 ;; this differently.
1101 (define_insn "*pushsi2"
1102 [(set (match_operand:SI 0 "push_operand" "=<")
1103 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1106 [(set_attr "type" "push")
1107 (set_attr "mode" "SI")])
1109 ;; For 64BIT abi we always round up to 8 bytes.
1110 (define_insn "*pushsi2_rex64"
1111 [(set (match_operand:SI 0 "push_operand" "=X")
1112 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1115 [(set_attr "type" "push")
1116 (set_attr "mode" "SI")])
1118 (define_insn "*pushsi2_prologue"
1119 [(set (match_operand:SI 0 "push_operand" "=<")
1120 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1121 (clobber (mem:BLK (scratch)))]
1124 [(set_attr "type" "push")
1125 (set_attr "mode" "SI")])
1127 (define_insn "*popsi1_epilogue"
1128 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1129 (mem:SI (reg:SI SP_REG)))
1130 (set (reg:SI SP_REG)
1131 (plus:SI (reg:SI SP_REG) (const_int 4)))
1132 (clobber (mem:BLK (scratch)))]
1135 [(set_attr "type" "pop")
1136 (set_attr "mode" "SI")])
1138 (define_insn "popsi1"
1139 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1140 (mem:SI (reg:SI SP_REG)))
1141 (set (reg:SI SP_REG)
1142 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1145 [(set_attr "type" "pop")
1146 (set_attr "mode" "SI")])
1148 (define_insn "*movsi_xor"
1149 [(set (match_operand:SI 0 "register_operand" "=r")
1150 (match_operand:SI 1 "const0_operand" "i"))
1151 (clobber (reg:CC FLAGS_REG))]
1152 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1153 "xor{l}\t{%0, %0|%0, %0}"
1154 [(set_attr "type" "alu1")
1155 (set_attr "mode" "SI")
1156 (set_attr "length_immediate" "0")])
1158 (define_insn "*movsi_or"
1159 [(set (match_operand:SI 0 "register_operand" "=r")
1160 (match_operand:SI 1 "immediate_operand" "i"))
1161 (clobber (reg:CC FLAGS_REG))]
1163 && operands[1] == constm1_rtx
1164 && (TARGET_PENTIUM || optimize_size)"
1166 operands[1] = constm1_rtx;
1167 return "or{l}\t{%1, %0|%0, %1}";
1169 [(set_attr "type" "alu1")
1170 (set_attr "mode" "SI")
1171 (set_attr "length_immediate" "1")])
1173 (define_insn "*movsi_1"
1174 [(set (match_operand:SI 0 "nonimmediate_operand"
1175 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1176 (match_operand:SI 1 "general_operand"
1177 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1178 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1180 switch (get_attr_type (insn))
1183 if (get_attr_mode (insn) == MODE_TI)
1184 return "pxor\t%0, %0";
1185 return "xorps\t%0, %0";
1188 switch (get_attr_mode (insn))
1191 return "movdqa\t{%1, %0|%0, %1}";
1193 return "movaps\t{%1, %0|%0, %1}";
1195 return "movd\t{%1, %0|%0, %1}";
1197 return "movss\t{%1, %0|%0, %1}";
1203 return "pxor\t%0, %0";
1206 if (get_attr_mode (insn) == MODE_DI)
1207 return "movq\t{%1, %0|%0, %1}";
1208 return "movd\t{%1, %0|%0, %1}";
1211 return "lea{l}\t{%1, %0|%0, %1}";
1214 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1215 return "mov{l}\t{%1, %0|%0, %1}";
1219 (cond [(eq_attr "alternative" "2")
1220 (const_string "mmxadd")
1221 (eq_attr "alternative" "3,4,5")
1222 (const_string "mmxmov")
1223 (eq_attr "alternative" "6")
1224 (const_string "sselog1")
1225 (eq_attr "alternative" "7,8,9,10,11")
1226 (const_string "ssemov")
1227 (match_operand:DI 1 "pic_32bit_operand" "")
1228 (const_string "lea")
1230 (const_string "imov")))
1232 (cond [(eq_attr "alternative" "2,3")
1234 (eq_attr "alternative" "6,7")
1236 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1237 (const_string "V4SF")
1238 (const_string "TI"))
1239 (and (eq_attr "alternative" "8,9,10,11")
1240 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1243 (const_string "SI")))])
1245 ;; Stores and loads of ax to arbitrary constant address.
1246 ;; We fake an second form of instruction to force reload to load address
1247 ;; into register when rax is not available
1248 (define_insn "*movabssi_1_rex64"
1249 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1250 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1251 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1253 movabs{l}\t{%1, %P0|%P0, %1}
1254 mov{l}\t{%1, %a0|%a0, %1}"
1255 [(set_attr "type" "imov")
1256 (set_attr "modrm" "0,*")
1257 (set_attr "length_address" "8,0")
1258 (set_attr "length_immediate" "0,*")
1259 (set_attr "memory" "store")
1260 (set_attr "mode" "SI")])
1262 (define_insn "*movabssi_2_rex64"
1263 [(set (match_operand:SI 0 "register_operand" "=a,r")
1264 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1265 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1267 movabs{l}\t{%P1, %0|%0, %P1}
1268 mov{l}\t{%a1, %0|%0, %a1}"
1269 [(set_attr "type" "imov")
1270 (set_attr "modrm" "0,*")
1271 (set_attr "length_address" "8,0")
1272 (set_attr "length_immediate" "0")
1273 (set_attr "memory" "load")
1274 (set_attr "mode" "SI")])
1276 (define_insn "*swapsi"
1277 [(set (match_operand:SI 0 "register_operand" "+r")
1278 (match_operand:SI 1 "register_operand" "+r"))
1283 [(set_attr "type" "imov")
1284 (set_attr "mode" "SI")
1285 (set_attr "pent_pair" "np")
1286 (set_attr "athlon_decode" "vector")])
1288 (define_expand "movhi"
1289 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1290 (match_operand:HI 1 "general_operand" ""))]
1292 "ix86_expand_move (HImode, operands); DONE;")
1294 (define_insn "*pushhi2"
1295 [(set (match_operand:HI 0 "push_operand" "=X")
1296 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1299 [(set_attr "type" "push")
1300 (set_attr "mode" "SI")])
1302 ;; For 64BIT abi we always round up to 8 bytes.
1303 (define_insn "*pushhi2_rex64"
1304 [(set (match_operand:HI 0 "push_operand" "=X")
1305 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1308 [(set_attr "type" "push")
1309 (set_attr "mode" "DI")])
1311 (define_insn "*movhi_1"
1312 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1313 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1314 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1316 switch (get_attr_type (insn))
1319 /* movzwl is faster than movw on p2 due to partial word stalls,
1320 though not as fast as an aligned movl. */
1321 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1323 if (get_attr_mode (insn) == MODE_SI)
1324 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1326 return "mov{w}\t{%1, %0|%0, %1}";
1330 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1331 (const_string "imov")
1332 (and (eq_attr "alternative" "0")
1333 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1335 (eq (symbol_ref "TARGET_HIMODE_MATH")
1337 (const_string "imov")
1338 (and (eq_attr "alternative" "1,2")
1339 (match_operand:HI 1 "aligned_operand" ""))
1340 (const_string "imov")
1341 (and (ne (symbol_ref "TARGET_MOVX")
1343 (eq_attr "alternative" "0,2"))
1344 (const_string "imovx")
1346 (const_string "imov")))
1348 (cond [(eq_attr "type" "imovx")
1350 (and (eq_attr "alternative" "1,2")
1351 (match_operand:HI 1 "aligned_operand" ""))
1353 (and (eq_attr "alternative" "0")
1354 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1356 (eq (symbol_ref "TARGET_HIMODE_MATH")
1360 (const_string "HI")))])
1362 ;; Stores and loads of ax to arbitrary constant address.
1363 ;; We fake an second form of instruction to force reload to load address
1364 ;; into register when rax is not available
1365 (define_insn "*movabshi_1_rex64"
1366 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1367 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1368 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1370 movabs{w}\t{%1, %P0|%P0, %1}
1371 mov{w}\t{%1, %a0|%a0, %1}"
1372 [(set_attr "type" "imov")
1373 (set_attr "modrm" "0,*")
1374 (set_attr "length_address" "8,0")
1375 (set_attr "length_immediate" "0,*")
1376 (set_attr "memory" "store")
1377 (set_attr "mode" "HI")])
1379 (define_insn "*movabshi_2_rex64"
1380 [(set (match_operand:HI 0 "register_operand" "=a,r")
1381 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1382 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1384 movabs{w}\t{%P1, %0|%0, %P1}
1385 mov{w}\t{%a1, %0|%0, %a1}"
1386 [(set_attr "type" "imov")
1387 (set_attr "modrm" "0,*")
1388 (set_attr "length_address" "8,0")
1389 (set_attr "length_immediate" "0")
1390 (set_attr "memory" "load")
1391 (set_attr "mode" "HI")])
1393 (define_insn "*swaphi_1"
1394 [(set (match_operand:HI 0 "register_operand" "+r")
1395 (match_operand:HI 1 "register_operand" "+r"))
1398 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1400 [(set_attr "type" "imov")
1401 (set_attr "mode" "SI")
1402 (set_attr "pent_pair" "np")
1403 (set_attr "athlon_decode" "vector")])
1405 (define_insn "*swaphi_2"
1406 [(set (match_operand:HI 0 "register_operand" "+r")
1407 (match_operand:HI 1 "register_operand" "+r"))
1410 "TARGET_PARTIAL_REG_STALL"
1412 [(set_attr "type" "imov")
1413 (set_attr "mode" "HI")
1414 (set_attr "pent_pair" "np")
1415 (set_attr "athlon_decode" "vector")])
1417 (define_expand "movstricthi"
1418 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1419 (match_operand:HI 1 "general_operand" ""))]
1420 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1422 /* Don't generate memory->memory moves, go through a register */
1423 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1424 operands[1] = force_reg (HImode, operands[1]);
1427 (define_insn "*movstricthi_1"
1428 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1429 (match_operand:HI 1 "general_operand" "rn,m"))]
1430 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1431 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1432 "mov{w}\t{%1, %0|%0, %1}"
1433 [(set_attr "type" "imov")
1434 (set_attr "mode" "HI")])
1436 (define_insn "*movstricthi_xor"
1437 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1438 (match_operand:HI 1 "const0_operand" "i"))
1439 (clobber (reg:CC FLAGS_REG))]
1441 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1442 "xor{w}\t{%0, %0|%0, %0}"
1443 [(set_attr "type" "alu1")
1444 (set_attr "mode" "HI")
1445 (set_attr "length_immediate" "0")])
1447 (define_expand "movqi"
1448 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1449 (match_operand:QI 1 "general_operand" ""))]
1451 "ix86_expand_move (QImode, operands); DONE;")
1453 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1454 ;; "push a byte". But actually we use pushl, which has the effect
1455 ;; of rounding the amount pushed up to a word.
1457 (define_insn "*pushqi2"
1458 [(set (match_operand:QI 0 "push_operand" "=X")
1459 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1462 [(set_attr "type" "push")
1463 (set_attr "mode" "SI")])
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushqi2_rex64"
1467 [(set (match_operand:QI 0 "push_operand" "=X")
1468 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1471 [(set_attr "type" "push")
1472 (set_attr "mode" "DI")])
1474 ;; Situation is quite tricky about when to choose full sized (SImode) move
1475 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1476 ;; partial register dependency machines (such as AMD Athlon), where QImode
1477 ;; moves issue extra dependency and for partial register stalls machines
1478 ;; that don't use QImode patterns (and QImode move cause stall on the next
1481 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1482 ;; register stall machines with, where we use QImode instructions, since
1483 ;; partial register stall can be caused there. Then we use movzx.
1484 (define_insn "*movqi_1"
1485 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1486 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1487 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1489 switch (get_attr_type (insn))
1492 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1493 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1495 if (get_attr_mode (insn) == MODE_SI)
1496 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1498 return "mov{b}\t{%1, %0|%0, %1}";
1502 (cond [(and (eq_attr "alternative" "5")
1503 (not (match_operand:QI 1 "aligned_operand" "")))
1504 (const_string "imovx")
1505 (ne (symbol_ref "optimize_size") (const_int 0))
1506 (const_string "imov")
1507 (and (eq_attr "alternative" "3")
1508 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1510 (eq (symbol_ref "TARGET_QIMODE_MATH")
1512 (const_string "imov")
1513 (eq_attr "alternative" "3,5")
1514 (const_string "imovx")
1515 (and (ne (symbol_ref "TARGET_MOVX")
1517 (eq_attr "alternative" "2"))
1518 (const_string "imovx")
1520 (const_string "imov")))
1522 (cond [(eq_attr "alternative" "3,4,5")
1524 (eq_attr "alternative" "6")
1526 (eq_attr "type" "imovx")
1528 (and (eq_attr "type" "imov")
1529 (and (eq_attr "alternative" "0,1")
1530 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1532 (and (eq (symbol_ref "optimize_size")
1534 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1537 ;; Avoid partial register stalls when not using QImode arithmetic
1538 (and (eq_attr "type" "imov")
1539 (and (eq_attr "alternative" "0,1")
1540 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1542 (eq (symbol_ref "TARGET_QIMODE_MATH")
1546 (const_string "QI")))])
1548 (define_expand "reload_outqi"
1549 [(parallel [(match_operand:QI 0 "" "=m")
1550 (match_operand:QI 1 "register_operand" "r")
1551 (match_operand:QI 2 "register_operand" "=&q")])]
1555 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1557 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1558 if (! q_regs_operand (op1, QImode))
1560 emit_insn (gen_movqi (op2, op1));
1563 emit_insn (gen_movqi (op0, op1));
1567 (define_insn "*swapqi_1"
1568 [(set (match_operand:QI 0 "register_operand" "+r")
1569 (match_operand:QI 1 "register_operand" "+r"))
1572 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1574 [(set_attr "type" "imov")
1575 (set_attr "mode" "SI")
1576 (set_attr "pent_pair" "np")
1577 (set_attr "athlon_decode" "vector")])
1579 (define_insn "*swapqi_2"
1580 [(set (match_operand:QI 0 "register_operand" "+q")
1581 (match_operand:QI 1 "register_operand" "+q"))
1584 "TARGET_PARTIAL_REG_STALL"
1586 [(set_attr "type" "imov")
1587 (set_attr "mode" "QI")
1588 (set_attr "pent_pair" "np")
1589 (set_attr "athlon_decode" "vector")])
1591 (define_expand "movstrictqi"
1592 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1593 (match_operand:QI 1 "general_operand" ""))]
1594 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1596 /* Don't generate memory->memory moves, go through a register. */
1597 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1598 operands[1] = force_reg (QImode, operands[1]);
1601 (define_insn "*movstrictqi_1"
1602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1603 (match_operand:QI 1 "general_operand" "*qn,m"))]
1604 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1605 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1606 "mov{b}\t{%1, %0|%0, %1}"
1607 [(set_attr "type" "imov")
1608 (set_attr "mode" "QI")])
1610 (define_insn "*movstrictqi_xor"
1611 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1612 (match_operand:QI 1 "const0_operand" "i"))
1613 (clobber (reg:CC FLAGS_REG))]
1614 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1615 "xor{b}\t{%0, %0|%0, %0}"
1616 [(set_attr "type" "alu1")
1617 (set_attr "mode" "QI")
1618 (set_attr "length_immediate" "0")])
1620 (define_insn "*movsi_extv_1"
1621 [(set (match_operand:SI 0 "register_operand" "=R")
1622 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1626 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1627 [(set_attr "type" "imovx")
1628 (set_attr "mode" "SI")])
1630 (define_insn "*movhi_extv_1"
1631 [(set (match_operand:HI 0 "register_operand" "=R")
1632 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1636 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1637 [(set_attr "type" "imovx")
1638 (set_attr "mode" "SI")])
1640 (define_insn "*movqi_extv_1"
1641 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1642 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1647 switch (get_attr_type (insn))
1650 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1652 return "mov{b}\t{%h1, %0|%0, %h1}";
1656 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1657 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1658 (ne (symbol_ref "TARGET_MOVX")
1660 (const_string "imovx")
1661 (const_string "imov")))
1663 (if_then_else (eq_attr "type" "imovx")
1665 (const_string "QI")))])
1667 (define_insn "*movqi_extv_1_rex64"
1668 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1669 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1674 switch (get_attr_type (insn))
1677 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1679 return "mov{b}\t{%h1, %0|%0, %h1}";
1683 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1684 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1685 (ne (symbol_ref "TARGET_MOVX")
1687 (const_string "imovx")
1688 (const_string "imov")))
1690 (if_then_else (eq_attr "type" "imovx")
1692 (const_string "QI")))])
1694 ;; Stores and loads of ax to arbitrary constant address.
1695 ;; We fake an second form of instruction to force reload to load address
1696 ;; into register when rax is not available
1697 (define_insn "*movabsqi_1_rex64"
1698 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1699 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1700 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1702 movabs{b}\t{%1, %P0|%P0, %1}
1703 mov{b}\t{%1, %a0|%a0, %1}"
1704 [(set_attr "type" "imov")
1705 (set_attr "modrm" "0,*")
1706 (set_attr "length_address" "8,0")
1707 (set_attr "length_immediate" "0,*")
1708 (set_attr "memory" "store")
1709 (set_attr "mode" "QI")])
1711 (define_insn "*movabsqi_2_rex64"
1712 [(set (match_operand:QI 0 "register_operand" "=a,r")
1713 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1714 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1716 movabs{b}\t{%P1, %0|%0, %P1}
1717 mov{b}\t{%a1, %0|%0, %a1}"
1718 [(set_attr "type" "imov")
1719 (set_attr "modrm" "0,*")
1720 (set_attr "length_address" "8,0")
1721 (set_attr "length_immediate" "0")
1722 (set_attr "memory" "load")
1723 (set_attr "mode" "QI")])
1725 (define_insn "*movdi_extzv_1"
1726 [(set (match_operand:DI 0 "register_operand" "=R")
1727 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1731 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1732 [(set_attr "type" "imovx")
1733 (set_attr "mode" "DI")])
1735 (define_insn "*movsi_extzv_1"
1736 [(set (match_operand:SI 0 "register_operand" "=R")
1737 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1741 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1742 [(set_attr "type" "imovx")
1743 (set_attr "mode" "SI")])
1745 (define_insn "*movqi_extzv_2"
1746 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1747 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1752 switch (get_attr_type (insn))
1755 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1757 return "mov{b}\t{%h1, %0|%0, %h1}";
1761 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1762 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1763 (ne (symbol_ref "TARGET_MOVX")
1765 (const_string "imovx")
1766 (const_string "imov")))
1768 (if_then_else (eq_attr "type" "imovx")
1770 (const_string "QI")))])
1772 (define_insn "*movqi_extzv_2_rex64"
1773 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1774 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1779 switch (get_attr_type (insn))
1782 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1784 return "mov{b}\t{%h1, %0|%0, %h1}";
1788 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789 (ne (symbol_ref "TARGET_MOVX")
1791 (const_string "imovx")
1792 (const_string "imov")))
1794 (if_then_else (eq_attr "type" "imovx")
1796 (const_string "QI")))])
1798 (define_insn "movsi_insv_1"
1799 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1802 (match_operand:SI 1 "general_operand" "Qmn"))]
1804 "mov{b}\t{%b1, %h0|%h0, %b1}"
1805 [(set_attr "type" "imov")
1806 (set_attr "mode" "QI")])
1808 (define_insn "movdi_insv_1_rex64"
1809 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1812 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1814 "mov{b}\t{%b1, %h0|%h0, %b1}"
1815 [(set_attr "type" "imov")
1816 (set_attr "mode" "QI")])
1818 (define_insn "*movqi_insv_2"
1819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1822 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1825 "mov{b}\t{%h1, %h0|%h0, %h1}"
1826 [(set_attr "type" "imov")
1827 (set_attr "mode" "QI")])
1829 (define_expand "movdi"
1830 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1831 (match_operand:DI 1 "general_operand" ""))]
1833 "ix86_expand_move (DImode, operands); DONE;")
1835 (define_insn "*pushdi"
1836 [(set (match_operand:DI 0 "push_operand" "=<")
1837 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1841 (define_insn "*pushdi2_rex64"
1842 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1843 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1848 [(set_attr "type" "push,multi")
1849 (set_attr "mode" "DI")])
1851 ;; Convert impossible pushes of immediate to existing instructions.
1852 ;; First try to get scratch register and go through it. In case this
1853 ;; fails, push sign extended lower part first and then overwrite
1854 ;; upper part by 32bit move.
1856 [(match_scratch:DI 2 "r")
1857 (set (match_operand:DI 0 "push_operand" "")
1858 (match_operand:DI 1 "immediate_operand" ""))]
1859 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1860 && !x86_64_immediate_operand (operands[1], DImode)"
1861 [(set (match_dup 2) (match_dup 1))
1862 (set (match_dup 0) (match_dup 2))]
1865 ;; We need to define this as both peepholer and splitter for case
1866 ;; peephole2 pass is not run.
1867 ;; "&& 1" is needed to keep it from matching the previous pattern.
1869 [(set (match_operand:DI 0 "push_operand" "")
1870 (match_operand:DI 1 "immediate_operand" ""))]
1871 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1872 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1873 [(set (match_dup 0) (match_dup 1))
1874 (set (match_dup 2) (match_dup 3))]
1875 "split_di (operands + 1, 1, operands + 2, operands + 3);
1876 operands[1] = gen_lowpart (DImode, operands[2]);
1877 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1882 [(set (match_operand:DI 0 "push_operand" "")
1883 (match_operand:DI 1 "immediate_operand" ""))]
1884 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1885 ? flow2_completed : reload_completed)
1886 && !symbolic_operand (operands[1], DImode)
1887 && !x86_64_immediate_operand (operands[1], DImode)"
1888 [(set (match_dup 0) (match_dup 1))
1889 (set (match_dup 2) (match_dup 3))]
1890 "split_di (operands + 1, 1, operands + 2, operands + 3);
1891 operands[1] = gen_lowpart (DImode, operands[2]);
1892 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1896 (define_insn "*pushdi2_prologue_rex64"
1897 [(set (match_operand:DI 0 "push_operand" "=<")
1898 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1899 (clobber (mem:BLK (scratch)))]
1902 [(set_attr "type" "push")
1903 (set_attr "mode" "DI")])
1905 (define_insn "*popdi1_epilogue_rex64"
1906 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1907 (mem:DI (reg:DI SP_REG)))
1908 (set (reg:DI SP_REG)
1909 (plus:DI (reg:DI SP_REG) (const_int 8)))
1910 (clobber (mem:BLK (scratch)))]
1913 [(set_attr "type" "pop")
1914 (set_attr "mode" "DI")])
1916 (define_insn "popdi1"
1917 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918 (mem:DI (reg:DI SP_REG)))
1919 (set (reg:DI SP_REG)
1920 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1923 [(set_attr "type" "pop")
1924 (set_attr "mode" "DI")])
1926 (define_insn "*movdi_xor_rex64"
1927 [(set (match_operand:DI 0 "register_operand" "=r")
1928 (match_operand:DI 1 "const0_operand" "i"))
1929 (clobber (reg:CC FLAGS_REG))]
1930 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1931 && reload_completed"
1932 "xor{l}\t{%k0, %k0|%k0, %k0}"
1933 [(set_attr "type" "alu1")
1934 (set_attr "mode" "SI")
1935 (set_attr "length_immediate" "0")])
1937 (define_insn "*movdi_or_rex64"
1938 [(set (match_operand:DI 0 "register_operand" "=r")
1939 (match_operand:DI 1 "const_int_operand" "i"))
1940 (clobber (reg:CC FLAGS_REG))]
1941 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1943 && operands[1] == constm1_rtx"
1945 operands[1] = constm1_rtx;
1946 return "or{q}\t{%1, %0|%0, %1}";
1948 [(set_attr "type" "alu1")
1949 (set_attr "mode" "DI")
1950 (set_attr "length_immediate" "1")])
1952 (define_insn "*movdi_2"
1953 [(set (match_operand:DI 0 "nonimmediate_operand"
1954 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1955 (match_operand:DI 1 "general_operand"
1956 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1957 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1962 movq\t{%1, %0|%0, %1}
1963 movq\t{%1, %0|%0, %1}
1965 movq\t{%1, %0|%0, %1}
1966 movdqa\t{%1, %0|%0, %1}
1967 movq\t{%1, %0|%0, %1}
1969 movlps\t{%1, %0|%0, %1}
1970 movaps\t{%1, %0|%0, %1}
1971 movlps\t{%1, %0|%0, %1}"
1972 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1973 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1976 [(set (match_operand:DI 0 "push_operand" "")
1977 (match_operand:DI 1 "general_operand" ""))]
1978 "!TARGET_64BIT && reload_completed
1979 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1981 "ix86_split_long_move (operands); DONE;")
1983 ;; %%% This multiword shite has got to go.
1985 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1986 (match_operand:DI 1 "general_operand" ""))]
1987 "!TARGET_64BIT && reload_completed
1988 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1989 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1991 "ix86_split_long_move (operands); DONE;")
1993 (define_insn "*movdi_1_rex64"
1994 [(set (match_operand:DI 0 "nonimmediate_operand"
1995 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1996 (match_operand:DI 1 "general_operand"
1997 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1998 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2000 switch (get_attr_type (insn))
2003 if (which_alternative == 13)
2004 return "movq2dq\t{%1, %0|%0, %1}";
2006 return "movdq2q\t{%1, %0|%0, %1}";
2008 if (get_attr_mode (insn) == MODE_TI)
2009 return "movdqa\t{%1, %0|%0, %1}";
2012 /* Moves from and into integer register is done using movd opcode with
2014 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2015 return "movd\t{%1, %0|%0, %1}";
2016 return "movq\t{%1, %0|%0, %1}";
2019 return "pxor\t%0, %0";
2023 return "lea{q}\t{%a1, %0|%0, %a1}";
2025 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2026 if (get_attr_mode (insn) == MODE_SI)
2027 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028 else if (which_alternative == 2)
2029 return "movabs{q}\t{%1, %0|%0, %1}";
2031 return "mov{q}\t{%1, %0|%0, %1}";
2035 (cond [(eq_attr "alternative" "5")
2036 (const_string "mmxadd")
2037 (eq_attr "alternative" "6,7,8")
2038 (const_string "mmxmov")
2039 (eq_attr "alternative" "9")
2040 (const_string "sselog1")
2041 (eq_attr "alternative" "10,11,12")
2042 (const_string "ssemov")
2043 (eq_attr "alternative" "13,14")
2044 (const_string "ssecvt")
2045 (eq_attr "alternative" "4")
2046 (const_string "multi")
2047 (match_operand:DI 1 "pic_32bit_operand" "")
2048 (const_string "lea")
2050 (const_string "imov")))
2051 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2052 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2053 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2055 ;; Stores and loads of ax to arbitrary constant address.
2056 ;; We fake an second form of instruction to force reload to load address
2057 ;; into register when rax is not available
2058 (define_insn "*movabsdi_1_rex64"
2059 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2060 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2061 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2063 movabs{q}\t{%1, %P0|%P0, %1}
2064 mov{q}\t{%1, %a0|%a0, %1}"
2065 [(set_attr "type" "imov")
2066 (set_attr "modrm" "0,*")
2067 (set_attr "length_address" "8,0")
2068 (set_attr "length_immediate" "0,*")
2069 (set_attr "memory" "store")
2070 (set_attr "mode" "DI")])
2072 (define_insn "*movabsdi_2_rex64"
2073 [(set (match_operand:DI 0 "register_operand" "=a,r")
2074 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2075 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2077 movabs{q}\t{%P1, %0|%0, %P1}
2078 mov{q}\t{%a1, %0|%0, %a1}"
2079 [(set_attr "type" "imov")
2080 (set_attr "modrm" "0,*")
2081 (set_attr "length_address" "8,0")
2082 (set_attr "length_immediate" "0")
2083 (set_attr "memory" "load")
2084 (set_attr "mode" "DI")])
2086 ;; Convert impossible stores of immediate to existing instructions.
2087 ;; First try to get scratch register and go through it. In case this
2088 ;; fails, move by 32bit parts.
2090 [(match_scratch:DI 2 "r")
2091 (set (match_operand:DI 0 "memory_operand" "")
2092 (match_operand:DI 1 "immediate_operand" ""))]
2093 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2094 && !x86_64_immediate_operand (operands[1], DImode)"
2095 [(set (match_dup 2) (match_dup 1))
2096 (set (match_dup 0) (match_dup 2))]
2099 ;; We need to define this as both peepholer and splitter for case
2100 ;; peephole2 pass is not run.
2101 ;; "&& 1" is needed to keep it from matching the previous pattern.
2103 [(set (match_operand:DI 0 "memory_operand" "")
2104 (match_operand:DI 1 "immediate_operand" ""))]
2105 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2106 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2107 [(set (match_dup 2) (match_dup 3))
2108 (set (match_dup 4) (match_dup 5))]
2109 "split_di (operands, 2, operands + 2, operands + 4);")
2112 [(set (match_operand:DI 0 "memory_operand" "")
2113 (match_operand:DI 1 "immediate_operand" ""))]
2114 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2115 ? flow2_completed : reload_completed)
2116 && !symbolic_operand (operands[1], DImode)
2117 && !x86_64_immediate_operand (operands[1], DImode)"
2118 [(set (match_dup 2) (match_dup 3))
2119 (set (match_dup 4) (match_dup 5))]
2120 "split_di (operands, 2, operands + 2, operands + 4);")
2122 (define_insn "*swapdi_rex64"
2123 [(set (match_operand:DI 0 "register_operand" "+r")
2124 (match_operand:DI 1 "register_operand" "+r"))
2129 [(set_attr "type" "imov")
2130 (set_attr "mode" "DI")
2131 (set_attr "pent_pair" "np")
2132 (set_attr "athlon_decode" "vector")])
2134 (define_expand "movti"
2135 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2136 (match_operand:TI 1 "nonimmediate_operand" ""))]
2137 "TARGET_SSE || TARGET_64BIT"
2140 ix86_expand_move (TImode, operands);
2142 ix86_expand_vector_move (TImode, operands);
2146 (define_insn "*movti_internal"
2147 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2148 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2149 "TARGET_SSE && !TARGET_64BIT
2150 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2152 switch (which_alternative)
2155 if (get_attr_mode (insn) == MODE_V4SF)
2156 return "xorps\t%0, %0";
2158 return "pxor\t%0, %0";
2161 if (get_attr_mode (insn) == MODE_V4SF)
2162 return "movaps\t{%1, %0|%0, %1}";
2164 return "movdqa\t{%1, %0|%0, %1}";
2169 [(set_attr "type" "sselog1,ssemov,ssemov")
2171 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2172 (ne (symbol_ref "optimize_size") (const_int 0)))
2173 (const_string "V4SF")
2174 (and (eq_attr "alternative" "2")
2175 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2177 (const_string "V4SF")]
2178 (const_string "TI")))])
2180 (define_insn "*movti_rex64"
2181 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2182 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2184 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2186 switch (which_alternative)
2192 if (get_attr_mode (insn) == MODE_V4SF)
2193 return "xorps\t%0, %0";
2195 return "pxor\t%0, %0";
2198 if (get_attr_mode (insn) == MODE_V4SF)
2199 return "movaps\t{%1, %0|%0, %1}";
2201 return "movdqa\t{%1, %0|%0, %1}";
2206 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2208 (cond [(eq_attr "alternative" "2,3")
2210 (ne (symbol_ref "optimize_size")
2212 (const_string "V4SF")
2213 (const_string "TI"))
2214 (eq_attr "alternative" "4")
2216 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2218 (ne (symbol_ref "optimize_size")
2220 (const_string "V4SF")
2221 (const_string "TI"))]
2222 (const_string "DI")))])
2225 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2226 (match_operand:TI 1 "general_operand" ""))]
2227 "reload_completed && !SSE_REG_P (operands[0])
2228 && !SSE_REG_P (operands[1])"
2230 "ix86_split_long_move (operands); DONE;")
2232 (define_expand "movsf"
2233 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2234 (match_operand:SF 1 "general_operand" ""))]
2236 "ix86_expand_move (SFmode, operands); DONE;")
2238 (define_insn "*pushsf"
2239 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2240 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2243 /* Anything else should be already split before reg-stack. */
2244 gcc_assert (which_alternative == 1);
2245 return "push{l}\t%1";
2247 [(set_attr "type" "multi,push,multi")
2248 (set_attr "unit" "i387,*,*")
2249 (set_attr "mode" "SF,SI,SF")])
2251 (define_insn "*pushsf_rex64"
2252 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2253 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2256 /* Anything else should be already split before reg-stack. */
2257 gcc_assert (which_alternative == 1);
2258 return "push{q}\t%q1";
2260 [(set_attr "type" "multi,push,multi")
2261 (set_attr "unit" "i387,*,*")
2262 (set_attr "mode" "SF,DI,SF")])
2265 [(set (match_operand:SF 0 "push_operand" "")
2266 (match_operand:SF 1 "memory_operand" ""))]
2268 && GET_CODE (operands[1]) == MEM
2269 && constant_pool_reference_p (operands[1])"
2272 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2275 ;; %%% Kill this when call knows how to work this out.
2277 [(set (match_operand:SF 0 "push_operand" "")
2278 (match_operand:SF 1 "any_fp_register_operand" ""))]
2280 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2281 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2284 [(set (match_operand:SF 0 "push_operand" "")
2285 (match_operand:SF 1 "any_fp_register_operand" ""))]
2287 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2288 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2290 (define_insn "*movsf_1"
2291 [(set (match_operand:SF 0 "nonimmediate_operand"
2292 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2293 (match_operand:SF 1 "general_operand"
2294 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2295 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2296 && (reload_in_progress || reload_completed
2297 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2298 || GET_CODE (operands[1]) != CONST_DOUBLE
2299 || memory_operand (operands[0], SFmode))"
2301 switch (which_alternative)
2304 return output_387_reg_move (insn, operands);
2307 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2308 return "fstp%z0\t%y0";
2310 return "fst%z0\t%y0";
2313 return standard_80387_constant_opcode (operands[1]);
2317 return "mov{l}\t{%1, %0|%0, %1}";
2319 if (get_attr_mode (insn) == MODE_TI)
2320 return "pxor\t%0, %0";
2322 return "xorps\t%0, %0";
2324 if (get_attr_mode (insn) == MODE_V4SF)
2325 return "movaps\t{%1, %0|%0, %1}";
2327 return "movss\t{%1, %0|%0, %1}";
2330 return "movss\t{%1, %0|%0, %1}";
2334 return "movd\t{%1, %0|%0, %1}";
2337 return "movq\t{%1, %0|%0, %1}";
2343 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2345 (cond [(eq_attr "alternative" "3,4,9,10")
2347 (eq_attr "alternative" "5")
2349 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2351 (ne (symbol_ref "TARGET_SSE2")
2353 (eq (symbol_ref "optimize_size")
2356 (const_string "V4SF"))
2357 /* For architectures resolving dependencies on
2358 whole SSE registers use APS move to break dependency
2359 chains, otherwise use short move to avoid extra work.
2361 Do the same for architectures resolving dependencies on
2362 the parts. While in DF mode it is better to always handle
2363 just register parts, the SF mode is different due to lack
2364 of instructions to load just part of the register. It is
2365 better to maintain the whole registers in single format
2366 to avoid problems on using packed logical operations. */
2367 (eq_attr "alternative" "6")
2369 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2371 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2373 (const_string "V4SF")
2374 (const_string "SF"))
2375 (eq_attr "alternative" "11")
2376 (const_string "DI")]
2377 (const_string "SF")))])
2379 (define_insn "*swapsf"
2380 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2381 (match_operand:SF 1 "fp_register_operand" "+f"))
2384 "reload_completed || TARGET_80387"
2386 if (STACK_TOP_P (operands[0]))
2391 [(set_attr "type" "fxch")
2392 (set_attr "mode" "SF")])
2394 (define_expand "movdf"
2395 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2396 (match_operand:DF 1 "general_operand" ""))]
2398 "ix86_expand_move (DFmode, operands); DONE;")
2400 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2401 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2402 ;; On the average, pushdf using integers can be still shorter. Allow this
2403 ;; pattern for optimize_size too.
2405 (define_insn "*pushdf_nointeger"
2406 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2407 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2408 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2410 /* This insn should be already split before reg-stack. */
2413 [(set_attr "type" "multi")
2414 (set_attr "unit" "i387,*,*,*")
2415 (set_attr "mode" "DF,SI,SI,DF")])
2417 (define_insn "*pushdf_integer"
2418 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2419 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2420 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2422 /* This insn should be already split before reg-stack. */
2425 [(set_attr "type" "multi")
2426 (set_attr "unit" "i387,*,*")
2427 (set_attr "mode" "DF,SI,DF")])
2429 ;; %%% Kill this when call knows how to work this out.
2431 [(set (match_operand:DF 0 "push_operand" "")
2432 (match_operand:DF 1 "any_fp_register_operand" ""))]
2433 "!TARGET_64BIT && reload_completed"
2434 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2435 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2439 [(set (match_operand:DF 0 "push_operand" "")
2440 (match_operand:DF 1 "any_fp_register_operand" ""))]
2441 "TARGET_64BIT && reload_completed"
2442 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2443 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2447 [(set (match_operand:DF 0 "push_operand" "")
2448 (match_operand:DF 1 "general_operand" ""))]
2451 "ix86_split_long_move (operands); DONE;")
2453 ;; Moving is usually shorter when only FP registers are used. This separate
2454 ;; movdf pattern avoids the use of integer registers for FP operations
2455 ;; when optimizing for size.
2457 (define_insn "*movdf_nointeger"
2458 [(set (match_operand:DF 0 "nonimmediate_operand"
2459 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2460 (match_operand:DF 1 "general_operand"
2461 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2462 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2463 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2464 && (reload_in_progress || reload_completed
2465 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2466 || GET_CODE (operands[1]) != CONST_DOUBLE
2467 || memory_operand (operands[0], DFmode))"
2469 switch (which_alternative)
2472 return output_387_reg_move (insn, operands);
2475 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2476 return "fstp%z0\t%y0";
2478 return "fst%z0\t%y0";
2481 return standard_80387_constant_opcode (operands[1]);
2487 switch (get_attr_mode (insn))
2490 return "xorps\t%0, %0";
2492 return "xorpd\t%0, %0";
2494 return "pxor\t%0, %0";
2501 switch (get_attr_mode (insn))
2504 return "movaps\t{%1, %0|%0, %1}";
2506 return "movapd\t{%1, %0|%0, %1}";
2508 return "movdqa\t{%1, %0|%0, %1}";
2510 return "movq\t{%1, %0|%0, %1}";
2512 return "movsd\t{%1, %0|%0, %1}";
2514 return "movlpd\t{%1, %0|%0, %1}";
2516 return "movlps\t{%1, %0|%0, %1}";
2525 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2527 (cond [(eq_attr "alternative" "0,1,2")
2529 (eq_attr "alternative" "3,4")
2532 /* For SSE1, we have many fewer alternatives. */
2533 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2534 (cond [(eq_attr "alternative" "5,6")
2535 (const_string "V4SF")
2537 (const_string "V2SF"))
2539 /* xorps is one byte shorter. */
2540 (eq_attr "alternative" "5")
2541 (cond [(ne (symbol_ref "optimize_size")
2543 (const_string "V4SF")
2544 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2548 (const_string "V2DF"))
2550 /* For architectures resolving dependencies on
2551 whole SSE registers use APD move to break dependency
2552 chains, otherwise use short move to avoid extra work.
2554 movaps encodes one byte shorter. */
2555 (eq_attr "alternative" "6")
2557 [(ne (symbol_ref "optimize_size")
2559 (const_string "V4SF")
2560 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2562 (const_string "V2DF")
2564 (const_string "DF"))
2565 /* For architectures resolving dependencies on register
2566 parts we may avoid extra work to zero out upper part
2568 (eq_attr "alternative" "7")
2570 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2572 (const_string "V1DF")
2573 (const_string "DF"))
2575 (const_string "DF")))])
2577 (define_insn "*movdf_integer"
2578 [(set (match_operand:DF 0 "nonimmediate_operand"
2579 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2580 (match_operand:DF 1 "general_operand"
2581 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2582 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2583 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2584 && (reload_in_progress || reload_completed
2585 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2586 || GET_CODE (operands[1]) != CONST_DOUBLE
2587 || memory_operand (operands[0], DFmode))"
2589 switch (which_alternative)
2592 return output_387_reg_move (insn, operands);
2595 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2596 return "fstp%z0\t%y0";
2598 return "fst%z0\t%y0";
2601 return standard_80387_constant_opcode (operands[1]);
2608 switch (get_attr_mode (insn))
2611 return "xorps\t%0, %0";
2613 return "xorpd\t%0, %0";
2615 return "pxor\t%0, %0";
2622 switch (get_attr_mode (insn))
2625 return "movaps\t{%1, %0|%0, %1}";
2627 return "movapd\t{%1, %0|%0, %1}";
2629 return "movdqa\t{%1, %0|%0, %1}";
2631 return "movq\t{%1, %0|%0, %1}";
2633 return "movsd\t{%1, %0|%0, %1}";
2635 return "movlpd\t{%1, %0|%0, %1}";
2637 return "movlps\t{%1, %0|%0, %1}";
2646 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2648 (cond [(eq_attr "alternative" "0,1,2")
2650 (eq_attr "alternative" "3,4")
2653 /* For SSE1, we have many fewer alternatives. */
2654 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2655 (cond [(eq_attr "alternative" "5,6")
2656 (const_string "V4SF")
2658 (const_string "V2SF"))
2660 /* xorps is one byte shorter. */
2661 (eq_attr "alternative" "5")
2662 (cond [(ne (symbol_ref "optimize_size")
2664 (const_string "V4SF")
2665 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2669 (const_string "V2DF"))
2671 /* For architectures resolving dependencies on
2672 whole SSE registers use APD move to break dependency
2673 chains, otherwise use short move to avoid extra work.
2675 movaps encodes one byte shorter. */
2676 (eq_attr "alternative" "6")
2678 [(ne (symbol_ref "optimize_size")
2680 (const_string "V4SF")
2681 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2683 (const_string "V2DF")
2685 (const_string "DF"))
2686 /* For architectures resolving dependencies on register
2687 parts we may avoid extra work to zero out upper part
2689 (eq_attr "alternative" "7")
2691 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2693 (const_string "V1DF")
2694 (const_string "DF"))
2696 (const_string "DF")))])
2699 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2700 (match_operand:DF 1 "general_operand" ""))]
2702 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2703 && ! (ANY_FP_REG_P (operands[0]) ||
2704 (GET_CODE (operands[0]) == SUBREG
2705 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2706 && ! (ANY_FP_REG_P (operands[1]) ||
2707 (GET_CODE (operands[1]) == SUBREG
2708 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2710 "ix86_split_long_move (operands); DONE;")
2712 (define_insn "*swapdf"
2713 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2714 (match_operand:DF 1 "fp_register_operand" "+f"))
2717 "reload_completed || TARGET_80387"
2719 if (STACK_TOP_P (operands[0]))
2724 [(set_attr "type" "fxch")
2725 (set_attr "mode" "DF")])
2727 (define_expand "movxf"
2728 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2729 (match_operand:XF 1 "general_operand" ""))]
2731 "ix86_expand_move (XFmode, operands); DONE;")
2733 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2734 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2735 ;; Pushing using integer instructions is longer except for constants
2736 ;; and direct memory references.
2737 ;; (assuming that any given constant is pushed only once, but this ought to be
2738 ;; handled elsewhere).
2740 (define_insn "*pushxf_nointeger"
2741 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2742 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2745 /* This insn should be already split before reg-stack. */
2748 [(set_attr "type" "multi")
2749 (set_attr "unit" "i387,*,*")
2750 (set_attr "mode" "XF,SI,SI")])
2752 (define_insn "*pushxf_integer"
2753 [(set (match_operand:XF 0 "push_operand" "=<,<")
2754 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2757 /* This insn should be already split before reg-stack. */
2760 [(set_attr "type" "multi")
2761 (set_attr "unit" "i387,*")
2762 (set_attr "mode" "XF,SI")])
2765 [(set (match_operand 0 "push_operand" "")
2766 (match_operand 1 "general_operand" ""))]
2768 && (GET_MODE (operands[0]) == XFmode
2769 || GET_MODE (operands[0]) == DFmode)
2770 && !ANY_FP_REG_P (operands[1])"
2772 "ix86_split_long_move (operands); DONE;")
2775 [(set (match_operand:XF 0 "push_operand" "")
2776 (match_operand:XF 1 "any_fp_register_operand" ""))]
2778 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2779 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2780 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2783 [(set (match_operand:XF 0 "push_operand" "")
2784 (match_operand:XF 1 "any_fp_register_operand" ""))]
2786 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2787 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2788 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2790 ;; Do not use integer registers when optimizing for size
2791 (define_insn "*movxf_nointeger"
2792 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2793 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2795 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2796 && (reload_in_progress || reload_completed
2797 || standard_80387_constant_p (operands[1])
2798 || GET_CODE (operands[1]) != CONST_DOUBLE
2799 || memory_operand (operands[0], XFmode))"
2801 switch (which_alternative)
2804 return output_387_reg_move (insn, operands);
2807 /* There is no non-popping store to memory for XFmode. So if
2808 we need one, follow the store with a load. */
2809 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2810 return "fstp%z0\t%y0\;fld%z0\t%y0";
2812 return "fstp%z0\t%y0";
2815 return standard_80387_constant_opcode (operands[1]);
2823 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2824 (set_attr "mode" "XF,XF,XF,SI,SI")])
2826 (define_insn "*movxf_integer"
2827 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2828 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2831 && (reload_in_progress || reload_completed
2832 || standard_80387_constant_p (operands[1])
2833 || GET_CODE (operands[1]) != CONST_DOUBLE
2834 || memory_operand (operands[0], XFmode))"
2836 switch (which_alternative)
2839 return output_387_reg_move (insn, operands);
2842 /* There is no non-popping store to memory for XFmode. So if
2843 we need one, follow the store with a load. */
2844 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2845 return "fstp%z0\t%y0\;fld%z0\t%y0";
2847 return "fstp%z0\t%y0";
2850 return standard_80387_constant_opcode (operands[1]);
2859 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2860 (set_attr "mode" "XF,XF,XF,SI,SI")])
2863 [(set (match_operand 0 "nonimmediate_operand" "")
2864 (match_operand 1 "general_operand" ""))]
2866 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2867 && GET_MODE (operands[0]) == XFmode
2868 && ! (ANY_FP_REG_P (operands[0]) ||
2869 (GET_CODE (operands[0]) == SUBREG
2870 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2871 && ! (ANY_FP_REG_P (operands[1]) ||
2872 (GET_CODE (operands[1]) == SUBREG
2873 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2875 "ix86_split_long_move (operands); DONE;")
2878 [(set (match_operand 0 "register_operand" "")
2879 (match_operand 1 "memory_operand" ""))]
2881 && GET_CODE (operands[1]) == MEM
2882 && (GET_MODE (operands[0]) == XFmode
2883 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2884 && constant_pool_reference_p (operands[1])"
2885 [(set (match_dup 0) (match_dup 1))]
2887 rtx c = avoid_constant_pool_reference (operands[1]);
2888 rtx r = operands[0];
2890 if (GET_CODE (r) == SUBREG)
2895 if (!standard_sse_constant_p (c))
2898 else if (FP_REG_P (r))
2900 if (!standard_80387_constant_p (c))
2903 else if (MMX_REG_P (r))
2910 [(set (match_operand 0 "register_operand" "")
2911 (float_extend (match_operand 1 "memory_operand" "")))]
2913 && GET_CODE (operands[1]) == MEM
2914 && (GET_MODE (operands[0]) == XFmode
2915 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2916 && constant_pool_reference_p (operands[1])"
2917 [(set (match_dup 0) (match_dup 1))]
2919 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2920 rtx r = operands[0];
2922 if (GET_CODE (r) == SUBREG)
2927 if (!standard_sse_constant_p (c))
2930 else if (FP_REG_P (r))
2932 if (!standard_80387_constant_p (c))
2935 else if (MMX_REG_P (r))
2941 (define_insn "swapxf"
2942 [(set (match_operand:XF 0 "register_operand" "+f")
2943 (match_operand:XF 1 "register_operand" "+f"))
2948 if (STACK_TOP_P (operands[0]))
2953 [(set_attr "type" "fxch")
2954 (set_attr "mode" "XF")])
2956 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2958 [(set (match_operand:X87MODEF 0 "register_operand" "")
2959 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2960 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2961 && (standard_80387_constant_p (operands[1]) == 8
2962 || standard_80387_constant_p (operands[1]) == 9)"
2963 [(set (match_dup 0)(match_dup 1))
2965 (neg:X87MODEF (match_dup 0)))]
2969 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2970 if (real_isnegzero (&r))
2971 operands[1] = CONST0_RTX (<MODE>mode);
2973 operands[1] = CONST1_RTX (<MODE>mode);
2976 (define_expand "movtf"
2977 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2978 (match_operand:TF 1 "nonimmediate_operand" ""))]
2981 ix86_expand_move (TFmode, operands);
2985 (define_insn "*movtf_internal"
2986 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2987 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2989 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2991 switch (which_alternative)
2997 if (get_attr_mode (insn) == MODE_V4SF)
2998 return "xorps\t%0, %0";
3000 return "pxor\t%0, %0";
3003 if (get_attr_mode (insn) == MODE_V4SF)
3004 return "movaps\t{%1, %0|%0, %1}";
3006 return "movdqa\t{%1, %0|%0, %1}";
3011 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3013 (cond [(eq_attr "alternative" "2,3")
3015 (ne (symbol_ref "optimize_size")
3017 (const_string "V4SF")
3018 (const_string "TI"))
3019 (eq_attr "alternative" "4")
3021 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3023 (ne (symbol_ref "optimize_size")
3025 (const_string "V4SF")
3026 (const_string "TI"))]
3027 (const_string "DI")))])
3030 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3031 (match_operand:TF 1 "general_operand" ""))]
3032 "reload_completed && !SSE_REG_P (operands[0])
3033 && !SSE_REG_P (operands[1])"
3035 "ix86_split_long_move (operands); DONE;")
3037 ;; Zero extension instructions
3039 (define_expand "zero_extendhisi2"
3040 [(set (match_operand:SI 0 "register_operand" "")
3041 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3044 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3046 operands[1] = force_reg (HImode, operands[1]);
3047 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3052 (define_insn "zero_extendhisi2_and"
3053 [(set (match_operand:SI 0 "register_operand" "=r")
3054 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3055 (clobber (reg:CC FLAGS_REG))]
3056 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3058 [(set_attr "type" "alu1")
3059 (set_attr "mode" "SI")])
3062 [(set (match_operand:SI 0 "register_operand" "")
3063 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3064 (clobber (reg:CC FLAGS_REG))]
3065 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3066 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3067 (clobber (reg:CC FLAGS_REG))])]
3070 (define_insn "*zero_extendhisi2_movzwl"
3071 [(set (match_operand:SI 0 "register_operand" "=r")
3072 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3073 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3074 "movz{wl|x}\t{%1, %0|%0, %1}"
3075 [(set_attr "type" "imovx")
3076 (set_attr "mode" "SI")])
3078 (define_expand "zero_extendqihi2"
3080 [(set (match_operand:HI 0 "register_operand" "")
3081 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3082 (clobber (reg:CC FLAGS_REG))])]
3086 (define_insn "*zero_extendqihi2_and"
3087 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3088 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3089 (clobber (reg:CC FLAGS_REG))]
3090 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3092 [(set_attr "type" "alu1")
3093 (set_attr "mode" "HI")])
3095 (define_insn "*zero_extendqihi2_movzbw_and"
3096 [(set (match_operand:HI 0 "register_operand" "=r,r")
3097 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3098 (clobber (reg:CC FLAGS_REG))]
3099 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3101 [(set_attr "type" "imovx,alu1")
3102 (set_attr "mode" "HI")])
3104 ; zero extend to SImode here to avoid partial register stalls
3105 (define_insn "*zero_extendqihi2_movzbl"
3106 [(set (match_operand:HI 0 "register_operand" "=r")
3107 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3110 [(set_attr "type" "imovx")
3111 (set_attr "mode" "SI")])
3113 ;; For the movzbw case strip only the clobber
3115 [(set (match_operand:HI 0 "register_operand" "")
3116 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3117 (clobber (reg:CC FLAGS_REG))]
3119 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3120 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3121 [(set (match_operand:HI 0 "register_operand" "")
3122 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3127 [(set (match_operand:HI 0 "register_operand" "")
3128 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3129 (clobber (reg:CC FLAGS_REG))]
3131 && ANY_QI_REG_P (operands[0])
3132 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3133 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3134 [(set (match_dup 0) (const_int 0))
3135 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3136 "operands[2] = gen_lowpart (QImode, operands[0]);")
3138 ;; Rest is handled by single and.
3140 [(set (match_operand:HI 0 "register_operand" "")
3141 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3142 (clobber (reg:CC FLAGS_REG))]
3144 && true_regnum (operands[0]) == true_regnum (operands[1])"
3145 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3146 (clobber (reg:CC FLAGS_REG))])]
3149 (define_expand "zero_extendqisi2"
3151 [(set (match_operand:SI 0 "register_operand" "")
3152 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3153 (clobber (reg:CC FLAGS_REG))])]
3157 (define_insn "*zero_extendqisi2_and"
3158 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3159 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3160 (clobber (reg:CC FLAGS_REG))]
3161 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3163 [(set_attr "type" "alu1")
3164 (set_attr "mode" "SI")])
3166 (define_insn "*zero_extendqisi2_movzbw_and"
3167 [(set (match_operand:SI 0 "register_operand" "=r,r")
3168 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3169 (clobber (reg:CC FLAGS_REG))]
3170 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3172 [(set_attr "type" "imovx,alu1")
3173 (set_attr "mode" "SI")])
3175 (define_insn "*zero_extendqisi2_movzbw"
3176 [(set (match_operand:SI 0 "register_operand" "=r")
3177 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3178 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3179 "movz{bl|x}\t{%1, %0|%0, %1}"
3180 [(set_attr "type" "imovx")
3181 (set_attr "mode" "SI")])
3183 ;; For the movzbl case strip only the clobber
3185 [(set (match_operand:SI 0 "register_operand" "")
3186 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3187 (clobber (reg:CC FLAGS_REG))]
3189 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3190 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3192 (zero_extend:SI (match_dup 1)))])
3194 ;; When source and destination does not overlap, clear destination
3195 ;; first and then do the movb
3197 [(set (match_operand:SI 0 "register_operand" "")
3198 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3199 (clobber (reg:CC FLAGS_REG))]
3201 && ANY_QI_REG_P (operands[0])
3202 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3203 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3204 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3205 [(set (match_dup 0) (const_int 0))
3206 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3207 "operands[2] = gen_lowpart (QImode, operands[0]);")
3209 ;; Rest is handled by single and.
3211 [(set (match_operand:SI 0 "register_operand" "")
3212 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3213 (clobber (reg:CC FLAGS_REG))]
3215 && true_regnum (operands[0]) == true_regnum (operands[1])"
3216 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3217 (clobber (reg:CC FLAGS_REG))])]
3220 ;; %%% Kill me once multi-word ops are sane.
3221 (define_expand "zero_extendsidi2"
3222 [(set (match_operand:DI 0 "register_operand" "=r")
3223 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3227 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3232 (define_insn "zero_extendsidi2_32"
3233 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3234 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3235 (clobber (reg:CC FLAGS_REG))]
3241 movd\t{%1, %0|%0, %1}
3242 movd\t{%1, %0|%0, %1}"
3243 [(set_attr "mode" "SI,SI,SI,DI,TI")
3244 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3246 (define_insn "zero_extendsidi2_rex64"
3247 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3248 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3251 mov\t{%k1, %k0|%k0, %k1}
3253 movd\t{%1, %0|%0, %1}
3254 movd\t{%1, %0|%0, %1}"
3255 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3256 (set_attr "mode" "SI,DI,SI,SI")])
3259 [(set (match_operand:DI 0 "memory_operand" "")
3260 (zero_extend:DI (match_dup 0)))]
3262 [(set (match_dup 4) (const_int 0))]
3263 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3266 [(set (match_operand:DI 0 "register_operand" "")
3267 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3268 (clobber (reg:CC FLAGS_REG))]
3269 "!TARGET_64BIT && reload_completed
3270 && true_regnum (operands[0]) == true_regnum (operands[1])"
3271 [(set (match_dup 4) (const_int 0))]
3272 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3275 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3276 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3277 (clobber (reg:CC FLAGS_REG))]
3278 "!TARGET_64BIT && reload_completed
3279 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3280 [(set (match_dup 3) (match_dup 1))
3281 (set (match_dup 4) (const_int 0))]
3282 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3284 (define_insn "zero_extendhidi2"
3285 [(set (match_operand:DI 0 "register_operand" "=r")
3286 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3288 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3289 [(set_attr "type" "imovx")
3290 (set_attr "mode" "DI")])
3292 (define_insn "zero_extendqidi2"
3293 [(set (match_operand:DI 0 "register_operand" "=r")
3294 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3296 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3297 [(set_attr "type" "imovx")
3298 (set_attr "mode" "DI")])
3300 ;; Sign extension instructions
3302 (define_expand "extendsidi2"
3303 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3304 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3305 (clobber (reg:CC FLAGS_REG))
3306 (clobber (match_scratch:SI 2 ""))])]
3311 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3316 (define_insn "*extendsidi2_1"
3317 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3318 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3319 (clobber (reg:CC FLAGS_REG))
3320 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3324 (define_insn "extendsidi2_rex64"
3325 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3326 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3330 movs{lq|x}\t{%1,%0|%0, %1}"
3331 [(set_attr "type" "imovx")
3332 (set_attr "mode" "DI")
3333 (set_attr "prefix_0f" "0")
3334 (set_attr "modrm" "0,1")])
3336 (define_insn "extendhidi2"
3337 [(set (match_operand:DI 0 "register_operand" "=r")
3338 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3340 "movs{wq|x}\t{%1,%0|%0, %1}"
3341 [(set_attr "type" "imovx")
3342 (set_attr "mode" "DI")])
3344 (define_insn "extendqidi2"
3345 [(set (match_operand:DI 0 "register_operand" "=r")
3346 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348 "movs{bq|x}\t{%1,%0|%0, %1}"
3349 [(set_attr "type" "imovx")
3350 (set_attr "mode" "DI")])
3352 ;; Extend to memory case when source register does die.
3354 [(set (match_operand:DI 0 "memory_operand" "")
3355 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3356 (clobber (reg:CC FLAGS_REG))
3357 (clobber (match_operand:SI 2 "register_operand" ""))]
3359 && dead_or_set_p (insn, operands[1])
3360 && !reg_mentioned_p (operands[1], operands[0]))"
3361 [(set (match_dup 3) (match_dup 1))
3362 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3363 (clobber (reg:CC FLAGS_REG))])
3364 (set (match_dup 4) (match_dup 1))]
3365 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3367 ;; Extend to memory case when source register does not die.
3369 [(set (match_operand:DI 0 "memory_operand" "")
3370 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3371 (clobber (reg:CC FLAGS_REG))
3372 (clobber (match_operand:SI 2 "register_operand" ""))]
3376 split_di (&operands[0], 1, &operands[3], &operands[4]);
3378 emit_move_insn (operands[3], operands[1]);
3380 /* Generate a cltd if possible and doing so it profitable. */
3381 if (true_regnum (operands[1]) == 0
3382 && true_regnum (operands[2]) == 1
3383 && (optimize_size || TARGET_USE_CLTD))
3385 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3389 emit_move_insn (operands[2], operands[1]);
3390 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3392 emit_move_insn (operands[4], operands[2]);
3396 ;; Extend to register case. Optimize case where source and destination
3397 ;; registers match and cases where we can use cltd.
3399 [(set (match_operand:DI 0 "register_operand" "")
3400 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3401 (clobber (reg:CC FLAGS_REG))
3402 (clobber (match_scratch:SI 2 ""))]
3406 split_di (&operands[0], 1, &operands[3], &operands[4]);
3408 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3409 emit_move_insn (operands[3], operands[1]);
3411 /* Generate a cltd if possible and doing so it profitable. */
3412 if (true_regnum (operands[3]) == 0
3413 && (optimize_size || TARGET_USE_CLTD))
3415 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3419 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3420 emit_move_insn (operands[4], operands[1]);
3422 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3426 (define_insn "extendhisi2"
3427 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3428 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3431 switch (get_attr_prefix_0f (insn))
3434 return "{cwtl|cwde}";
3436 return "movs{wl|x}\t{%1,%0|%0, %1}";
3439 [(set_attr "type" "imovx")
3440 (set_attr "mode" "SI")
3441 (set (attr "prefix_0f")
3442 ;; movsx is short decodable while cwtl is vector decoded.
3443 (if_then_else (and (eq_attr "cpu" "!k6")
3444 (eq_attr "alternative" "0"))
3446 (const_string "1")))
3448 (if_then_else (eq_attr "prefix_0f" "0")
3450 (const_string "1")))])
3452 (define_insn "*extendhisi2_zext"
3453 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3455 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3458 switch (get_attr_prefix_0f (insn))
3461 return "{cwtl|cwde}";
3463 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3466 [(set_attr "type" "imovx")
3467 (set_attr "mode" "SI")
3468 (set (attr "prefix_0f")
3469 ;; movsx is short decodable while cwtl is vector decoded.
3470 (if_then_else (and (eq_attr "cpu" "!k6")
3471 (eq_attr "alternative" "0"))
3473 (const_string "1")))
3475 (if_then_else (eq_attr "prefix_0f" "0")
3477 (const_string "1")))])
3479 (define_insn "extendqihi2"
3480 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3481 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3484 switch (get_attr_prefix_0f (insn))
3487 return "{cbtw|cbw}";
3489 return "movs{bw|x}\t{%1,%0|%0, %1}";
3492 [(set_attr "type" "imovx")
3493 (set_attr "mode" "HI")
3494 (set (attr "prefix_0f")
3495 ;; movsx is short decodable while cwtl is vector decoded.
3496 (if_then_else (and (eq_attr "cpu" "!k6")
3497 (eq_attr "alternative" "0"))
3499 (const_string "1")))
3501 (if_then_else (eq_attr "prefix_0f" "0")
3503 (const_string "1")))])
3505 (define_insn "extendqisi2"
3506 [(set (match_operand:SI 0 "register_operand" "=r")
3507 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3509 "movs{bl|x}\t{%1,%0|%0, %1}"
3510 [(set_attr "type" "imovx")
3511 (set_attr "mode" "SI")])
3513 (define_insn "*extendqisi2_zext"
3514 [(set (match_operand:DI 0 "register_operand" "=r")
3516 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3518 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3519 [(set_attr "type" "imovx")
3520 (set_attr "mode" "SI")])
3522 ;; Conversions between float and double.
3524 ;; These are all no-ops in the model used for the 80387. So just
3527 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3528 (define_insn "*dummy_extendsfdf2"
3529 [(set (match_operand:DF 0 "push_operand" "=<")
3530 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3535 [(set (match_operand:DF 0 "push_operand" "")
3536 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3538 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3539 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3542 [(set (match_operand:DF 0 "push_operand" "")
3543 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3545 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3546 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3548 (define_insn "*dummy_extendsfxf2"
3549 [(set (match_operand:XF 0 "push_operand" "=<")
3550 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3555 [(set (match_operand:XF 0 "push_operand" "")
3556 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3558 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3559 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3560 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3563 [(set (match_operand:XF 0 "push_operand" "")
3564 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3566 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3567 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3568 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3571 [(set (match_operand:XF 0 "push_operand" "")
3572 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3574 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3575 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3576 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3579 [(set (match_operand:XF 0 "push_operand" "")
3580 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3582 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3583 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3584 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3586 (define_expand "extendsfdf2"
3587 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3588 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3589 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3591 /* ??? Needed for compress_float_constant since all fp constants
3592 are LEGITIMATE_CONSTANT_P. */
3593 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3595 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3596 && standard_80387_constant_p (operands[1]) > 0)
3598 operands[1] = simplify_const_unary_operation
3599 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3600 emit_move_insn_1 (operands[0], operands[1]);
3603 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3607 (define_insn "*extendsfdf2_mixed"
3608 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3609 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3610 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3612 switch (which_alternative)
3615 return output_387_reg_move (insn, operands);
3618 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3619 return "fstp%z0\t%y0";
3621 return "fst%z0\t%y0";
3624 return "cvtss2sd\t{%1, %0|%0, %1}";
3630 [(set_attr "type" "fmov,fmov,ssecvt")
3631 (set_attr "mode" "SF,XF,DF")])
3633 (define_insn "*extendsfdf2_sse"
3634 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3635 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3636 "TARGET_SSE2 && TARGET_SSE_MATH"
3637 "cvtss2sd\t{%1, %0|%0, %1}"
3638 [(set_attr "type" "ssecvt")
3639 (set_attr "mode" "DF")])
3641 (define_insn "*extendsfdf2_i387"
3642 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3643 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3646 switch (which_alternative)
3649 return output_387_reg_move (insn, operands);
3652 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3653 return "fstp%z0\t%y0";
3655 return "fst%z0\t%y0";
3661 [(set_attr "type" "fmov")
3662 (set_attr "mode" "SF,XF")])
3664 (define_expand "extendsfxf2"
3665 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3666 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3669 /* ??? Needed for compress_float_constant since all fp constants
3670 are LEGITIMATE_CONSTANT_P. */
3671 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3673 if (standard_80387_constant_p (operands[1]) > 0)
3675 operands[1] = simplify_const_unary_operation
3676 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3677 emit_move_insn_1 (operands[0], operands[1]);
3680 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3684 (define_insn "*extendsfxf2_i387"
3685 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3686 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3689 switch (which_alternative)
3692 return output_387_reg_move (insn, operands);
3695 /* There is no non-popping store to memory for XFmode. So if
3696 we need one, follow the store with a load. */
3697 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3698 return "fstp%z0\t%y0";
3700 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3706 [(set_attr "type" "fmov")
3707 (set_attr "mode" "SF,XF")])
3709 (define_expand "extenddfxf2"
3710 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3711 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3714 /* ??? Needed for compress_float_constant since all fp constants
3715 are LEGITIMATE_CONSTANT_P. */
3716 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3718 if (standard_80387_constant_p (operands[1]) > 0)
3720 operands[1] = simplify_const_unary_operation
3721 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3722 emit_move_insn_1 (operands[0], operands[1]);
3725 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3729 (define_insn "*extenddfxf2_i387"
3730 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3731 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3734 switch (which_alternative)
3737 return output_387_reg_move (insn, operands);
3740 /* There is no non-popping store to memory for XFmode. So if
3741 we need one, follow the store with a load. */
3742 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3743 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3745 return "fstp%z0\t%y0";
3751 [(set_attr "type" "fmov")
3752 (set_attr "mode" "DF,XF")])
3754 ;; %%% This seems bad bad news.
3755 ;; This cannot output into an f-reg because there is no way to be sure
3756 ;; of truncating in that case. Otherwise this is just like a simple move
3757 ;; insn. So we pretend we can output to a reg in order to get better
3758 ;; register preferencing, but we really use a stack slot.
3760 ;; Conversion from DFmode to SFmode.
3762 (define_expand "truncdfsf2"
3763 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3765 (match_operand:DF 1 "nonimmediate_operand" "")))]
3766 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3768 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3770 else if (flag_unsafe_math_optimizations)
3774 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3775 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3780 (define_expand "truncdfsf2_with_temp"
3781 [(parallel [(set (match_operand:SF 0 "" "")
3782 (float_truncate:SF (match_operand:DF 1 "" "")))
3783 (clobber (match_operand:SF 2 "" ""))])]
3786 (define_insn "*truncdfsf_fast_mixed"
3787 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3789 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3790 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3792 switch (which_alternative)
3795 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3796 return "fstp%z0\t%y0";
3798 return "fst%z0\t%y0";
3800 return output_387_reg_move (insn, operands);
3802 return "cvtsd2ss\t{%1, %0|%0, %1}";
3807 [(set_attr "type" "fmov,fmov,ssecvt")
3808 (set_attr "mode" "SF")])
3810 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3811 ;; because nothing we do here is unsafe.
3812 (define_insn "*truncdfsf_fast_sse"
3813 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3815 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3816 "TARGET_SSE2 && TARGET_SSE_MATH"
3817 "cvtsd2ss\t{%1, %0|%0, %1}"
3818 [(set_attr "type" "ssecvt")
3819 (set_attr "mode" "SF")])
3821 (define_insn "*truncdfsf_fast_i387"
3822 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3824 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3825 "TARGET_80387 && flag_unsafe_math_optimizations"
3826 "* return output_387_reg_move (insn, operands);"
3827 [(set_attr "type" "fmov")
3828 (set_attr "mode" "SF")])
3830 (define_insn "*truncdfsf_mixed"
3831 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3833 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3834 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3835 "TARGET_MIX_SSE_I387"
3837 switch (which_alternative)
3840 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3841 return "fstp%z0\t%y0";
3843 return "fst%z0\t%y0";
3847 return "cvtsd2ss\t{%1, %0|%0, %1}";
3852 [(set_attr "type" "fmov,multi,ssecvt")
3853 (set_attr "unit" "*,i387,*")
3854 (set_attr "mode" "SF")])
3856 (define_insn "*truncdfsf_i387"
3857 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3859 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3860 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3863 switch (which_alternative)
3866 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867 return "fstp%z0\t%y0";
3869 return "fst%z0\t%y0";
3876 [(set_attr "type" "fmov,multi")
3877 (set_attr "unit" "*,i387")
3878 (set_attr "mode" "SF")])
3880 (define_insn "*truncdfsf2_i387_1"
3881 [(set (match_operand:SF 0 "memory_operand" "=m")
3883 (match_operand:DF 1 "register_operand" "f")))]
3885 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3886 && !TARGET_MIX_SSE_I387"
3888 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3889 return "fstp%z0\t%y0";
3891 return "fst%z0\t%y0";
3893 [(set_attr "type" "fmov")
3894 (set_attr "mode" "SF")])
3897 [(set (match_operand:SF 0 "register_operand" "")
3899 (match_operand:DF 1 "fp_register_operand" "")))
3900 (clobber (match_operand 2 "" ""))]
3902 [(set (match_dup 2) (match_dup 1))
3903 (set (match_dup 0) (match_dup 2))]
3905 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3908 ;; Conversion from XFmode to SFmode.
3910 (define_expand "truncxfsf2"
3911 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3913 (match_operand:XF 1 "register_operand" "")))
3914 (clobber (match_dup 2))])]
3917 if (flag_unsafe_math_optimizations)
3919 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3920 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3921 if (reg != operands[0])
3922 emit_move_insn (operands[0], reg);
3926 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3929 (define_insn "*truncxfsf2_mixed"
3930 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3932 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3933 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3934 "TARGET_MIX_SSE_I387"
3936 gcc_assert (!which_alternative);
3937 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3938 return "fstp%z0\t%y0";
3940 return "fst%z0\t%y0";
3942 [(set_attr "type" "fmov,multi,multi,multi")
3943 (set_attr "unit" "*,i387,i387,i387")
3944 (set_attr "mode" "SF")])
3946 (define_insn "truncxfsf2_i387_noop"
3947 [(set (match_operand:SF 0 "register_operand" "=f")
3948 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3949 "TARGET_80387 && flag_unsafe_math_optimizations"
3950 "* return output_387_reg_move (insn, operands);"
3951 [(set_attr "type" "fmov")
3952 (set_attr "mode" "SF")])
3954 (define_insn "*truncxfsf2_i387"
3955 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3957 (match_operand:XF 1 "register_operand" "f,f,f")))
3958 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3961 gcc_assert (!which_alternative);
3962 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3963 return "fstp%z0\t%y0";
3965 return "fst%z0\t%y0";
3967 [(set_attr "type" "fmov,multi,multi")
3968 (set_attr "unit" "*,i387,i387")
3969 (set_attr "mode" "SF")])
3971 (define_insn "*truncxfsf2_i387_1"
3972 [(set (match_operand:SF 0 "memory_operand" "=m")
3974 (match_operand:XF 1 "register_operand" "f")))]
3977 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3978 return "fstp%z0\t%y0";
3980 return "fst%z0\t%y0";
3982 [(set_attr "type" "fmov")
3983 (set_attr "mode" "SF")])
3986 [(set (match_operand:SF 0 "register_operand" "")
3988 (match_operand:XF 1 "register_operand" "")))
3989 (clobber (match_operand:SF 2 "memory_operand" ""))]
3990 "TARGET_80387 && reload_completed"
3991 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3992 (set (match_dup 0) (match_dup 2))]
3996 [(set (match_operand:SF 0 "memory_operand" "")
3998 (match_operand:XF 1 "register_operand" "")))
3999 (clobber (match_operand:SF 2 "memory_operand" ""))]
4001 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4004 ;; Conversion from XFmode to DFmode.
4006 (define_expand "truncxfdf2"
4007 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4009 (match_operand:XF 1 "register_operand" "")))
4010 (clobber (match_dup 2))])]
4013 if (flag_unsafe_math_optimizations)
4015 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4016 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4017 if (reg != operands[0])
4018 emit_move_insn (operands[0], reg);
4022 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4025 (define_insn "*truncxfdf2_mixed"
4026 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4028 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4029 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4030 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4032 gcc_assert (!which_alternative);
4033 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4034 return "fstp%z0\t%y0";
4036 return "fst%z0\t%y0";
4038 [(set_attr "type" "fmov,multi,multi,multi")
4039 (set_attr "unit" "*,i387,i387,i387")
4040 (set_attr "mode" "DF")])
4042 (define_insn "truncxfdf2_i387_noop"
4043 [(set (match_operand:DF 0 "register_operand" "=f")
4044 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4045 "TARGET_80387 && flag_unsafe_math_optimizations"
4046 "* return output_387_reg_move (insn, operands);"
4047 [(set_attr "type" "fmov")
4048 (set_attr "mode" "DF")])
4050 (define_insn "*truncxfdf2_i387"
4051 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4053 (match_operand:XF 1 "register_operand" "f,f,f")))
4054 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4057 gcc_assert (!which_alternative);
4058 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4059 return "fstp%z0\t%y0";
4061 return "fst%z0\t%y0";
4063 [(set_attr "type" "fmov,multi,multi")
4064 (set_attr "unit" "*,i387,i387")
4065 (set_attr "mode" "DF")])
4067 (define_insn "*truncxfdf2_i387_1"
4068 [(set (match_operand:DF 0 "memory_operand" "=m")
4070 (match_operand:XF 1 "register_operand" "f")))]
4073 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4074 return "fstp%z0\t%y0";
4076 return "fst%z0\t%y0";
4078 [(set_attr "type" "fmov")
4079 (set_attr "mode" "DF")])
4082 [(set (match_operand:DF 0 "register_operand" "")
4084 (match_operand:XF 1 "register_operand" "")))
4085 (clobber (match_operand:DF 2 "memory_operand" ""))]
4086 "TARGET_80387 && reload_completed"
4087 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4088 (set (match_dup 0) (match_dup 2))]
4092 [(set (match_operand:DF 0 "memory_operand" "")
4094 (match_operand:XF 1 "register_operand" "")))
4095 (clobber (match_operand:DF 2 "memory_operand" ""))]
4097 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4100 ;; Signed conversion to DImode.
4102 (define_expand "fix_truncxfdi2"
4103 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4104 (fix:DI (match_operand:XF 1 "register_operand" "")))
4105 (clobber (reg:CC FLAGS_REG))])]
4110 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4115 (define_expand "fix_trunc<mode>di2"
4116 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4117 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4118 (clobber (reg:CC FLAGS_REG))])]
4119 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4122 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4124 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4127 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4129 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4130 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4131 if (out != operands[0])
4132 emit_move_insn (operands[0], out);
4137 ;; Signed conversion to SImode.
4139 (define_expand "fix_truncxfsi2"
4140 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4141 (fix:SI (match_operand:XF 1 "register_operand" "")))
4142 (clobber (reg:CC FLAGS_REG))])]
4147 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4152 (define_expand "fix_trunc<mode>si2"
4153 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4154 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4155 (clobber (reg:CC FLAGS_REG))])]
4156 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4159 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4161 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4164 if (SSE_FLOAT_MODE_P (<MODE>mode))
4166 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4167 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4168 if (out != operands[0])
4169 emit_move_insn (operands[0], out);
4174 ;; Signed conversion to HImode.
4176 (define_expand "fix_trunc<mode>hi2"
4177 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4178 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4179 (clobber (reg:CC FLAGS_REG))])]
4181 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4185 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4190 ;; When SSE is available, it is always faster to use it!
4191 (define_insn "fix_truncsfdi_sse"
4192 [(set (match_operand:DI 0 "register_operand" "=r,r")
4193 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4194 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4195 "cvttss2si{q}\t{%1, %0|%0, %1}"
4196 [(set_attr "type" "sseicvt")
4197 (set_attr "mode" "SF")
4198 (set_attr "athlon_decode" "double,vector")])
4200 (define_insn "fix_truncdfdi_sse"
4201 [(set (match_operand:DI 0 "register_operand" "=r,r")
4202 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4203 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4204 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4205 [(set_attr "type" "sseicvt")
4206 (set_attr "mode" "DF")
4207 (set_attr "athlon_decode" "double,vector")])
4209 (define_insn "fix_truncsfsi_sse"
4210 [(set (match_operand:SI 0 "register_operand" "=r,r")
4211 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4212 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4213 "cvttss2si\t{%1, %0|%0, %1}"
4214 [(set_attr "type" "sseicvt")
4215 (set_attr "mode" "DF")
4216 (set_attr "athlon_decode" "double,vector")])
4218 (define_insn "fix_truncdfsi_sse"
4219 [(set (match_operand:SI 0 "register_operand" "=r,r")
4220 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4221 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4222 "cvttsd2si\t{%1, %0|%0, %1}"
4223 [(set_attr "type" "sseicvt")
4224 (set_attr "mode" "DF")
4225 (set_attr "athlon_decode" "double,vector")])
4227 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4229 [(set (match_operand:DF 0 "register_operand" "")
4230 (match_operand:DF 1 "memory_operand" ""))
4231 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4232 (fix:SSEMODEI24 (match_dup 0)))]
4234 && peep2_reg_dead_p (2, operands[0])"
4235 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4239 [(set (match_operand:SF 0 "register_operand" "")
4240 (match_operand:SF 1 "memory_operand" ""))
4241 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4242 (fix:SSEMODEI24 (match_dup 0)))]
4244 && peep2_reg_dead_p (2, operands[0])"
4245 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4248 ;; Avoid vector decoded forms of the instruction.
4250 [(match_scratch:DF 2 "Y")
4251 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4252 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4253 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4254 [(set (match_dup 2) (match_dup 1))
4255 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4259 [(match_scratch:SF 2 "x")
4260 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4261 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4262 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4263 [(set (match_dup 2) (match_dup 1))
4264 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4267 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4268 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4269 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4271 && FLOAT_MODE_P (GET_MODE (operands[1]))
4272 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4273 && (TARGET_64BIT || <MODE>mode != DImode))
4275 && !(reload_completed || reload_in_progress)"
4280 if (memory_operand (operands[0], VOIDmode))
4281 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4284 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4285 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4291 [(set_attr "type" "fisttp")
4292 (set_attr "mode" "<MODE>")])
4294 (define_insn "fix_trunc<mode>_i387_fisttp"
4295 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4296 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4297 (clobber (match_scratch:XF 2 "=&1f"))]
4299 && FLOAT_MODE_P (GET_MODE (operands[1]))
4300 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4301 && (TARGET_64BIT || <MODE>mode != DImode))
4302 && TARGET_SSE_MATH)"
4303 "* return output_fix_trunc (insn, operands, 1);"
4304 [(set_attr "type" "fisttp")
4305 (set_attr "mode" "<MODE>")])
4307 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4308 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4309 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4310 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4311 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4313 && FLOAT_MODE_P (GET_MODE (operands[1]))
4314 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4315 && (TARGET_64BIT || <MODE>mode != DImode))
4316 && TARGET_SSE_MATH)"
4318 [(set_attr "type" "fisttp")
4319 (set_attr "mode" "<MODE>")])
4322 [(set (match_operand:X87MODEI 0 "register_operand" "")
4323 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4324 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4325 (clobber (match_scratch 3 ""))]
4327 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4328 (clobber (match_dup 3))])
4329 (set (match_dup 0) (match_dup 2))]
4333 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4334 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4335 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4336 (clobber (match_scratch 3 ""))]
4338 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4339 (clobber (match_dup 3))])]
4342 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4343 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4344 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4345 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4346 ;; function in i386.c.
4347 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4348 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4349 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4350 (clobber (reg:CC FLAGS_REG))]
4351 "TARGET_80387 && !TARGET_FISTTP
4352 && FLOAT_MODE_P (GET_MODE (operands[1]))
4353 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4354 && (TARGET_64BIT || <MODE>mode != DImode))
4355 && !(reload_completed || reload_in_progress)"
4360 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4362 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4363 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4364 if (memory_operand (operands[0], VOIDmode))
4365 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4366 operands[2], operands[3]));
4369 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4370 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4371 operands[2], operands[3],
4376 [(set_attr "type" "fistp")
4377 (set_attr "i387_cw" "trunc")
4378 (set_attr "mode" "<MODE>")])
4380 (define_insn "fix_truncdi_i387"
4381 [(set (match_operand:DI 0 "memory_operand" "=m")
4382 (fix:DI (match_operand 1 "register_operand" "f")))
4383 (use (match_operand:HI 2 "memory_operand" "m"))
4384 (use (match_operand:HI 3 "memory_operand" "m"))
4385 (clobber (match_scratch:XF 4 "=&1f"))]
4386 "TARGET_80387 && !TARGET_FISTTP
4387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4388 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4389 "* return output_fix_trunc (insn, operands, 0);"
4390 [(set_attr "type" "fistp")
4391 (set_attr "i387_cw" "trunc")
4392 (set_attr "mode" "DI")])
4394 (define_insn "fix_truncdi_i387_with_temp"
4395 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4396 (fix:DI (match_operand 1 "register_operand" "f,f")))
4397 (use (match_operand:HI 2 "memory_operand" "m,m"))
4398 (use (match_operand:HI 3 "memory_operand" "m,m"))
4399 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4400 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4401 "TARGET_80387 && !TARGET_FISTTP
4402 && FLOAT_MODE_P (GET_MODE (operands[1]))
4403 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4405 [(set_attr "type" "fistp")
4406 (set_attr "i387_cw" "trunc")
4407 (set_attr "mode" "DI")])
4410 [(set (match_operand:DI 0 "register_operand" "")
4411 (fix:DI (match_operand 1 "register_operand" "")))
4412 (use (match_operand:HI 2 "memory_operand" ""))
4413 (use (match_operand:HI 3 "memory_operand" ""))
4414 (clobber (match_operand:DI 4 "memory_operand" ""))
4415 (clobber (match_scratch 5 ""))]
4417 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4420 (clobber (match_dup 5))])
4421 (set (match_dup 0) (match_dup 4))]
4425 [(set (match_operand:DI 0 "memory_operand" "")
4426 (fix:DI (match_operand 1 "register_operand" "")))
4427 (use (match_operand:HI 2 "memory_operand" ""))
4428 (use (match_operand:HI 3 "memory_operand" ""))
4429 (clobber (match_operand:DI 4 "memory_operand" ""))
4430 (clobber (match_scratch 5 ""))]
4432 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4435 (clobber (match_dup 5))])]
4438 (define_insn "fix_trunc<mode>_i387"
4439 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4440 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4441 (use (match_operand:HI 2 "memory_operand" "m"))
4442 (use (match_operand:HI 3 "memory_operand" "m"))]
4443 "TARGET_80387 && !TARGET_FISTTP
4444 && FLOAT_MODE_P (GET_MODE (operands[1]))
4445 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4446 "* return output_fix_trunc (insn, operands, 0);"
4447 [(set_attr "type" "fistp")
4448 (set_attr "i387_cw" "trunc")
4449 (set_attr "mode" "<MODE>")])
4451 (define_insn "fix_trunc<mode>_i387_with_temp"
4452 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4453 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4454 (use (match_operand:HI 2 "memory_operand" "m,m"))
4455 (use (match_operand:HI 3 "memory_operand" "m,m"))
4456 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4457 "TARGET_80387 && !TARGET_FISTTP
4458 && FLOAT_MODE_P (GET_MODE (operands[1]))
4459 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4461 [(set_attr "type" "fistp")
4462 (set_attr "i387_cw" "trunc")
4463 (set_attr "mode" "<MODE>")])
4466 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4467 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4468 (use (match_operand:HI 2 "memory_operand" ""))
4469 (use (match_operand:HI 3 "memory_operand" ""))
4470 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4472 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4474 (use (match_dup 3))])
4475 (set (match_dup 0) (match_dup 4))]
4479 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4480 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4481 (use (match_operand:HI 2 "memory_operand" ""))
4482 (use (match_operand:HI 3 "memory_operand" ""))
4483 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4485 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4487 (use (match_dup 3))])]
4490 (define_insn "x86_fnstcw_1"
4491 [(set (match_operand:HI 0 "memory_operand" "=m")
4492 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4495 [(set_attr "length" "2")
4496 (set_attr "mode" "HI")
4497 (set_attr "unit" "i387")])
4499 (define_insn "x86_fldcw_1"
4500 [(set (reg:HI FPCR_REG)
4501 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4504 [(set_attr "length" "2")
4505 (set_attr "mode" "HI")
4506 (set_attr "unit" "i387")
4507 (set_attr "athlon_decode" "vector")])
4509 ;; Conversion between fixed point and floating point.
4511 ;; Even though we only accept memory inputs, the backend _really_
4512 ;; wants to be able to do this between registers.
4514 (define_expand "floathisf2"
4515 [(set (match_operand:SF 0 "register_operand" "")
4516 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4517 "TARGET_80387 || TARGET_SSE_MATH"
4519 if (TARGET_SSE_MATH)
4521 emit_insn (gen_floatsisf2 (operands[0],
4522 convert_to_mode (SImode, operands[1], 0)));
4527 (define_insn "*floathisf2_i387"
4528 [(set (match_operand:SF 0 "register_operand" "=f,f")
4529 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4530 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4534 [(set_attr "type" "fmov,multi")
4535 (set_attr "mode" "SF")
4536 (set_attr "unit" "*,i387")
4537 (set_attr "fp_int_src" "true")])
4539 (define_expand "floatsisf2"
4540 [(set (match_operand:SF 0 "register_operand" "")
4541 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4542 "TARGET_80387 || TARGET_SSE_MATH"
4545 (define_insn "*floatsisf2_mixed"
4546 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4547 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4548 "TARGET_MIX_SSE_I387"
4552 cvtsi2ss\t{%1, %0|%0, %1}
4553 cvtsi2ss\t{%1, %0|%0, %1}"
4554 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4555 (set_attr "mode" "SF")
4556 (set_attr "unit" "*,i387,*,*")
4557 (set_attr "athlon_decode" "*,*,vector,double")
4558 (set_attr "fp_int_src" "true")])
4560 (define_insn "*floatsisf2_sse"
4561 [(set (match_operand:SF 0 "register_operand" "=x,x")
4562 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4564 "cvtsi2ss\t{%1, %0|%0, %1}"
4565 [(set_attr "type" "sseicvt")
4566 (set_attr "mode" "SF")
4567 (set_attr "athlon_decode" "vector,double")
4568 (set_attr "fp_int_src" "true")])
4570 (define_insn "*floatsisf2_i387"
4571 [(set (match_operand:SF 0 "register_operand" "=f,f")
4572 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4577 [(set_attr "type" "fmov,multi")
4578 (set_attr "mode" "SF")
4579 (set_attr "unit" "*,i387")
4580 (set_attr "fp_int_src" "true")])
4582 (define_expand "floatdisf2"
4583 [(set (match_operand:SF 0 "register_operand" "")
4584 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4585 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4588 (define_insn "*floatdisf2_mixed"
4589 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4590 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4591 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4595 cvtsi2ss{q}\t{%1, %0|%0, %1}
4596 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4597 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4598 (set_attr "mode" "SF")
4599 (set_attr "unit" "*,i387,*,*")
4600 (set_attr "athlon_decode" "*,*,vector,double")
4601 (set_attr "fp_int_src" "true")])
4603 (define_insn "*floatdisf2_sse"
4604 [(set (match_operand:SF 0 "register_operand" "=x,x")
4605 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4606 "TARGET_64BIT && TARGET_SSE_MATH"
4607 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4608 [(set_attr "type" "sseicvt")
4609 (set_attr "mode" "SF")
4610 (set_attr "athlon_decode" "vector,double")
4611 (set_attr "fp_int_src" "true")])
4613 (define_insn "*floatdisf2_i387"
4614 [(set (match_operand:SF 0 "register_operand" "=f,f")
4615 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4620 [(set_attr "type" "fmov,multi")
4621 (set_attr "mode" "SF")
4622 (set_attr "unit" "*,i387")
4623 (set_attr "fp_int_src" "true")])
4625 (define_expand "floathidf2"
4626 [(set (match_operand:DF 0 "register_operand" "")
4627 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4628 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4630 if (TARGET_SSE2 && TARGET_SSE_MATH)
4632 emit_insn (gen_floatsidf2 (operands[0],
4633 convert_to_mode (SImode, operands[1], 0)));
4638 (define_insn "*floathidf2_i387"
4639 [(set (match_operand:DF 0 "register_operand" "=f,f")
4640 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4641 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4645 [(set_attr "type" "fmov,multi")
4646 (set_attr "mode" "DF")
4647 (set_attr "unit" "*,i387")
4648 (set_attr "fp_int_src" "true")])
4650 (define_expand "floatsidf2"
4651 [(set (match_operand:DF 0 "register_operand" "")
4652 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4653 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4656 (define_insn "*floatsidf2_mixed"
4657 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4658 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4659 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4663 cvtsi2sd\t{%1, %0|%0, %1}
4664 cvtsi2sd\t{%1, %0|%0, %1}"
4665 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4666 (set_attr "mode" "DF")
4667 (set_attr "unit" "*,i387,*,*")
4668 (set_attr "athlon_decode" "*,*,double,direct")
4669 (set_attr "fp_int_src" "true")])
4671 (define_insn "*floatsidf2_sse"
4672 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4673 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4674 "TARGET_SSE2 && TARGET_SSE_MATH"
4675 "cvtsi2sd\t{%1, %0|%0, %1}"
4676 [(set_attr "type" "sseicvt")
4677 (set_attr "mode" "DF")
4678 (set_attr "athlon_decode" "double,direct")
4679 (set_attr "fp_int_src" "true")])
4681 (define_insn "*floatsidf2_i387"
4682 [(set (match_operand:DF 0 "register_operand" "=f,f")
4683 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4688 [(set_attr "type" "fmov,multi")
4689 (set_attr "mode" "DF")
4690 (set_attr "unit" "*,i387")
4691 (set_attr "fp_int_src" "true")])
4693 (define_expand "floatdidf2"
4694 [(set (match_operand:DF 0 "register_operand" "")
4695 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4696 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4699 (define_insn "*floatdidf2_mixed"
4700 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4701 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4702 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4706 cvtsi2sd{q}\t{%1, %0|%0, %1}
4707 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4708 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4709 (set_attr "mode" "DF")
4710 (set_attr "unit" "*,i387,*,*")
4711 (set_attr "athlon_decode" "*,*,double,direct")
4712 (set_attr "fp_int_src" "true")])
4714 (define_insn "*floatdidf2_sse"
4715 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4716 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4717 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4718 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4719 [(set_attr "type" "sseicvt")
4720 (set_attr "mode" "DF")
4721 (set_attr "athlon_decode" "double,direct")
4722 (set_attr "fp_int_src" "true")])
4724 (define_insn "*floatdidf2_i387"
4725 [(set (match_operand:DF 0 "register_operand" "=f,f")
4726 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4731 [(set_attr "type" "fmov,multi")
4732 (set_attr "mode" "DF")
4733 (set_attr "unit" "*,i387")
4734 (set_attr "fp_int_src" "true")])
4736 (define_insn "floathixf2"
4737 [(set (match_operand:XF 0 "register_operand" "=f,f")
4738 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4743 [(set_attr "type" "fmov,multi")
4744 (set_attr "mode" "XF")
4745 (set_attr "unit" "*,i387")
4746 (set_attr "fp_int_src" "true")])
4748 (define_insn "floatsixf2"
4749 [(set (match_operand:XF 0 "register_operand" "=f,f")
4750 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4755 [(set_attr "type" "fmov,multi")
4756 (set_attr "mode" "XF")
4757 (set_attr "unit" "*,i387")
4758 (set_attr "fp_int_src" "true")])
4760 (define_insn "floatdixf2"
4761 [(set (match_operand:XF 0 "register_operand" "=f,f")
4762 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4767 [(set_attr "type" "fmov,multi")
4768 (set_attr "mode" "XF")
4769 (set_attr "unit" "*,i387")
4770 (set_attr "fp_int_src" "true")])
4772 ;; %%% Kill these when reload knows how to do it.
4774 [(set (match_operand 0 "fp_register_operand" "")
4775 (float (match_operand 1 "register_operand" "")))]
4778 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4781 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4782 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4783 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4784 ix86_free_from_memory (GET_MODE (operands[1]));
4788 (define_expand "floatunssisf2"
4789 [(use (match_operand:SF 0 "register_operand" ""))
4790 (use (match_operand:SI 1 "register_operand" ""))]
4791 "!TARGET_64BIT && TARGET_SSE_MATH"
4792 "x86_emit_floatuns (operands); DONE;")
4794 (define_expand "floatunsdisf2"
4795 [(use (match_operand:SF 0 "register_operand" ""))
4796 (use (match_operand:DI 1 "register_operand" ""))]
4797 "TARGET_64BIT && TARGET_SSE_MATH"
4798 "x86_emit_floatuns (operands); DONE;")
4800 (define_expand "floatunsdidf2"
4801 [(use (match_operand:DF 0 "register_operand" ""))
4802 (use (match_operand:DI 1 "register_operand" ""))]
4803 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4804 "x86_emit_floatuns (operands); DONE;")
4806 ;; SSE extract/set expanders
4811 ;; %%% splits for addditi3
4813 (define_expand "addti3"
4814 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4815 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4816 (match_operand:TI 2 "x86_64_general_operand" "")))
4817 (clobber (reg:CC FLAGS_REG))]
4819 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4821 (define_insn "*addti3_1"
4822 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4823 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4824 (match_operand:TI 2 "general_operand" "roiF,riF")))
4825 (clobber (reg:CC FLAGS_REG))]
4826 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4830 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4831 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4832 (match_operand:TI 2 "general_operand" "")))
4833 (clobber (reg:CC FLAGS_REG))]
4834 "TARGET_64BIT && reload_completed"
4835 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4837 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4838 (parallel [(set (match_dup 3)
4839 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4842 (clobber (reg:CC FLAGS_REG))])]
4843 "split_ti (operands+0, 1, operands+0, operands+3);
4844 split_ti (operands+1, 1, operands+1, operands+4);
4845 split_ti (operands+2, 1, operands+2, operands+5);")
4847 ;; %%% splits for addsidi3
4848 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4849 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4850 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4852 (define_expand "adddi3"
4853 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4854 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4855 (match_operand:DI 2 "x86_64_general_operand" "")))
4856 (clobber (reg:CC FLAGS_REG))]
4858 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4860 (define_insn "*adddi3_1"
4861 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4862 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4863 (match_operand:DI 2 "general_operand" "roiF,riF")))
4864 (clobber (reg:CC FLAGS_REG))]
4865 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4869 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4870 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4871 (match_operand:DI 2 "general_operand" "")))
4872 (clobber (reg:CC FLAGS_REG))]
4873 "!TARGET_64BIT && reload_completed"
4874 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4876 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4877 (parallel [(set (match_dup 3)
4878 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4881 (clobber (reg:CC FLAGS_REG))])]
4882 "split_di (operands+0, 1, operands+0, operands+3);
4883 split_di (operands+1, 1, operands+1, operands+4);
4884 split_di (operands+2, 1, operands+2, operands+5);")
4886 (define_insn "adddi3_carry_rex64"
4887 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4888 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4889 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4890 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4891 (clobber (reg:CC FLAGS_REG))]
4892 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4893 "adc{q}\t{%2, %0|%0, %2}"
4894 [(set_attr "type" "alu")
4895 (set_attr "pent_pair" "pu")
4896 (set_attr "mode" "DI")])
4898 (define_insn "*adddi3_cc_rex64"
4899 [(set (reg:CC FLAGS_REG)
4900 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4901 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4903 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4904 (plus:DI (match_dup 1) (match_dup 2)))]
4905 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4906 "add{q}\t{%2, %0|%0, %2}"
4907 [(set_attr "type" "alu")
4908 (set_attr "mode" "DI")])
4910 (define_insn "addqi3_carry"
4911 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4912 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4913 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4914 (match_operand:QI 2 "general_operand" "qi,qm")))
4915 (clobber (reg:CC FLAGS_REG))]
4916 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4917 "adc{b}\t{%2, %0|%0, %2}"
4918 [(set_attr "type" "alu")
4919 (set_attr "pent_pair" "pu")
4920 (set_attr "mode" "QI")])
4922 (define_insn "addhi3_carry"
4923 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4924 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4925 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4926 (match_operand:HI 2 "general_operand" "ri,rm")))
4927 (clobber (reg:CC FLAGS_REG))]
4928 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4929 "adc{w}\t{%2, %0|%0, %2}"
4930 [(set_attr "type" "alu")
4931 (set_attr "pent_pair" "pu")
4932 (set_attr "mode" "HI")])
4934 (define_insn "addsi3_carry"
4935 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4936 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4937 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4938 (match_operand:SI 2 "general_operand" "ri,rm")))
4939 (clobber (reg:CC FLAGS_REG))]
4940 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4941 "adc{l}\t{%2, %0|%0, %2}"
4942 [(set_attr "type" "alu")
4943 (set_attr "pent_pair" "pu")
4944 (set_attr "mode" "SI")])
4946 (define_insn "*addsi3_carry_zext"
4947 [(set (match_operand:DI 0 "register_operand" "=r")
4949 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4950 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4951 (match_operand:SI 2 "general_operand" "rim"))))
4952 (clobber (reg:CC FLAGS_REG))]
4953 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4954 "adc{l}\t{%2, %k0|%k0, %2}"
4955 [(set_attr "type" "alu")
4956 (set_attr "pent_pair" "pu")
4957 (set_attr "mode" "SI")])
4959 (define_insn "*addsi3_cc"
4960 [(set (reg:CC FLAGS_REG)
4961 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4962 (match_operand:SI 2 "general_operand" "ri,rm")]
4964 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4965 (plus:SI (match_dup 1) (match_dup 2)))]
4966 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4967 "add{l}\t{%2, %0|%0, %2}"
4968 [(set_attr "type" "alu")
4969 (set_attr "mode" "SI")])
4971 (define_insn "addqi3_cc"
4972 [(set (reg:CC FLAGS_REG)
4973 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4974 (match_operand:QI 2 "general_operand" "qi,qm")]
4976 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4977 (plus:QI (match_dup 1) (match_dup 2)))]
4978 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4979 "add{b}\t{%2, %0|%0, %2}"
4980 [(set_attr "type" "alu")
4981 (set_attr "mode" "QI")])
4983 (define_expand "addsi3"
4984 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4985 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4986 (match_operand:SI 2 "general_operand" "")))
4987 (clobber (reg:CC FLAGS_REG))])]
4989 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4991 (define_insn "*lea_1"
4992 [(set (match_operand:SI 0 "register_operand" "=r")
4993 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4995 "lea{l}\t{%a1, %0|%0, %a1}"
4996 [(set_attr "type" "lea")
4997 (set_attr "mode" "SI")])
4999 (define_insn "*lea_1_rex64"
5000 [(set (match_operand:SI 0 "register_operand" "=r")
5001 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5003 "lea{l}\t{%a1, %0|%0, %a1}"
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "SI")])
5007 (define_insn "*lea_1_zext"
5008 [(set (match_operand:DI 0 "register_operand" "=r")
5010 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5012 "lea{l}\t{%a1, %k0|%k0, %a1}"
5013 [(set_attr "type" "lea")
5014 (set_attr "mode" "SI")])
5016 (define_insn "*lea_2_rex64"
5017 [(set (match_operand:DI 0 "register_operand" "=r")
5018 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5020 "lea{q}\t{%a1, %0|%0, %a1}"
5021 [(set_attr "type" "lea")
5022 (set_attr "mode" "DI")])
5024 ;; The lea patterns for non-Pmodes needs to be matched by several
5025 ;; insns converted to real lea by splitters.
5027 (define_insn_and_split "*lea_general_1"
5028 [(set (match_operand 0 "register_operand" "=r")
5029 (plus (plus (match_operand 1 "index_register_operand" "l")
5030 (match_operand 2 "register_operand" "r"))
5031 (match_operand 3 "immediate_operand" "i")))]
5032 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5033 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5034 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5035 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5036 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5037 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5038 || GET_MODE (operands[3]) == VOIDmode)"
5040 "&& reload_completed"
5044 operands[0] = gen_lowpart (SImode, operands[0]);
5045 operands[1] = gen_lowpart (Pmode, operands[1]);
5046 operands[2] = gen_lowpart (Pmode, operands[2]);
5047 operands[3] = gen_lowpart (Pmode, operands[3]);
5048 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5050 if (Pmode != SImode)
5051 pat = gen_rtx_SUBREG (SImode, pat, 0);
5052 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5055 [(set_attr "type" "lea")
5056 (set_attr "mode" "SI")])
5058 (define_insn_and_split "*lea_general_1_zext"
5059 [(set (match_operand:DI 0 "register_operand" "=r")
5061 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5062 (match_operand:SI 2 "register_operand" "r"))
5063 (match_operand:SI 3 "immediate_operand" "i"))))]
5066 "&& reload_completed"
5068 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5070 (match_dup 3)) 0)))]
5072 operands[1] = gen_lowpart (Pmode, operands[1]);
5073 operands[2] = gen_lowpart (Pmode, operands[2]);
5074 operands[3] = gen_lowpart (Pmode, operands[3]);
5076 [(set_attr "type" "lea")
5077 (set_attr "mode" "SI")])
5079 (define_insn_and_split "*lea_general_2"
5080 [(set (match_operand 0 "register_operand" "=r")
5081 (plus (mult (match_operand 1 "index_register_operand" "l")
5082 (match_operand 2 "const248_operand" "i"))
5083 (match_operand 3 "nonmemory_operand" "ri")))]
5084 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5085 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5086 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5087 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5088 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5089 || GET_MODE (operands[3]) == VOIDmode)"
5091 "&& reload_completed"
5095 operands[0] = gen_lowpart (SImode, operands[0]);
5096 operands[1] = gen_lowpart (Pmode, operands[1]);
5097 operands[3] = gen_lowpart (Pmode, operands[3]);
5098 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5100 if (Pmode != SImode)
5101 pat = gen_rtx_SUBREG (SImode, pat, 0);
5102 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5105 [(set_attr "type" "lea")
5106 (set_attr "mode" "SI")])
5108 (define_insn_and_split "*lea_general_2_zext"
5109 [(set (match_operand:DI 0 "register_operand" "=r")
5111 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5112 (match_operand:SI 2 "const248_operand" "n"))
5113 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5116 "&& reload_completed"
5118 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5120 (match_dup 3)) 0)))]
5122 operands[1] = gen_lowpart (Pmode, operands[1]);
5123 operands[3] = gen_lowpart (Pmode, operands[3]);
5125 [(set_attr "type" "lea")
5126 (set_attr "mode" "SI")])
5128 (define_insn_and_split "*lea_general_3"
5129 [(set (match_operand 0 "register_operand" "=r")
5130 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5131 (match_operand 2 "const248_operand" "i"))
5132 (match_operand 3 "register_operand" "r"))
5133 (match_operand 4 "immediate_operand" "i")))]
5134 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5135 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5136 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5137 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5138 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5140 "&& reload_completed"
5144 operands[0] = gen_lowpart (SImode, operands[0]);
5145 operands[1] = gen_lowpart (Pmode, operands[1]);
5146 operands[3] = gen_lowpart (Pmode, operands[3]);
5147 operands[4] = gen_lowpart (Pmode, operands[4]);
5148 pat = gen_rtx_PLUS (Pmode,
5149 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5153 if (Pmode != SImode)
5154 pat = gen_rtx_SUBREG (SImode, pat, 0);
5155 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5158 [(set_attr "type" "lea")
5159 (set_attr "mode" "SI")])
5161 (define_insn_and_split "*lea_general_3_zext"
5162 [(set (match_operand:DI 0 "register_operand" "=r")
5164 (plus:SI (plus:SI (mult:SI
5165 (match_operand:SI 1 "index_register_operand" "l")
5166 (match_operand:SI 2 "const248_operand" "n"))
5167 (match_operand:SI 3 "register_operand" "r"))
5168 (match_operand:SI 4 "immediate_operand" "i"))))]
5171 "&& reload_completed"
5173 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5176 (match_dup 4)) 0)))]
5178 operands[1] = gen_lowpart (Pmode, operands[1]);
5179 operands[3] = gen_lowpart (Pmode, operands[3]);
5180 operands[4] = gen_lowpart (Pmode, operands[4]);
5182 [(set_attr "type" "lea")
5183 (set_attr "mode" "SI")])
5185 (define_insn "*adddi_1_rex64"
5186 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5187 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5188 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5189 (clobber (reg:CC FLAGS_REG))]
5190 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5192 switch (get_attr_type (insn))
5195 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5196 return "lea{q}\t{%a2, %0|%0, %a2}";
5199 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5200 if (operands[2] == const1_rtx)
5201 return "inc{q}\t%0";
5204 gcc_assert (operands[2] == constm1_rtx);
5205 return "dec{q}\t%0";
5209 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5211 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5212 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5213 if (GET_CODE (operands[2]) == CONST_INT
5214 /* Avoid overflows. */
5215 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5216 && (INTVAL (operands[2]) == 128
5217 || (INTVAL (operands[2]) < 0
5218 && INTVAL (operands[2]) != -128)))
5220 operands[2] = GEN_INT (-INTVAL (operands[2]));
5221 return "sub{q}\t{%2, %0|%0, %2}";
5223 return "add{q}\t{%2, %0|%0, %2}";
5227 (cond [(eq_attr "alternative" "2")
5228 (const_string "lea")
5229 ; Current assemblers are broken and do not allow @GOTOFF in
5230 ; ought but a memory context.
5231 (match_operand:DI 2 "pic_symbolic_operand" "")
5232 (const_string "lea")
5233 (match_operand:DI 2 "incdec_operand" "")
5234 (const_string "incdec")
5236 (const_string "alu")))
5237 (set_attr "mode" "DI")])
5239 ;; Convert lea to the lea pattern to avoid flags dependency.
5241 [(set (match_operand:DI 0 "register_operand" "")
5242 (plus:DI (match_operand:DI 1 "register_operand" "")
5243 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5244 (clobber (reg:CC FLAGS_REG))]
5245 "TARGET_64BIT && reload_completed
5246 && true_regnum (operands[0]) != true_regnum (operands[1])"
5248 (plus:DI (match_dup 1)
5252 (define_insn "*adddi_2_rex64"
5253 [(set (reg FLAGS_REG)
5255 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5256 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5258 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5259 (plus:DI (match_dup 1) (match_dup 2)))]
5260 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5261 && ix86_binary_operator_ok (PLUS, DImode, operands)
5262 /* Current assemblers are broken and do not allow @GOTOFF in
5263 ought but a memory context. */
5264 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5266 switch (get_attr_type (insn))
5269 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5270 if (operands[2] == const1_rtx)
5271 return "inc{q}\t%0";
5274 gcc_assert (operands[2] == constm1_rtx);
5275 return "dec{q}\t%0";
5279 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280 /* ???? We ought to handle there the 32bit case too
5281 - do we need new constraint? */
5282 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5283 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5284 if (GET_CODE (operands[2]) == CONST_INT
5285 /* Avoid overflows. */
5286 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5287 && (INTVAL (operands[2]) == 128
5288 || (INTVAL (operands[2]) < 0
5289 && INTVAL (operands[2]) != -128)))
5291 operands[2] = GEN_INT (-INTVAL (operands[2]));
5292 return "sub{q}\t{%2, %0|%0, %2}";
5294 return "add{q}\t{%2, %0|%0, %2}";
5298 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5299 (const_string "incdec")
5300 (const_string "alu")))
5301 (set_attr "mode" "DI")])
5303 (define_insn "*adddi_3_rex64"
5304 [(set (reg FLAGS_REG)
5305 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5306 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5307 (clobber (match_scratch:DI 0 "=r"))]
5309 && ix86_match_ccmode (insn, CCZmode)
5310 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5311 /* Current assemblers are broken and do not allow @GOTOFF in
5312 ought but a memory context. */
5313 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5315 switch (get_attr_type (insn))
5318 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5319 if (operands[2] == const1_rtx)
5320 return "inc{q}\t%0";
5323 gcc_assert (operands[2] == constm1_rtx);
5324 return "dec{q}\t%0";
5328 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5329 /* ???? We ought to handle there the 32bit case too
5330 - do we need new constraint? */
5331 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5332 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5333 if (GET_CODE (operands[2]) == CONST_INT
5334 /* Avoid overflows. */
5335 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5336 && (INTVAL (operands[2]) == 128
5337 || (INTVAL (operands[2]) < 0
5338 && INTVAL (operands[2]) != -128)))
5340 operands[2] = GEN_INT (-INTVAL (operands[2]));
5341 return "sub{q}\t{%2, %0|%0, %2}";
5343 return "add{q}\t{%2, %0|%0, %2}";
5347 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5348 (const_string "incdec")
5349 (const_string "alu")))
5350 (set_attr "mode" "DI")])
5352 ; For comparisons against 1, -1 and 128, we may generate better code
5353 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5354 ; is matched then. We can't accept general immediate, because for
5355 ; case of overflows, the result is messed up.
5356 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5358 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5359 ; only for comparisons not depending on it.
5360 (define_insn "*adddi_4_rex64"
5361 [(set (reg FLAGS_REG)
5362 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5363 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5364 (clobber (match_scratch:DI 0 "=rm"))]
5366 && ix86_match_ccmode (insn, CCGCmode)"
5368 switch (get_attr_type (insn))
5371 if (operands[2] == constm1_rtx)
5372 return "inc{q}\t%0";
5375 gcc_assert (operands[2] == const1_rtx);
5376 return "dec{q}\t%0";
5380 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5381 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5382 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5383 if ((INTVAL (operands[2]) == -128
5384 || (INTVAL (operands[2]) > 0
5385 && INTVAL (operands[2]) != 128))
5386 /* Avoid overflows. */
5387 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5388 return "sub{q}\t{%2, %0|%0, %2}";
5389 operands[2] = GEN_INT (-INTVAL (operands[2]));
5390 return "add{q}\t{%2, %0|%0, %2}";
5394 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5395 (const_string "incdec")
5396 (const_string "alu")))
5397 (set_attr "mode" "DI")])
5399 (define_insn "*adddi_5_rex64"
5400 [(set (reg FLAGS_REG)
5402 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5403 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5405 (clobber (match_scratch:DI 0 "=r"))]
5407 && ix86_match_ccmode (insn, CCGOCmode)
5408 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5409 /* Current assemblers are broken and do not allow @GOTOFF in
5410 ought but a memory context. */
5411 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5413 switch (get_attr_type (insn))
5416 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5417 if (operands[2] == const1_rtx)
5418 return "inc{q}\t%0";
5421 gcc_assert (operands[2] == constm1_rtx);
5422 return "dec{q}\t%0";
5426 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5427 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5428 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5429 if (GET_CODE (operands[2]) == CONST_INT
5430 /* Avoid overflows. */
5431 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5432 && (INTVAL (operands[2]) == 128
5433 || (INTVAL (operands[2]) < 0
5434 && INTVAL (operands[2]) != -128)))
5436 operands[2] = GEN_INT (-INTVAL (operands[2]));
5437 return "sub{q}\t{%2, %0|%0, %2}";
5439 return "add{q}\t{%2, %0|%0, %2}";
5443 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5444 (const_string "incdec")
5445 (const_string "alu")))
5446 (set_attr "mode" "DI")])
5449 (define_insn "*addsi_1"
5450 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5451 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5452 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5453 (clobber (reg:CC FLAGS_REG))]
5454 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5456 switch (get_attr_type (insn))
5459 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5460 return "lea{l}\t{%a2, %0|%0, %a2}";
5463 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5464 if (operands[2] == const1_rtx)
5465 return "inc{l}\t%0";
5468 gcc_assert (operands[2] == constm1_rtx);
5469 return "dec{l}\t%0";
5473 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5475 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5476 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5477 if (GET_CODE (operands[2]) == CONST_INT
5478 && (INTVAL (operands[2]) == 128
5479 || (INTVAL (operands[2]) < 0
5480 && INTVAL (operands[2]) != -128)))
5482 operands[2] = GEN_INT (-INTVAL (operands[2]));
5483 return "sub{l}\t{%2, %0|%0, %2}";
5485 return "add{l}\t{%2, %0|%0, %2}";
5489 (cond [(eq_attr "alternative" "2")
5490 (const_string "lea")
5491 ; Current assemblers are broken and do not allow @GOTOFF in
5492 ; ought but a memory context.
5493 (match_operand:SI 2 "pic_symbolic_operand" "")
5494 (const_string "lea")
5495 (match_operand:SI 2 "incdec_operand" "")
5496 (const_string "incdec")
5498 (const_string "alu")))
5499 (set_attr "mode" "SI")])
5501 ;; Convert lea to the lea pattern to avoid flags dependency.
5503 [(set (match_operand 0 "register_operand" "")
5504 (plus (match_operand 1 "register_operand" "")
5505 (match_operand 2 "nonmemory_operand" "")))
5506 (clobber (reg:CC FLAGS_REG))]
5508 && true_regnum (operands[0]) != true_regnum (operands[1])"
5512 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5513 may confuse gen_lowpart. */
5514 if (GET_MODE (operands[0]) != Pmode)
5516 operands[1] = gen_lowpart (Pmode, operands[1]);
5517 operands[2] = gen_lowpart (Pmode, operands[2]);
5519 operands[0] = gen_lowpart (SImode, operands[0]);
5520 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5521 if (Pmode != SImode)
5522 pat = gen_rtx_SUBREG (SImode, pat, 0);
5523 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5527 ;; It may seem that nonimmediate operand is proper one for operand 1.
5528 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5529 ;; we take care in ix86_binary_operator_ok to not allow two memory
5530 ;; operands so proper swapping will be done in reload. This allow
5531 ;; patterns constructed from addsi_1 to match.
5532 (define_insn "addsi_1_zext"
5533 [(set (match_operand:DI 0 "register_operand" "=r,r")
5535 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5536 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5537 (clobber (reg:CC FLAGS_REG))]
5538 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5540 switch (get_attr_type (insn))
5543 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5544 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5547 if (operands[2] == const1_rtx)
5548 return "inc{l}\t%k0";
5551 gcc_assert (operands[2] == constm1_rtx);
5552 return "dec{l}\t%k0";
5556 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5557 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5558 if (GET_CODE (operands[2]) == CONST_INT
5559 && (INTVAL (operands[2]) == 128
5560 || (INTVAL (operands[2]) < 0
5561 && INTVAL (operands[2]) != -128)))
5563 operands[2] = GEN_INT (-INTVAL (operands[2]));
5564 return "sub{l}\t{%2, %k0|%k0, %2}";
5566 return "add{l}\t{%2, %k0|%k0, %2}";
5570 (cond [(eq_attr "alternative" "1")
5571 (const_string "lea")
5572 ; Current assemblers are broken and do not allow @GOTOFF in
5573 ; ought but a memory context.
5574 (match_operand:SI 2 "pic_symbolic_operand" "")
5575 (const_string "lea")
5576 (match_operand:SI 2 "incdec_operand" "")
5577 (const_string "incdec")
5579 (const_string "alu")))
5580 (set_attr "mode" "SI")])
5582 ;; Convert lea to the lea pattern to avoid flags dependency.
5584 [(set (match_operand:DI 0 "register_operand" "")
5586 (plus:SI (match_operand:SI 1 "register_operand" "")
5587 (match_operand:SI 2 "nonmemory_operand" ""))))
5588 (clobber (reg:CC FLAGS_REG))]
5589 "TARGET_64BIT && reload_completed
5590 && true_regnum (operands[0]) != true_regnum (operands[1])"
5592 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5594 operands[1] = gen_lowpart (Pmode, operands[1]);
5595 operands[2] = gen_lowpart (Pmode, operands[2]);
5598 (define_insn "*addsi_2"
5599 [(set (reg FLAGS_REG)
5601 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5602 (match_operand:SI 2 "general_operand" "rmni,rni"))
5604 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5605 (plus:SI (match_dup 1) (match_dup 2)))]
5606 "ix86_match_ccmode (insn, CCGOCmode)
5607 && ix86_binary_operator_ok (PLUS, SImode, operands)
5608 /* Current assemblers are broken and do not allow @GOTOFF in
5609 ought but a memory context. */
5610 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5612 switch (get_attr_type (insn))
5615 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5616 if (operands[2] == const1_rtx)
5617 return "inc{l}\t%0";
5620 gcc_assert (operands[2] == constm1_rtx);
5621 return "dec{l}\t%0";
5625 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5626 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5627 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5628 if (GET_CODE (operands[2]) == CONST_INT
5629 && (INTVAL (operands[2]) == 128
5630 || (INTVAL (operands[2]) < 0
5631 && INTVAL (operands[2]) != -128)))
5633 operands[2] = GEN_INT (-INTVAL (operands[2]));
5634 return "sub{l}\t{%2, %0|%0, %2}";
5636 return "add{l}\t{%2, %0|%0, %2}";
5640 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5641 (const_string "incdec")
5642 (const_string "alu")))
5643 (set_attr "mode" "SI")])
5645 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5646 (define_insn "*addsi_2_zext"
5647 [(set (reg FLAGS_REG)
5649 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5650 (match_operand:SI 2 "general_operand" "rmni"))
5652 (set (match_operand:DI 0 "register_operand" "=r")
5653 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5654 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5655 && ix86_binary_operator_ok (PLUS, SImode, operands)
5656 /* Current assemblers are broken and do not allow @GOTOFF in
5657 ought but a memory context. */
5658 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5660 switch (get_attr_type (insn))
5663 if (operands[2] == const1_rtx)
5664 return "inc{l}\t%k0";
5667 gcc_assert (operands[2] == constm1_rtx);
5668 return "dec{l}\t%k0";
5672 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5673 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5674 if (GET_CODE (operands[2]) == CONST_INT
5675 && (INTVAL (operands[2]) == 128
5676 || (INTVAL (operands[2]) < 0
5677 && INTVAL (operands[2]) != -128)))
5679 operands[2] = GEN_INT (-INTVAL (operands[2]));
5680 return "sub{l}\t{%2, %k0|%k0, %2}";
5682 return "add{l}\t{%2, %k0|%k0, %2}";
5686 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5687 (const_string "incdec")
5688 (const_string "alu")))
5689 (set_attr "mode" "SI")])
5691 (define_insn "*addsi_3"
5692 [(set (reg FLAGS_REG)
5693 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5694 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5695 (clobber (match_scratch:SI 0 "=r"))]
5696 "ix86_match_ccmode (insn, CCZmode)
5697 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5698 /* Current assemblers are broken and do not allow @GOTOFF in
5699 ought but a memory context. */
5700 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5702 switch (get_attr_type (insn))
5705 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5706 if (operands[2] == const1_rtx)
5707 return "inc{l}\t%0";
5710 gcc_assert (operands[2] == constm1_rtx);
5711 return "dec{l}\t%0";
5715 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5716 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5717 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5718 if (GET_CODE (operands[2]) == CONST_INT
5719 && (INTVAL (operands[2]) == 128
5720 || (INTVAL (operands[2]) < 0
5721 && INTVAL (operands[2]) != -128)))
5723 operands[2] = GEN_INT (-INTVAL (operands[2]));
5724 return "sub{l}\t{%2, %0|%0, %2}";
5726 return "add{l}\t{%2, %0|%0, %2}";
5730 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5731 (const_string "incdec")
5732 (const_string "alu")))
5733 (set_attr "mode" "SI")])
5735 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5736 (define_insn "*addsi_3_zext"
5737 [(set (reg FLAGS_REG)
5738 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5739 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5740 (set (match_operand:DI 0 "register_operand" "=r")
5741 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5742 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5743 && ix86_binary_operator_ok (PLUS, SImode, operands)
5744 /* Current assemblers are broken and do not allow @GOTOFF in
5745 ought but a memory context. */
5746 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5748 switch (get_attr_type (insn))
5751 if (operands[2] == const1_rtx)
5752 return "inc{l}\t%k0";
5755 gcc_assert (operands[2] == constm1_rtx);
5756 return "dec{l}\t%k0";
5760 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5761 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5762 if (GET_CODE (operands[2]) == CONST_INT
5763 && (INTVAL (operands[2]) == 128
5764 || (INTVAL (operands[2]) < 0
5765 && INTVAL (operands[2]) != -128)))
5767 operands[2] = GEN_INT (-INTVAL (operands[2]));
5768 return "sub{l}\t{%2, %k0|%k0, %2}";
5770 return "add{l}\t{%2, %k0|%k0, %2}";
5774 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5775 (const_string "incdec")
5776 (const_string "alu")))
5777 (set_attr "mode" "SI")])
5779 ; For comparisons against 1, -1 and 128, we may generate better code
5780 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5781 ; is matched then. We can't accept general immediate, because for
5782 ; case of overflows, the result is messed up.
5783 ; This pattern also don't hold of 0x80000000, since the value overflows
5785 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5786 ; only for comparisons not depending on it.
5787 (define_insn "*addsi_4"
5788 [(set (reg FLAGS_REG)
5789 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5790 (match_operand:SI 2 "const_int_operand" "n")))
5791 (clobber (match_scratch:SI 0 "=rm"))]
5792 "ix86_match_ccmode (insn, CCGCmode)
5793 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5795 switch (get_attr_type (insn))
5798 if (operands[2] == constm1_rtx)
5799 return "inc{l}\t%0";
5802 gcc_assert (operands[2] == const1_rtx);
5803 return "dec{l}\t%0";
5807 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5808 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5809 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5810 if ((INTVAL (operands[2]) == -128
5811 || (INTVAL (operands[2]) > 0
5812 && INTVAL (operands[2]) != 128)))
5813 return "sub{l}\t{%2, %0|%0, %2}";
5814 operands[2] = GEN_INT (-INTVAL (operands[2]));
5815 return "add{l}\t{%2, %0|%0, %2}";
5819 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5820 (const_string "incdec")
5821 (const_string "alu")))
5822 (set_attr "mode" "SI")])
5824 (define_insn "*addsi_5"
5825 [(set (reg FLAGS_REG)
5827 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5828 (match_operand:SI 2 "general_operand" "rmni"))
5830 (clobber (match_scratch:SI 0 "=r"))]
5831 "ix86_match_ccmode (insn, CCGOCmode)
5832 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5833 /* Current assemblers are broken and do not allow @GOTOFF in
5834 ought but a memory context. */
5835 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5837 switch (get_attr_type (insn))
5840 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5841 if (operands[2] == const1_rtx)
5842 return "inc{l}\t%0";
5845 gcc_assert (operands[2] == constm1_rtx);
5846 return "dec{l}\t%0";
5850 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5851 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5852 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5853 if (GET_CODE (operands[2]) == CONST_INT
5854 && (INTVAL (operands[2]) == 128
5855 || (INTVAL (operands[2]) < 0
5856 && INTVAL (operands[2]) != -128)))
5858 operands[2] = GEN_INT (-INTVAL (operands[2]));
5859 return "sub{l}\t{%2, %0|%0, %2}";
5861 return "add{l}\t{%2, %0|%0, %2}";
5865 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5866 (const_string "incdec")
5867 (const_string "alu")))
5868 (set_attr "mode" "SI")])
5870 (define_expand "addhi3"
5871 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5872 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5873 (match_operand:HI 2 "general_operand" "")))
5874 (clobber (reg:CC FLAGS_REG))])]
5875 "TARGET_HIMODE_MATH"
5876 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5878 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5879 ;; type optimizations enabled by define-splits. This is not important
5880 ;; for PII, and in fact harmful because of partial register stalls.
5882 (define_insn "*addhi_1_lea"
5883 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5884 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5885 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5886 (clobber (reg:CC FLAGS_REG))]
5887 "!TARGET_PARTIAL_REG_STALL
5888 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5890 switch (get_attr_type (insn))
5895 if (operands[2] == const1_rtx)
5896 return "inc{w}\t%0";
5899 gcc_assert (operands[2] == constm1_rtx);
5900 return "dec{w}\t%0";
5904 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5905 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5906 if (GET_CODE (operands[2]) == CONST_INT
5907 && (INTVAL (operands[2]) == 128
5908 || (INTVAL (operands[2]) < 0
5909 && INTVAL (operands[2]) != -128)))
5911 operands[2] = GEN_INT (-INTVAL (operands[2]));
5912 return "sub{w}\t{%2, %0|%0, %2}";
5914 return "add{w}\t{%2, %0|%0, %2}";
5918 (if_then_else (eq_attr "alternative" "2")
5919 (const_string "lea")
5920 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5921 (const_string "incdec")
5922 (const_string "alu"))))
5923 (set_attr "mode" "HI,HI,SI")])
5925 (define_insn "*addhi_1"
5926 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5927 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5928 (match_operand:HI 2 "general_operand" "ri,rm")))
5929 (clobber (reg:CC FLAGS_REG))]
5930 "TARGET_PARTIAL_REG_STALL
5931 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5933 switch (get_attr_type (insn))
5936 if (operands[2] == const1_rtx)
5937 return "inc{w}\t%0";
5940 gcc_assert (operands[2] == constm1_rtx);
5941 return "dec{w}\t%0";
5945 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5946 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5947 if (GET_CODE (operands[2]) == CONST_INT
5948 && (INTVAL (operands[2]) == 128
5949 || (INTVAL (operands[2]) < 0
5950 && INTVAL (operands[2]) != -128)))
5952 operands[2] = GEN_INT (-INTVAL (operands[2]));
5953 return "sub{w}\t{%2, %0|%0, %2}";
5955 return "add{w}\t{%2, %0|%0, %2}";
5959 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5960 (const_string "incdec")
5961 (const_string "alu")))
5962 (set_attr "mode" "HI")])
5964 (define_insn "*addhi_2"
5965 [(set (reg FLAGS_REG)
5967 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5968 (match_operand:HI 2 "general_operand" "rmni,rni"))
5970 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5971 (plus:HI (match_dup 1) (match_dup 2)))]
5972 "ix86_match_ccmode (insn, CCGOCmode)
5973 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5975 switch (get_attr_type (insn))
5978 if (operands[2] == const1_rtx)
5979 return "inc{w}\t%0";
5982 gcc_assert (operands[2] == constm1_rtx);
5983 return "dec{w}\t%0";
5987 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5988 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5989 if (GET_CODE (operands[2]) == CONST_INT
5990 && (INTVAL (operands[2]) == 128
5991 || (INTVAL (operands[2]) < 0
5992 && INTVAL (operands[2]) != -128)))
5994 operands[2] = GEN_INT (-INTVAL (operands[2]));
5995 return "sub{w}\t{%2, %0|%0, %2}";
5997 return "add{w}\t{%2, %0|%0, %2}";
6001 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6002 (const_string "incdec")
6003 (const_string "alu")))
6004 (set_attr "mode" "HI")])
6006 (define_insn "*addhi_3"
6007 [(set (reg FLAGS_REG)
6008 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6009 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6010 (clobber (match_scratch:HI 0 "=r"))]
6011 "ix86_match_ccmode (insn, CCZmode)
6012 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6014 switch (get_attr_type (insn))
6017 if (operands[2] == const1_rtx)
6018 return "inc{w}\t%0";
6021 gcc_assert (operands[2] == constm1_rtx);
6022 return "dec{w}\t%0";
6026 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6027 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6028 if (GET_CODE (operands[2]) == CONST_INT
6029 && (INTVAL (operands[2]) == 128
6030 || (INTVAL (operands[2]) < 0
6031 && INTVAL (operands[2]) != -128)))
6033 operands[2] = GEN_INT (-INTVAL (operands[2]));
6034 return "sub{w}\t{%2, %0|%0, %2}";
6036 return "add{w}\t{%2, %0|%0, %2}";
6040 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6041 (const_string "incdec")
6042 (const_string "alu")))
6043 (set_attr "mode" "HI")])
6045 ; See comments above addsi_4 for details.
6046 (define_insn "*addhi_4"
6047 [(set (reg FLAGS_REG)
6048 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6049 (match_operand:HI 2 "const_int_operand" "n")))
6050 (clobber (match_scratch:HI 0 "=rm"))]
6051 "ix86_match_ccmode (insn, CCGCmode)
6052 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6054 switch (get_attr_type (insn))
6057 if (operands[2] == constm1_rtx)
6058 return "inc{w}\t%0";
6061 gcc_assert (operands[2] == const1_rtx);
6062 return "dec{w}\t%0";
6066 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6067 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6068 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6069 if ((INTVAL (operands[2]) == -128
6070 || (INTVAL (operands[2]) > 0
6071 && INTVAL (operands[2]) != 128)))
6072 return "sub{w}\t{%2, %0|%0, %2}";
6073 operands[2] = GEN_INT (-INTVAL (operands[2]));
6074 return "add{w}\t{%2, %0|%0, %2}";
6078 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6079 (const_string "incdec")
6080 (const_string "alu")))
6081 (set_attr "mode" "SI")])
6084 (define_insn "*addhi_5"
6085 [(set (reg FLAGS_REG)
6087 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6088 (match_operand:HI 2 "general_operand" "rmni"))
6090 (clobber (match_scratch:HI 0 "=r"))]
6091 "ix86_match_ccmode (insn, CCGOCmode)
6092 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6094 switch (get_attr_type (insn))
6097 if (operands[2] == const1_rtx)
6098 return "inc{w}\t%0";
6101 gcc_assert (operands[2] == constm1_rtx);
6102 return "dec{w}\t%0";
6106 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6107 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6108 if (GET_CODE (operands[2]) == CONST_INT
6109 && (INTVAL (operands[2]) == 128
6110 || (INTVAL (operands[2]) < 0
6111 && INTVAL (operands[2]) != -128)))
6113 operands[2] = GEN_INT (-INTVAL (operands[2]));
6114 return "sub{w}\t{%2, %0|%0, %2}";
6116 return "add{w}\t{%2, %0|%0, %2}";
6120 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6121 (const_string "incdec")
6122 (const_string "alu")))
6123 (set_attr "mode" "HI")])
6125 (define_expand "addqi3"
6126 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6127 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6128 (match_operand:QI 2 "general_operand" "")))
6129 (clobber (reg:CC FLAGS_REG))])]
6130 "TARGET_QIMODE_MATH"
6131 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6133 ;; %%% Potential partial reg stall on alternative 2. What to do?
6134 (define_insn "*addqi_1_lea"
6135 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6136 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6137 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6138 (clobber (reg:CC FLAGS_REG))]
6139 "!TARGET_PARTIAL_REG_STALL
6140 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6142 int widen = (which_alternative == 2);
6143 switch (get_attr_type (insn))
6148 if (operands[2] == const1_rtx)
6149 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6152 gcc_assert (operands[2] == constm1_rtx);
6153 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6157 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6158 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6159 if (GET_CODE (operands[2]) == CONST_INT
6160 && (INTVAL (operands[2]) == 128
6161 || (INTVAL (operands[2]) < 0
6162 && INTVAL (operands[2]) != -128)))
6164 operands[2] = GEN_INT (-INTVAL (operands[2]));
6166 return "sub{l}\t{%2, %k0|%k0, %2}";
6168 return "sub{b}\t{%2, %0|%0, %2}";
6171 return "add{l}\t{%k2, %k0|%k0, %k2}";
6173 return "add{b}\t{%2, %0|%0, %2}";
6177 (if_then_else (eq_attr "alternative" "3")
6178 (const_string "lea")
6179 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6180 (const_string "incdec")
6181 (const_string "alu"))))
6182 (set_attr "mode" "QI,QI,SI,SI")])
6184 (define_insn "*addqi_1"
6185 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6186 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6187 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6188 (clobber (reg:CC FLAGS_REG))]
6189 "TARGET_PARTIAL_REG_STALL
6190 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6192 int widen = (which_alternative == 2);
6193 switch (get_attr_type (insn))
6196 if (operands[2] == const1_rtx)
6197 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6200 gcc_assert (operands[2] == constm1_rtx);
6201 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6205 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6206 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6207 if (GET_CODE (operands[2]) == CONST_INT
6208 && (INTVAL (operands[2]) == 128
6209 || (INTVAL (operands[2]) < 0
6210 && INTVAL (operands[2]) != -128)))
6212 operands[2] = GEN_INT (-INTVAL (operands[2]));
6214 return "sub{l}\t{%2, %k0|%k0, %2}";
6216 return "sub{b}\t{%2, %0|%0, %2}";
6219 return "add{l}\t{%k2, %k0|%k0, %k2}";
6221 return "add{b}\t{%2, %0|%0, %2}";
6225 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6226 (const_string "incdec")
6227 (const_string "alu")))
6228 (set_attr "mode" "QI,QI,SI")])
6230 (define_insn "*addqi_1_slp"
6231 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6232 (plus:QI (match_dup 0)
6233 (match_operand:QI 1 "general_operand" "qn,qnm")))
6234 (clobber (reg:CC FLAGS_REG))]
6235 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6236 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6238 switch (get_attr_type (insn))
6241 if (operands[1] == const1_rtx)
6242 return "inc{b}\t%0";
6245 gcc_assert (operands[1] == constm1_rtx);
6246 return "dec{b}\t%0";
6250 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6251 if (GET_CODE (operands[1]) == CONST_INT
6252 && INTVAL (operands[1]) < 0)
6254 operands[1] = GEN_INT (-INTVAL (operands[1]));
6255 return "sub{b}\t{%1, %0|%0, %1}";
6257 return "add{b}\t{%1, %0|%0, %1}";
6261 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6262 (const_string "incdec")
6263 (const_string "alu1")))
6264 (set (attr "memory")
6265 (if_then_else (match_operand 1 "memory_operand" "")
6266 (const_string "load")
6267 (const_string "none")))
6268 (set_attr "mode" "QI")])
6270 (define_insn "*addqi_2"
6271 [(set (reg FLAGS_REG)
6273 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6274 (match_operand:QI 2 "general_operand" "qmni,qni"))
6276 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6277 (plus:QI (match_dup 1) (match_dup 2)))]
6278 "ix86_match_ccmode (insn, CCGOCmode)
6279 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6281 switch (get_attr_type (insn))
6284 if (operands[2] == const1_rtx)
6285 return "inc{b}\t%0";
6288 gcc_assert (operands[2] == constm1_rtx
6289 || (GET_CODE (operands[2]) == CONST_INT
6290 && INTVAL (operands[2]) == 255));
6291 return "dec{b}\t%0";
6295 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6296 if (GET_CODE (operands[2]) == CONST_INT
6297 && INTVAL (operands[2]) < 0)
6299 operands[2] = GEN_INT (-INTVAL (operands[2]));
6300 return "sub{b}\t{%2, %0|%0, %2}";
6302 return "add{b}\t{%2, %0|%0, %2}";
6306 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6307 (const_string "incdec")
6308 (const_string "alu")))
6309 (set_attr "mode" "QI")])
6311 (define_insn "*addqi_3"
6312 [(set (reg FLAGS_REG)
6313 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6314 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6315 (clobber (match_scratch:QI 0 "=q"))]
6316 "ix86_match_ccmode (insn, CCZmode)
6317 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6319 switch (get_attr_type (insn))
6322 if (operands[2] == const1_rtx)
6323 return "inc{b}\t%0";
6326 gcc_assert (operands[2] == constm1_rtx
6327 || (GET_CODE (operands[2]) == CONST_INT
6328 && INTVAL (operands[2]) == 255));
6329 return "dec{b}\t%0";
6333 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6334 if (GET_CODE (operands[2]) == CONST_INT
6335 && INTVAL (operands[2]) < 0)
6337 operands[2] = GEN_INT (-INTVAL (operands[2]));
6338 return "sub{b}\t{%2, %0|%0, %2}";
6340 return "add{b}\t{%2, %0|%0, %2}";
6344 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6345 (const_string "incdec")
6346 (const_string "alu")))
6347 (set_attr "mode" "QI")])
6349 ; See comments above addsi_4 for details.
6350 (define_insn "*addqi_4"
6351 [(set (reg FLAGS_REG)
6352 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6353 (match_operand:QI 2 "const_int_operand" "n")))
6354 (clobber (match_scratch:QI 0 "=qm"))]
6355 "ix86_match_ccmode (insn, CCGCmode)
6356 && (INTVAL (operands[2]) & 0xff) != 0x80"
6358 switch (get_attr_type (insn))
6361 if (operands[2] == constm1_rtx
6362 || (GET_CODE (operands[2]) == CONST_INT
6363 && INTVAL (operands[2]) == 255))
6364 return "inc{b}\t%0";
6367 gcc_assert (operands[2] == const1_rtx);
6368 return "dec{b}\t%0";
6372 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6373 if (INTVAL (operands[2]) < 0)
6375 operands[2] = GEN_INT (-INTVAL (operands[2]));
6376 return "add{b}\t{%2, %0|%0, %2}";
6378 return "sub{b}\t{%2, %0|%0, %2}";
6382 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6383 (const_string "incdec")
6384 (const_string "alu")))
6385 (set_attr "mode" "QI")])
6388 (define_insn "*addqi_5"
6389 [(set (reg FLAGS_REG)
6391 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6392 (match_operand:QI 2 "general_operand" "qmni"))
6394 (clobber (match_scratch:QI 0 "=q"))]
6395 "ix86_match_ccmode (insn, CCGOCmode)
6396 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6398 switch (get_attr_type (insn))
6401 if (operands[2] == const1_rtx)
6402 return "inc{b}\t%0";
6405 gcc_assert (operands[2] == constm1_rtx
6406 || (GET_CODE (operands[2]) == CONST_INT
6407 && INTVAL (operands[2]) == 255));
6408 return "dec{b}\t%0";
6412 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6413 if (GET_CODE (operands[2]) == CONST_INT
6414 && INTVAL (operands[2]) < 0)
6416 operands[2] = GEN_INT (-INTVAL (operands[2]));
6417 return "sub{b}\t{%2, %0|%0, %2}";
6419 return "add{b}\t{%2, %0|%0, %2}";
6423 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6424 (const_string "incdec")
6425 (const_string "alu")))
6426 (set_attr "mode" "QI")])
6429 (define_insn "addqi_ext_1"
6430 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6435 (match_operand 1 "ext_register_operand" "0")
6438 (match_operand:QI 2 "general_operand" "Qmn")))
6439 (clobber (reg:CC FLAGS_REG))]
6442 switch (get_attr_type (insn))
6445 if (operands[2] == const1_rtx)
6446 return "inc{b}\t%h0";
6449 gcc_assert (operands[2] == constm1_rtx
6450 || (GET_CODE (operands[2]) == CONST_INT
6451 && INTVAL (operands[2]) == 255));
6452 return "dec{b}\t%h0";
6456 return "add{b}\t{%2, %h0|%h0, %2}";
6460 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6461 (const_string "incdec")
6462 (const_string "alu")))
6463 (set_attr "mode" "QI")])
6465 (define_insn "*addqi_ext_1_rex64"
6466 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6471 (match_operand 1 "ext_register_operand" "0")
6474 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6475 (clobber (reg:CC FLAGS_REG))]
6478 switch (get_attr_type (insn))
6481 if (operands[2] == const1_rtx)
6482 return "inc{b}\t%h0";
6485 gcc_assert (operands[2] == constm1_rtx
6486 || (GET_CODE (operands[2]) == CONST_INT
6487 && INTVAL (operands[2]) == 255));
6488 return "dec{b}\t%h0";
6492 return "add{b}\t{%2, %h0|%h0, %2}";
6496 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6497 (const_string "incdec")
6498 (const_string "alu")))
6499 (set_attr "mode" "QI")])
6501 (define_insn "*addqi_ext_2"
6502 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6507 (match_operand 1 "ext_register_operand" "%0")
6511 (match_operand 2 "ext_register_operand" "Q")
6514 (clobber (reg:CC FLAGS_REG))]
6516 "add{b}\t{%h2, %h0|%h0, %h2}"
6517 [(set_attr "type" "alu")
6518 (set_attr "mode" "QI")])
6520 ;; The patterns that match these are at the end of this file.
6522 (define_expand "addxf3"
6523 [(set (match_operand:XF 0 "register_operand" "")
6524 (plus:XF (match_operand:XF 1 "register_operand" "")
6525 (match_operand:XF 2 "register_operand" "")))]
6529 (define_expand "adddf3"
6530 [(set (match_operand:DF 0 "register_operand" "")
6531 (plus:DF (match_operand:DF 1 "register_operand" "")
6532 (match_operand:DF 2 "nonimmediate_operand" "")))]
6533 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6536 (define_expand "addsf3"
6537 [(set (match_operand:SF 0 "register_operand" "")
6538 (plus:SF (match_operand:SF 1 "register_operand" "")
6539 (match_operand:SF 2 "nonimmediate_operand" "")))]
6540 "TARGET_80387 || TARGET_SSE_MATH"
6543 ;; Subtract instructions
6545 ;; %%% splits for subditi3
6547 (define_expand "subti3"
6548 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6549 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6550 (match_operand:TI 2 "x86_64_general_operand" "")))
6551 (clobber (reg:CC FLAGS_REG))])]
6553 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6555 (define_insn "*subti3_1"
6556 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6557 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6558 (match_operand:TI 2 "general_operand" "roiF,riF")))
6559 (clobber (reg:CC FLAGS_REG))]
6560 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6564 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6565 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6566 (match_operand:TI 2 "general_operand" "")))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "TARGET_64BIT && reload_completed"
6569 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6570 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6571 (parallel [(set (match_dup 3)
6572 (minus:DI (match_dup 4)
6573 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6575 (clobber (reg:CC FLAGS_REG))])]
6576 "split_ti (operands+0, 1, operands+0, operands+3);
6577 split_ti (operands+1, 1, operands+1, operands+4);
6578 split_ti (operands+2, 1, operands+2, operands+5);")
6580 ;; %%% splits for subsidi3
6582 (define_expand "subdi3"
6583 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6584 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6585 (match_operand:DI 2 "x86_64_general_operand" "")))
6586 (clobber (reg:CC FLAGS_REG))])]
6588 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6590 (define_insn "*subdi3_1"
6591 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6592 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6593 (match_operand:DI 2 "general_operand" "roiF,riF")))
6594 (clobber (reg:CC FLAGS_REG))]
6595 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6599 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6600 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6601 (match_operand:DI 2 "general_operand" "")))
6602 (clobber (reg:CC FLAGS_REG))]
6603 "!TARGET_64BIT && reload_completed"
6604 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6605 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6606 (parallel [(set (match_dup 3)
6607 (minus:SI (match_dup 4)
6608 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6610 (clobber (reg:CC FLAGS_REG))])]
6611 "split_di (operands+0, 1, operands+0, operands+3);
6612 split_di (operands+1, 1, operands+1, operands+4);
6613 split_di (operands+2, 1, operands+2, operands+5);")
6615 (define_insn "subdi3_carry_rex64"
6616 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6617 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6618 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6619 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6620 (clobber (reg:CC FLAGS_REG))]
6621 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6622 "sbb{q}\t{%2, %0|%0, %2}"
6623 [(set_attr "type" "alu")
6624 (set_attr "pent_pair" "pu")
6625 (set_attr "mode" "DI")])
6627 (define_insn "*subdi_1_rex64"
6628 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6629 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6630 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6631 (clobber (reg:CC FLAGS_REG))]
6632 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6633 "sub{q}\t{%2, %0|%0, %2}"
6634 [(set_attr "type" "alu")
6635 (set_attr "mode" "DI")])
6637 (define_insn "*subdi_2_rex64"
6638 [(set (reg FLAGS_REG)
6640 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6641 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6643 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6644 (minus:DI (match_dup 1) (match_dup 2)))]
6645 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6646 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6647 "sub{q}\t{%2, %0|%0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "mode" "DI")])
6651 (define_insn "*subdi_3_rex63"
6652 [(set (reg FLAGS_REG)
6653 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6654 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6655 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6656 (minus:DI (match_dup 1) (match_dup 2)))]
6657 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6658 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6659 "sub{q}\t{%2, %0|%0, %2}"
6660 [(set_attr "type" "alu")
6661 (set_attr "mode" "DI")])
6663 (define_insn "subqi3_carry"
6664 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6665 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6666 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6667 (match_operand:QI 2 "general_operand" "qi,qm"))))
6668 (clobber (reg:CC FLAGS_REG))]
6669 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6670 "sbb{b}\t{%2, %0|%0, %2}"
6671 [(set_attr "type" "alu")
6672 (set_attr "pent_pair" "pu")
6673 (set_attr "mode" "QI")])
6675 (define_insn "subhi3_carry"
6676 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6677 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6678 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6679 (match_operand:HI 2 "general_operand" "ri,rm"))))
6680 (clobber (reg:CC FLAGS_REG))]
6681 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6682 "sbb{w}\t{%2, %0|%0, %2}"
6683 [(set_attr "type" "alu")
6684 (set_attr "pent_pair" "pu")
6685 (set_attr "mode" "HI")])
6687 (define_insn "subsi3_carry"
6688 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6689 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6690 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6691 (match_operand:SI 2 "general_operand" "ri,rm"))))
6692 (clobber (reg:CC FLAGS_REG))]
6693 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6694 "sbb{l}\t{%2, %0|%0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "pent_pair" "pu")
6697 (set_attr "mode" "SI")])
6699 (define_insn "subsi3_carry_zext"
6700 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6702 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6703 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6704 (match_operand:SI 2 "general_operand" "ri,rm")))))
6705 (clobber (reg:CC FLAGS_REG))]
6706 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707 "sbb{l}\t{%2, %k0|%k0, %2}"
6708 [(set_attr "type" "alu")
6709 (set_attr "pent_pair" "pu")
6710 (set_attr "mode" "SI")])
6712 (define_expand "subsi3"
6713 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6714 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6715 (match_operand:SI 2 "general_operand" "")))
6716 (clobber (reg:CC FLAGS_REG))])]
6718 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6720 (define_insn "*subsi_1"
6721 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6722 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6723 (match_operand:SI 2 "general_operand" "ri,rm")))
6724 (clobber (reg:CC FLAGS_REG))]
6725 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6726 "sub{l}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "alu")
6728 (set_attr "mode" "SI")])
6730 (define_insn "*subsi_1_zext"
6731 [(set (match_operand:DI 0 "register_operand" "=r")
6733 (minus:SI (match_operand:SI 1 "register_operand" "0")
6734 (match_operand:SI 2 "general_operand" "rim"))))
6735 (clobber (reg:CC FLAGS_REG))]
6736 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6737 "sub{l}\t{%2, %k0|%k0, %2}"
6738 [(set_attr "type" "alu")
6739 (set_attr "mode" "SI")])
6741 (define_insn "*subsi_2"
6742 [(set (reg FLAGS_REG)
6744 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6745 (match_operand:SI 2 "general_operand" "ri,rm"))
6747 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6748 (minus:SI (match_dup 1) (match_dup 2)))]
6749 "ix86_match_ccmode (insn, CCGOCmode)
6750 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6751 "sub{l}\t{%2, %0|%0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "mode" "SI")])
6755 (define_insn "*subsi_2_zext"
6756 [(set (reg FLAGS_REG)
6758 (minus:SI (match_operand:SI 1 "register_operand" "0")
6759 (match_operand:SI 2 "general_operand" "rim"))
6761 (set (match_operand:DI 0 "register_operand" "=r")
6763 (minus:SI (match_dup 1)
6765 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6766 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6767 "sub{l}\t{%2, %k0|%k0, %2}"
6768 [(set_attr "type" "alu")
6769 (set_attr "mode" "SI")])
6771 (define_insn "*subsi_3"
6772 [(set (reg FLAGS_REG)
6773 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6774 (match_operand:SI 2 "general_operand" "ri,rm")))
6775 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6776 (minus:SI (match_dup 1) (match_dup 2)))]
6777 "ix86_match_ccmode (insn, CCmode)
6778 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6779 "sub{l}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "SI")])
6783 (define_insn "*subsi_3_zext"
6784 [(set (reg FLAGS_REG)
6785 (compare (match_operand:SI 1 "register_operand" "0")
6786 (match_operand:SI 2 "general_operand" "rim")))
6787 (set (match_operand:DI 0 "register_operand" "=r")
6789 (minus:SI (match_dup 1)
6791 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6792 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6793 "sub{l}\t{%2, %1|%1, %2}"
6794 [(set_attr "type" "alu")
6795 (set_attr "mode" "DI")])
6797 (define_expand "subhi3"
6798 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6799 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6800 (match_operand:HI 2 "general_operand" "")))
6801 (clobber (reg:CC FLAGS_REG))])]
6802 "TARGET_HIMODE_MATH"
6803 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6805 (define_insn "*subhi_1"
6806 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6807 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6808 (match_operand:HI 2 "general_operand" "ri,rm")))
6809 (clobber (reg:CC FLAGS_REG))]
6810 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6811 "sub{w}\t{%2, %0|%0, %2}"
6812 [(set_attr "type" "alu")
6813 (set_attr "mode" "HI")])
6815 (define_insn "*subhi_2"
6816 [(set (reg FLAGS_REG)
6818 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6819 (match_operand:HI 2 "general_operand" "ri,rm"))
6821 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6822 (minus:HI (match_dup 1) (match_dup 2)))]
6823 "ix86_match_ccmode (insn, CCGOCmode)
6824 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6825 "sub{w}\t{%2, %0|%0, %2}"
6826 [(set_attr "type" "alu")
6827 (set_attr "mode" "HI")])
6829 (define_insn "*subhi_3"
6830 [(set (reg FLAGS_REG)
6831 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6832 (match_operand:HI 2 "general_operand" "ri,rm")))
6833 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6834 (minus:HI (match_dup 1) (match_dup 2)))]
6835 "ix86_match_ccmode (insn, CCmode)
6836 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6837 "sub{w}\t{%2, %0|%0, %2}"
6838 [(set_attr "type" "alu")
6839 (set_attr "mode" "HI")])
6841 (define_expand "subqi3"
6842 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6843 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6844 (match_operand:QI 2 "general_operand" "")))
6845 (clobber (reg:CC FLAGS_REG))])]
6846 "TARGET_QIMODE_MATH"
6847 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6849 (define_insn "*subqi_1"
6850 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6851 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6852 (match_operand:QI 2 "general_operand" "qn,qmn")))
6853 (clobber (reg:CC FLAGS_REG))]
6854 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6855 "sub{b}\t{%2, %0|%0, %2}"
6856 [(set_attr "type" "alu")
6857 (set_attr "mode" "QI")])
6859 (define_insn "*subqi_1_slp"
6860 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6861 (minus:QI (match_dup 0)
6862 (match_operand:QI 1 "general_operand" "qn,qmn")))
6863 (clobber (reg:CC FLAGS_REG))]
6864 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6865 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6866 "sub{b}\t{%1, %0|%0, %1}"
6867 [(set_attr "type" "alu1")
6868 (set_attr "mode" "QI")])
6870 (define_insn "*subqi_2"
6871 [(set (reg FLAGS_REG)
6873 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6874 (match_operand:QI 2 "general_operand" "qi,qm"))
6876 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6877 (minus:HI (match_dup 1) (match_dup 2)))]
6878 "ix86_match_ccmode (insn, CCGOCmode)
6879 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6880 "sub{b}\t{%2, %0|%0, %2}"
6881 [(set_attr "type" "alu")
6882 (set_attr "mode" "QI")])
6884 (define_insn "*subqi_3"
6885 [(set (reg FLAGS_REG)
6886 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6887 (match_operand:QI 2 "general_operand" "qi,qm")))
6888 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6889 (minus:HI (match_dup 1) (match_dup 2)))]
6890 "ix86_match_ccmode (insn, CCmode)
6891 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6892 "sub{b}\t{%2, %0|%0, %2}"
6893 [(set_attr "type" "alu")
6894 (set_attr "mode" "QI")])
6896 ;; The patterns that match these are at the end of this file.
6898 (define_expand "subxf3"
6899 [(set (match_operand:XF 0 "register_operand" "")
6900 (minus:XF (match_operand:XF 1 "register_operand" "")
6901 (match_operand:XF 2 "register_operand" "")))]
6905 (define_expand "subdf3"
6906 [(set (match_operand:DF 0 "register_operand" "")
6907 (minus:DF (match_operand:DF 1 "register_operand" "")
6908 (match_operand:DF 2 "nonimmediate_operand" "")))]
6909 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6912 (define_expand "subsf3"
6913 [(set (match_operand:SF 0 "register_operand" "")
6914 (minus:SF (match_operand:SF 1 "register_operand" "")
6915 (match_operand:SF 2 "nonimmediate_operand" "")))]
6916 "TARGET_80387 || TARGET_SSE_MATH"
6919 ;; Multiply instructions
6921 (define_expand "muldi3"
6922 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6923 (mult:DI (match_operand:DI 1 "register_operand" "")
6924 (match_operand:DI 2 "x86_64_general_operand" "")))
6925 (clobber (reg:CC FLAGS_REG))])]
6929 (define_insn "*muldi3_1_rex64"
6930 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6931 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6932 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6933 (clobber (reg:CC FLAGS_REG))]
6935 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6937 imul{q}\t{%2, %1, %0|%0, %1, %2}
6938 imul{q}\t{%2, %1, %0|%0, %1, %2}
6939 imul{q}\t{%2, %0|%0, %2}"
6940 [(set_attr "type" "imul")
6941 (set_attr "prefix_0f" "0,0,1")
6942 (set (attr "athlon_decode")
6943 (cond [(eq_attr "cpu" "athlon")
6944 (const_string "vector")
6945 (eq_attr "alternative" "1")
6946 (const_string "vector")
6947 (and (eq_attr "alternative" "2")
6948 (match_operand 1 "memory_operand" ""))
6949 (const_string "vector")]
6950 (const_string "direct")))
6951 (set_attr "mode" "DI")])
6953 (define_expand "mulsi3"
6954 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6955 (mult:SI (match_operand:SI 1 "register_operand" "")
6956 (match_operand:SI 2 "general_operand" "")))
6957 (clobber (reg:CC FLAGS_REG))])]
6961 (define_insn "*mulsi3_1"
6962 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6963 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6964 (match_operand:SI 2 "general_operand" "K,i,mr")))
6965 (clobber (reg:CC FLAGS_REG))]
6966 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6968 imul{l}\t{%2, %1, %0|%0, %1, %2}
6969 imul{l}\t{%2, %1, %0|%0, %1, %2}
6970 imul{l}\t{%2, %0|%0, %2}"
6971 [(set_attr "type" "imul")
6972 (set_attr "prefix_0f" "0,0,1")
6973 (set (attr "athlon_decode")
6974 (cond [(eq_attr "cpu" "athlon")
6975 (const_string "vector")
6976 (eq_attr "alternative" "1")
6977 (const_string "vector")
6978 (and (eq_attr "alternative" "2")
6979 (match_operand 1 "memory_operand" ""))
6980 (const_string "vector")]
6981 (const_string "direct")))
6982 (set_attr "mode" "SI")])
6984 (define_insn "*mulsi3_1_zext"
6985 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6987 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6988 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6989 (clobber (reg:CC FLAGS_REG))]
6991 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6993 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6994 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6995 imul{l}\t{%2, %k0|%k0, %2}"
6996 [(set_attr "type" "imul")
6997 (set_attr "prefix_0f" "0,0,1")
6998 (set (attr "athlon_decode")
6999 (cond [(eq_attr "cpu" "athlon")
7000 (const_string "vector")
7001 (eq_attr "alternative" "1")
7002 (const_string "vector")
7003 (and (eq_attr "alternative" "2")
7004 (match_operand 1 "memory_operand" ""))
7005 (const_string "vector")]
7006 (const_string "direct")))
7007 (set_attr "mode" "SI")])
7009 (define_expand "mulhi3"
7010 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7011 (mult:HI (match_operand:HI 1 "register_operand" "")
7012 (match_operand:HI 2 "general_operand" "")))
7013 (clobber (reg:CC FLAGS_REG))])]
7014 "TARGET_HIMODE_MATH"
7017 (define_insn "*mulhi3_1"
7018 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7019 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7020 (match_operand:HI 2 "general_operand" "K,i,mr")))
7021 (clobber (reg:CC FLAGS_REG))]
7022 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7024 imul{w}\t{%2, %1, %0|%0, %1, %2}
7025 imul{w}\t{%2, %1, %0|%0, %1, %2}
7026 imul{w}\t{%2, %0|%0, %2}"
7027 [(set_attr "type" "imul")
7028 (set_attr "prefix_0f" "0,0,1")
7029 (set (attr "athlon_decode")
7030 (cond [(eq_attr "cpu" "athlon")
7031 (const_string "vector")
7032 (eq_attr "alternative" "1,2")
7033 (const_string "vector")]
7034 (const_string "direct")))
7035 (set_attr "mode" "HI")])
7037 (define_expand "mulqi3"
7038 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7039 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7040 (match_operand:QI 2 "register_operand" "")))
7041 (clobber (reg:CC FLAGS_REG))])]
7042 "TARGET_QIMODE_MATH"
7045 (define_insn "*mulqi3_1"
7046 [(set (match_operand:QI 0 "register_operand" "=a")
7047 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7048 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7049 (clobber (reg:CC FLAGS_REG))]
7051 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7053 [(set_attr "type" "imul")
7054 (set_attr "length_immediate" "0")
7055 (set (attr "athlon_decode")
7056 (if_then_else (eq_attr "cpu" "athlon")
7057 (const_string "vector")
7058 (const_string "direct")))
7059 (set_attr "mode" "QI")])
7061 (define_expand "umulqihi3"
7062 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7063 (mult:HI (zero_extend:HI
7064 (match_operand:QI 1 "nonimmediate_operand" ""))
7066 (match_operand:QI 2 "register_operand" ""))))
7067 (clobber (reg:CC FLAGS_REG))])]
7068 "TARGET_QIMODE_MATH"
7071 (define_insn "*umulqihi3_1"
7072 [(set (match_operand:HI 0 "register_operand" "=a")
7073 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7074 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7075 (clobber (reg:CC FLAGS_REG))]
7077 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7079 [(set_attr "type" "imul")
7080 (set_attr "length_immediate" "0")
7081 (set (attr "athlon_decode")
7082 (if_then_else (eq_attr "cpu" "athlon")
7083 (const_string "vector")
7084 (const_string "direct")))
7085 (set_attr "mode" "QI")])
7087 (define_expand "mulqihi3"
7088 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7089 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7090 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7091 (clobber (reg:CC FLAGS_REG))])]
7092 "TARGET_QIMODE_MATH"
7095 (define_insn "*mulqihi3_insn"
7096 [(set (match_operand:HI 0 "register_operand" "=a")
7097 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7098 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7099 (clobber (reg:CC FLAGS_REG))]
7101 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7103 [(set_attr "type" "imul")
7104 (set_attr "length_immediate" "0")
7105 (set (attr "athlon_decode")
7106 (if_then_else (eq_attr "cpu" "athlon")
7107 (const_string "vector")
7108 (const_string "direct")))
7109 (set_attr "mode" "QI")])
7111 (define_expand "umulditi3"
7112 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7113 (mult:TI (zero_extend:TI
7114 (match_operand:DI 1 "nonimmediate_operand" ""))
7116 (match_operand:DI 2 "register_operand" ""))))
7117 (clobber (reg:CC FLAGS_REG))])]
7121 (define_insn "*umulditi3_insn"
7122 [(set (match_operand:TI 0 "register_operand" "=A")
7123 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7124 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7125 (clobber (reg:CC FLAGS_REG))]
7127 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7129 [(set_attr "type" "imul")
7130 (set_attr "length_immediate" "0")
7131 (set (attr "athlon_decode")
7132 (if_then_else (eq_attr "cpu" "athlon")
7133 (const_string "vector")
7134 (const_string "double")))
7135 (set_attr "mode" "DI")])
7137 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7138 (define_expand "umulsidi3"
7139 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7140 (mult:DI (zero_extend:DI
7141 (match_operand:SI 1 "nonimmediate_operand" ""))
7143 (match_operand:SI 2 "register_operand" ""))))
7144 (clobber (reg:CC FLAGS_REG))])]
7148 (define_insn "*umulsidi3_insn"
7149 [(set (match_operand:DI 0 "register_operand" "=A")
7150 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7151 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7152 (clobber (reg:CC FLAGS_REG))]
7154 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7156 [(set_attr "type" "imul")
7157 (set_attr "length_immediate" "0")
7158 (set (attr "athlon_decode")
7159 (if_then_else (eq_attr "cpu" "athlon")
7160 (const_string "vector")
7161 (const_string "double")))
7162 (set_attr "mode" "SI")])
7164 (define_expand "mulditi3"
7165 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7166 (mult:TI (sign_extend:TI
7167 (match_operand:DI 1 "nonimmediate_operand" ""))
7169 (match_operand:DI 2 "register_operand" ""))))
7170 (clobber (reg:CC FLAGS_REG))])]
7174 (define_insn "*mulditi3_insn"
7175 [(set (match_operand:TI 0 "register_operand" "=A")
7176 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7177 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7178 (clobber (reg:CC FLAGS_REG))]
7180 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7182 [(set_attr "type" "imul")
7183 (set_attr "length_immediate" "0")
7184 (set (attr "athlon_decode")
7185 (if_then_else (eq_attr "cpu" "athlon")
7186 (const_string "vector")
7187 (const_string "double")))
7188 (set_attr "mode" "DI")])
7190 (define_expand "mulsidi3"
7191 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7192 (mult:DI (sign_extend:DI
7193 (match_operand:SI 1 "nonimmediate_operand" ""))
7195 (match_operand:SI 2 "register_operand" ""))))
7196 (clobber (reg:CC FLAGS_REG))])]
7200 (define_insn "*mulsidi3_insn"
7201 [(set (match_operand:DI 0 "register_operand" "=A")
7202 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7203 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7204 (clobber (reg:CC FLAGS_REG))]
7206 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7208 [(set_attr "type" "imul")
7209 (set_attr "length_immediate" "0")
7210 (set (attr "athlon_decode")
7211 (if_then_else (eq_attr "cpu" "athlon")
7212 (const_string "vector")
7213 (const_string "double")))
7214 (set_attr "mode" "SI")])
7216 (define_expand "umuldi3_highpart"
7217 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7220 (mult:TI (zero_extend:TI
7221 (match_operand:DI 1 "nonimmediate_operand" ""))
7223 (match_operand:DI 2 "register_operand" "")))
7225 (clobber (match_scratch:DI 3 ""))
7226 (clobber (reg:CC FLAGS_REG))])]
7230 (define_insn "*umuldi3_highpart_rex64"
7231 [(set (match_operand:DI 0 "register_operand" "=d")
7234 (mult:TI (zero_extend:TI
7235 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7237 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7239 (clobber (match_scratch:DI 3 "=1"))
7240 (clobber (reg:CC FLAGS_REG))]
7242 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7244 [(set_attr "type" "imul")
7245 (set_attr "length_immediate" "0")
7246 (set (attr "athlon_decode")
7247 (if_then_else (eq_attr "cpu" "athlon")
7248 (const_string "vector")
7249 (const_string "double")))
7250 (set_attr "mode" "DI")])
7252 (define_expand "umulsi3_highpart"
7253 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7256 (mult:DI (zero_extend:DI
7257 (match_operand:SI 1 "nonimmediate_operand" ""))
7259 (match_operand:SI 2 "register_operand" "")))
7261 (clobber (match_scratch:SI 3 ""))
7262 (clobber (reg:CC FLAGS_REG))])]
7266 (define_insn "*umulsi3_highpart_insn"
7267 [(set (match_operand:SI 0 "register_operand" "=d")
7270 (mult:DI (zero_extend:DI
7271 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7273 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7275 (clobber (match_scratch:SI 3 "=1"))
7276 (clobber (reg:CC FLAGS_REG))]
7277 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7279 [(set_attr "type" "imul")
7280 (set_attr "length_immediate" "0")
7281 (set (attr "athlon_decode")
7282 (if_then_else (eq_attr "cpu" "athlon")
7283 (const_string "vector")
7284 (const_string "double")))
7285 (set_attr "mode" "SI")])
7287 (define_insn "*umulsi3_highpart_zext"
7288 [(set (match_operand:DI 0 "register_operand" "=d")
7289 (zero_extend:DI (truncate:SI
7291 (mult:DI (zero_extend:DI
7292 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7294 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7296 (clobber (match_scratch:SI 3 "=1"))
7297 (clobber (reg:CC FLAGS_REG))]
7299 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7301 [(set_attr "type" "imul")
7302 (set_attr "length_immediate" "0")
7303 (set (attr "athlon_decode")
7304 (if_then_else (eq_attr "cpu" "athlon")
7305 (const_string "vector")
7306 (const_string "double")))
7307 (set_attr "mode" "SI")])
7309 (define_expand "smuldi3_highpart"
7310 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7313 (mult:TI (sign_extend:TI
7314 (match_operand:DI 1 "nonimmediate_operand" ""))
7316 (match_operand:DI 2 "register_operand" "")))
7318 (clobber (match_scratch:DI 3 ""))
7319 (clobber (reg:CC FLAGS_REG))])]
7323 (define_insn "*smuldi3_highpart_rex64"
7324 [(set (match_operand:DI 0 "register_operand" "=d")
7327 (mult:TI (sign_extend:TI
7328 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7330 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7332 (clobber (match_scratch:DI 3 "=1"))
7333 (clobber (reg:CC FLAGS_REG))]
7335 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7337 [(set_attr "type" "imul")
7338 (set (attr "athlon_decode")
7339 (if_then_else (eq_attr "cpu" "athlon")
7340 (const_string "vector")
7341 (const_string "double")))
7342 (set_attr "mode" "DI")])
7344 (define_expand "smulsi3_highpart"
7345 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7348 (mult:DI (sign_extend:DI
7349 (match_operand:SI 1 "nonimmediate_operand" ""))
7351 (match_operand:SI 2 "register_operand" "")))
7353 (clobber (match_scratch:SI 3 ""))
7354 (clobber (reg:CC FLAGS_REG))])]
7358 (define_insn "*smulsi3_highpart_insn"
7359 [(set (match_operand:SI 0 "register_operand" "=d")
7362 (mult:DI (sign_extend:DI
7363 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7365 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7367 (clobber (match_scratch:SI 3 "=1"))
7368 (clobber (reg:CC FLAGS_REG))]
7369 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7371 [(set_attr "type" "imul")
7372 (set (attr "athlon_decode")
7373 (if_then_else (eq_attr "cpu" "athlon")
7374 (const_string "vector")
7375 (const_string "double")))
7376 (set_attr "mode" "SI")])
7378 (define_insn "*smulsi3_highpart_zext"
7379 [(set (match_operand:DI 0 "register_operand" "=d")
7380 (zero_extend:DI (truncate:SI
7382 (mult:DI (sign_extend:DI
7383 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7385 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7387 (clobber (match_scratch:SI 3 "=1"))
7388 (clobber (reg:CC FLAGS_REG))]
7390 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7392 [(set_attr "type" "imul")
7393 (set (attr "athlon_decode")
7394 (if_then_else (eq_attr "cpu" "athlon")
7395 (const_string "vector")
7396 (const_string "double")))
7397 (set_attr "mode" "SI")])
7399 ;; The patterns that match these are at the end of this file.
7401 (define_expand "mulxf3"
7402 [(set (match_operand:XF 0 "register_operand" "")
7403 (mult:XF (match_operand:XF 1 "register_operand" "")
7404 (match_operand:XF 2 "register_operand" "")))]
7408 (define_expand "muldf3"
7409 [(set (match_operand:DF 0 "register_operand" "")
7410 (mult:DF (match_operand:DF 1 "register_operand" "")
7411 (match_operand:DF 2 "nonimmediate_operand" "")))]
7412 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7415 (define_expand "mulsf3"
7416 [(set (match_operand:SF 0 "register_operand" "")
7417 (mult:SF (match_operand:SF 1 "register_operand" "")
7418 (match_operand:SF 2 "nonimmediate_operand" "")))]
7419 "TARGET_80387 || TARGET_SSE_MATH"
7422 ;; Divide instructions
7424 (define_insn "divqi3"
7425 [(set (match_operand:QI 0 "register_operand" "=a")
7426 (div:QI (match_operand:HI 1 "register_operand" "0")
7427 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7428 (clobber (reg:CC FLAGS_REG))]
7429 "TARGET_QIMODE_MATH"
7431 [(set_attr "type" "idiv")
7432 (set_attr "mode" "QI")])
7434 (define_insn "udivqi3"
7435 [(set (match_operand:QI 0 "register_operand" "=a")
7436 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7437 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7438 (clobber (reg:CC FLAGS_REG))]
7439 "TARGET_QIMODE_MATH"
7441 [(set_attr "type" "idiv")
7442 (set_attr "mode" "QI")])
7444 ;; The patterns that match these are at the end of this file.
7446 (define_expand "divxf3"
7447 [(set (match_operand:XF 0 "register_operand" "")
7448 (div:XF (match_operand:XF 1 "register_operand" "")
7449 (match_operand:XF 2 "register_operand" "")))]
7453 (define_expand "divdf3"
7454 [(set (match_operand:DF 0 "register_operand" "")
7455 (div:DF (match_operand:DF 1 "register_operand" "")
7456 (match_operand:DF 2 "nonimmediate_operand" "")))]
7457 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7460 (define_expand "divsf3"
7461 [(set (match_operand:SF 0 "register_operand" "")
7462 (div:SF (match_operand:SF 1 "register_operand" "")
7463 (match_operand:SF 2 "nonimmediate_operand" "")))]
7464 "TARGET_80387 || TARGET_SSE_MATH"
7467 ;; Remainder instructions.
7469 (define_expand "divmoddi4"
7470 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7471 (div:DI (match_operand:DI 1 "register_operand" "")
7472 (match_operand:DI 2 "nonimmediate_operand" "")))
7473 (set (match_operand:DI 3 "register_operand" "")
7474 (mod:DI (match_dup 1) (match_dup 2)))
7475 (clobber (reg:CC FLAGS_REG))])]
7479 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7480 ;; Penalize eax case slightly because it results in worse scheduling
7482 (define_insn "*divmoddi4_nocltd_rex64"
7483 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7484 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7485 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7486 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7487 (mod:DI (match_dup 2) (match_dup 3)))
7488 (clobber (reg:CC FLAGS_REG))]
7489 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7491 [(set_attr "type" "multi")])
7493 (define_insn "*divmoddi4_cltd_rex64"
7494 [(set (match_operand:DI 0 "register_operand" "=a")
7495 (div:DI (match_operand:DI 2 "register_operand" "a")
7496 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7497 (set (match_operand:DI 1 "register_operand" "=&d")
7498 (mod:DI (match_dup 2) (match_dup 3)))
7499 (clobber (reg:CC FLAGS_REG))]
7500 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7502 [(set_attr "type" "multi")])
7504 (define_insn "*divmoddi_noext_rex64"
7505 [(set (match_operand:DI 0 "register_operand" "=a")
7506 (div:DI (match_operand:DI 1 "register_operand" "0")
7507 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7508 (set (match_operand:DI 3 "register_operand" "=d")
7509 (mod:DI (match_dup 1) (match_dup 2)))
7510 (use (match_operand:DI 4 "register_operand" "3"))
7511 (clobber (reg:CC FLAGS_REG))]
7514 [(set_attr "type" "idiv")
7515 (set_attr "mode" "DI")])
7518 [(set (match_operand:DI 0 "register_operand" "")
7519 (div:DI (match_operand:DI 1 "register_operand" "")
7520 (match_operand:DI 2 "nonimmediate_operand" "")))
7521 (set (match_operand:DI 3 "register_operand" "")
7522 (mod:DI (match_dup 1) (match_dup 2)))
7523 (clobber (reg:CC FLAGS_REG))]
7524 "TARGET_64BIT && reload_completed"
7525 [(parallel [(set (match_dup 3)
7526 (ashiftrt:DI (match_dup 4) (const_int 63)))
7527 (clobber (reg:CC FLAGS_REG))])
7528 (parallel [(set (match_dup 0)
7529 (div:DI (reg:DI 0) (match_dup 2)))
7531 (mod:DI (reg:DI 0) (match_dup 2)))
7533 (clobber (reg:CC FLAGS_REG))])]
7535 /* Avoid use of cltd in favor of a mov+shift. */
7536 if (!TARGET_USE_CLTD && !optimize_size)
7538 if (true_regnum (operands[1]))
7539 emit_move_insn (operands[0], operands[1]);
7541 emit_move_insn (operands[3], operands[1]);
7542 operands[4] = operands[3];
7546 gcc_assert (!true_regnum (operands[1]));
7547 operands[4] = operands[1];
7552 (define_expand "divmodsi4"
7553 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7554 (div:SI (match_operand:SI 1 "register_operand" "")
7555 (match_operand:SI 2 "nonimmediate_operand" "")))
7556 (set (match_operand:SI 3 "register_operand" "")
7557 (mod:SI (match_dup 1) (match_dup 2)))
7558 (clobber (reg:CC FLAGS_REG))])]
7562 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7563 ;; Penalize eax case slightly because it results in worse scheduling
7565 (define_insn "*divmodsi4_nocltd"
7566 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7567 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7568 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7569 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7570 (mod:SI (match_dup 2) (match_dup 3)))
7571 (clobber (reg:CC FLAGS_REG))]
7572 "!optimize_size && !TARGET_USE_CLTD"
7574 [(set_attr "type" "multi")])
7576 (define_insn "*divmodsi4_cltd"
7577 [(set (match_operand:SI 0 "register_operand" "=a")
7578 (div:SI (match_operand:SI 2 "register_operand" "a")
7579 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7580 (set (match_operand:SI 1 "register_operand" "=&d")
7581 (mod:SI (match_dup 2) (match_dup 3)))
7582 (clobber (reg:CC FLAGS_REG))]
7583 "optimize_size || TARGET_USE_CLTD"
7585 [(set_attr "type" "multi")])
7587 (define_insn "*divmodsi_noext"
7588 [(set (match_operand:SI 0 "register_operand" "=a")
7589 (div:SI (match_operand:SI 1 "register_operand" "0")
7590 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7591 (set (match_operand:SI 3 "register_operand" "=d")
7592 (mod:SI (match_dup 1) (match_dup 2)))
7593 (use (match_operand:SI 4 "register_operand" "3"))
7594 (clobber (reg:CC FLAGS_REG))]
7597 [(set_attr "type" "idiv")
7598 (set_attr "mode" "SI")])
7601 [(set (match_operand:SI 0 "register_operand" "")
7602 (div:SI (match_operand:SI 1 "register_operand" "")
7603 (match_operand:SI 2 "nonimmediate_operand" "")))
7604 (set (match_operand:SI 3 "register_operand" "")
7605 (mod:SI (match_dup 1) (match_dup 2)))
7606 (clobber (reg:CC FLAGS_REG))]
7608 [(parallel [(set (match_dup 3)
7609 (ashiftrt:SI (match_dup 4) (const_int 31)))
7610 (clobber (reg:CC FLAGS_REG))])
7611 (parallel [(set (match_dup 0)
7612 (div:SI (reg:SI 0) (match_dup 2)))
7614 (mod:SI (reg:SI 0) (match_dup 2)))
7616 (clobber (reg:CC FLAGS_REG))])]
7618 /* Avoid use of cltd in favor of a mov+shift. */
7619 if (!TARGET_USE_CLTD && !optimize_size)
7621 if (true_regnum (operands[1]))
7622 emit_move_insn (operands[0], operands[1]);
7624 emit_move_insn (operands[3], operands[1]);
7625 operands[4] = operands[3];
7629 gcc_assert (!true_regnum (operands[1]));
7630 operands[4] = operands[1];
7634 (define_insn "divmodhi4"
7635 [(set (match_operand:HI 0 "register_operand" "=a")
7636 (div:HI (match_operand:HI 1 "register_operand" "0")
7637 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7638 (set (match_operand:HI 3 "register_operand" "=&d")
7639 (mod:HI (match_dup 1) (match_dup 2)))
7640 (clobber (reg:CC FLAGS_REG))]
7641 "TARGET_HIMODE_MATH"
7643 [(set_attr "type" "multi")
7644 (set_attr "length_immediate" "0")
7645 (set_attr "mode" "SI")])
7647 (define_insn "udivmoddi4"
7648 [(set (match_operand:DI 0 "register_operand" "=a")
7649 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7650 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7651 (set (match_operand:DI 3 "register_operand" "=&d")
7652 (umod:DI (match_dup 1) (match_dup 2)))
7653 (clobber (reg:CC FLAGS_REG))]
7655 "xor{q}\t%3, %3\;div{q}\t%2"
7656 [(set_attr "type" "multi")
7657 (set_attr "length_immediate" "0")
7658 (set_attr "mode" "DI")])
7660 (define_insn "*udivmoddi4_noext"
7661 [(set (match_operand:DI 0 "register_operand" "=a")
7662 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7663 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7664 (set (match_operand:DI 3 "register_operand" "=d")
7665 (umod:DI (match_dup 1) (match_dup 2)))
7667 (clobber (reg:CC FLAGS_REG))]
7670 [(set_attr "type" "idiv")
7671 (set_attr "mode" "DI")])
7674 [(set (match_operand:DI 0 "register_operand" "")
7675 (udiv:DI (match_operand:DI 1 "register_operand" "")
7676 (match_operand:DI 2 "nonimmediate_operand" "")))
7677 (set (match_operand:DI 3 "register_operand" "")
7678 (umod:DI (match_dup 1) (match_dup 2)))
7679 (clobber (reg:CC FLAGS_REG))]
7680 "TARGET_64BIT && reload_completed"
7681 [(set (match_dup 3) (const_int 0))
7682 (parallel [(set (match_dup 0)
7683 (udiv:DI (match_dup 1) (match_dup 2)))
7685 (umod:DI (match_dup 1) (match_dup 2)))
7687 (clobber (reg:CC FLAGS_REG))])]
7690 (define_insn "udivmodsi4"
7691 [(set (match_operand:SI 0 "register_operand" "=a")
7692 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7693 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7694 (set (match_operand:SI 3 "register_operand" "=&d")
7695 (umod:SI (match_dup 1) (match_dup 2)))
7696 (clobber (reg:CC FLAGS_REG))]
7698 "xor{l}\t%3, %3\;div{l}\t%2"
7699 [(set_attr "type" "multi")
7700 (set_attr "length_immediate" "0")
7701 (set_attr "mode" "SI")])
7703 (define_insn "*udivmodsi4_noext"
7704 [(set (match_operand:SI 0 "register_operand" "=a")
7705 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7706 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7707 (set (match_operand:SI 3 "register_operand" "=d")
7708 (umod:SI (match_dup 1) (match_dup 2)))
7710 (clobber (reg:CC FLAGS_REG))]
7713 [(set_attr "type" "idiv")
7714 (set_attr "mode" "SI")])
7717 [(set (match_operand:SI 0 "register_operand" "")
7718 (udiv:SI (match_operand:SI 1 "register_operand" "")
7719 (match_operand:SI 2 "nonimmediate_operand" "")))
7720 (set (match_operand:SI 3 "register_operand" "")
7721 (umod:SI (match_dup 1) (match_dup 2)))
7722 (clobber (reg:CC FLAGS_REG))]
7724 [(set (match_dup 3) (const_int 0))
7725 (parallel [(set (match_dup 0)
7726 (udiv:SI (match_dup 1) (match_dup 2)))
7728 (umod:SI (match_dup 1) (match_dup 2)))
7730 (clobber (reg:CC FLAGS_REG))])]
7733 (define_expand "udivmodhi4"
7734 [(set (match_dup 4) (const_int 0))
7735 (parallel [(set (match_operand:HI 0 "register_operand" "")
7736 (udiv:HI (match_operand:HI 1 "register_operand" "")
7737 (match_operand:HI 2 "nonimmediate_operand" "")))
7738 (set (match_operand:HI 3 "register_operand" "")
7739 (umod:HI (match_dup 1) (match_dup 2)))
7741 (clobber (reg:CC FLAGS_REG))])]
7742 "TARGET_HIMODE_MATH"
7743 "operands[4] = gen_reg_rtx (HImode);")
7745 (define_insn "*udivmodhi_noext"
7746 [(set (match_operand:HI 0 "register_operand" "=a")
7747 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7748 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7749 (set (match_operand:HI 3 "register_operand" "=d")
7750 (umod:HI (match_dup 1) (match_dup 2)))
7751 (use (match_operand:HI 4 "register_operand" "3"))
7752 (clobber (reg:CC FLAGS_REG))]
7755 [(set_attr "type" "idiv")
7756 (set_attr "mode" "HI")])
7758 ;; We cannot use div/idiv for double division, because it causes
7759 ;; "division by zero" on the overflow and that's not what we expect
7760 ;; from truncate. Because true (non truncating) double division is
7761 ;; never generated, we can't create this insn anyway.
7764 ; [(set (match_operand:SI 0 "register_operand" "=a")
7766 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7768 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7769 ; (set (match_operand:SI 3 "register_operand" "=d")
7771 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7772 ; (clobber (reg:CC FLAGS_REG))]
7774 ; "div{l}\t{%2, %0|%0, %2}"
7775 ; [(set_attr "type" "idiv")])
7777 ;;- Logical AND instructions
7779 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7780 ;; Note that this excludes ah.
7782 (define_insn "*testdi_1_rex64"
7783 [(set (reg FLAGS_REG)
7785 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7786 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7788 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7789 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7791 test{l}\t{%k1, %k0|%k0, %k1}
7792 test{l}\t{%k1, %k0|%k0, %k1}
7793 test{q}\t{%1, %0|%0, %1}
7794 test{q}\t{%1, %0|%0, %1}
7795 test{q}\t{%1, %0|%0, %1}"
7796 [(set_attr "type" "test")
7797 (set_attr "modrm" "0,1,0,1,1")
7798 (set_attr "mode" "SI,SI,DI,DI,DI")
7799 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7801 (define_insn "testsi_1"
7802 [(set (reg FLAGS_REG)
7804 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7805 (match_operand:SI 1 "general_operand" "in,in,rin"))
7807 "ix86_match_ccmode (insn, CCNOmode)
7808 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7809 "test{l}\t{%1, %0|%0, %1}"
7810 [(set_attr "type" "test")
7811 (set_attr "modrm" "0,1,1")
7812 (set_attr "mode" "SI")
7813 (set_attr "pent_pair" "uv,np,uv")])
7815 (define_expand "testsi_ccno_1"
7816 [(set (reg:CCNO FLAGS_REG)
7818 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7819 (match_operand:SI 1 "nonmemory_operand" ""))
7824 (define_insn "*testhi_1"
7825 [(set (reg FLAGS_REG)
7826 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7827 (match_operand:HI 1 "general_operand" "n,n,rn"))
7829 "ix86_match_ccmode (insn, CCNOmode)
7830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7831 "test{w}\t{%1, %0|%0, %1}"
7832 [(set_attr "type" "test")
7833 (set_attr "modrm" "0,1,1")
7834 (set_attr "mode" "HI")
7835 (set_attr "pent_pair" "uv,np,uv")])
7837 (define_expand "testqi_ccz_1"
7838 [(set (reg:CCZ FLAGS_REG)
7839 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7840 (match_operand:QI 1 "nonmemory_operand" ""))
7845 (define_insn "*testqi_1_maybe_si"
7846 [(set (reg FLAGS_REG)
7849 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7850 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7852 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7853 && ix86_match_ccmode (insn,
7854 GET_CODE (operands[1]) == CONST_INT
7855 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7857 if (which_alternative == 3)
7859 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7860 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7861 return "test{l}\t{%1, %k0|%k0, %1}";
7863 return "test{b}\t{%1, %0|%0, %1}";
7865 [(set_attr "type" "test")
7866 (set_attr "modrm" "0,1,1,1")
7867 (set_attr "mode" "QI,QI,QI,SI")
7868 (set_attr "pent_pair" "uv,np,uv,np")])
7870 (define_insn "*testqi_1"
7871 [(set (reg FLAGS_REG)
7874 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7875 (match_operand:QI 1 "general_operand" "n,n,qn"))
7877 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7878 && ix86_match_ccmode (insn, CCNOmode)"
7879 "test{b}\t{%1, %0|%0, %1}"
7880 [(set_attr "type" "test")
7881 (set_attr "modrm" "0,1,1")
7882 (set_attr "mode" "QI")
7883 (set_attr "pent_pair" "uv,np,uv")])
7885 (define_expand "testqi_ext_ccno_0"
7886 [(set (reg:CCNO FLAGS_REG)
7890 (match_operand 0 "ext_register_operand" "")
7893 (match_operand 1 "const_int_operand" ""))
7898 (define_insn "*testqi_ext_0"
7899 [(set (reg FLAGS_REG)
7903 (match_operand 0 "ext_register_operand" "Q")
7906 (match_operand 1 "const_int_operand" "n"))
7908 "ix86_match_ccmode (insn, CCNOmode)"
7909 "test{b}\t{%1, %h0|%h0, %1}"
7910 [(set_attr "type" "test")
7911 (set_attr "mode" "QI")
7912 (set_attr "length_immediate" "1")
7913 (set_attr "pent_pair" "np")])
7915 (define_insn "*testqi_ext_1"
7916 [(set (reg FLAGS_REG)
7920 (match_operand 0 "ext_register_operand" "Q")
7924 (match_operand:QI 1 "general_operand" "Qm")))
7926 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7927 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7928 "test{b}\t{%1, %h0|%h0, %1}"
7929 [(set_attr "type" "test")
7930 (set_attr "mode" "QI")])
7932 (define_insn "*testqi_ext_1_rex64"
7933 [(set (reg FLAGS_REG)
7937 (match_operand 0 "ext_register_operand" "Q")
7941 (match_operand:QI 1 "register_operand" "Q")))
7943 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7944 "test{b}\t{%1, %h0|%h0, %1}"
7945 [(set_attr "type" "test")
7946 (set_attr "mode" "QI")])
7948 (define_insn "*testqi_ext_2"
7949 [(set (reg FLAGS_REG)
7953 (match_operand 0 "ext_register_operand" "Q")
7957 (match_operand 1 "ext_register_operand" "Q")
7961 "ix86_match_ccmode (insn, CCNOmode)"
7962 "test{b}\t{%h1, %h0|%h0, %h1}"
7963 [(set_attr "type" "test")
7964 (set_attr "mode" "QI")])
7966 ;; Combine likes to form bit extractions for some tests. Humor it.
7967 (define_insn "*testqi_ext_3"
7968 [(set (reg FLAGS_REG)
7969 (compare (zero_extract:SI
7970 (match_operand 0 "nonimmediate_operand" "rm")
7971 (match_operand:SI 1 "const_int_operand" "")
7972 (match_operand:SI 2 "const_int_operand" ""))
7974 "ix86_match_ccmode (insn, CCNOmode)
7975 && INTVAL (operands[1]) > 0
7976 && INTVAL (operands[2]) >= 0
7977 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7978 && (GET_MODE (operands[0]) == SImode
7979 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7980 || GET_MODE (operands[0]) == HImode
7981 || GET_MODE (operands[0]) == QImode)"
7984 (define_insn "*testqi_ext_3_rex64"
7985 [(set (reg FLAGS_REG)
7986 (compare (zero_extract:DI
7987 (match_operand 0 "nonimmediate_operand" "rm")
7988 (match_operand:DI 1 "const_int_operand" "")
7989 (match_operand:DI 2 "const_int_operand" ""))
7992 && ix86_match_ccmode (insn, CCNOmode)
7993 && INTVAL (operands[1]) > 0
7994 && INTVAL (operands[2]) >= 0
7995 /* Ensure that resulting mask is zero or sign extended operand. */
7996 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7997 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7998 && INTVAL (operands[1]) > 32))
7999 && (GET_MODE (operands[0]) == SImode
8000 || GET_MODE (operands[0]) == DImode
8001 || GET_MODE (operands[0]) == HImode
8002 || GET_MODE (operands[0]) == QImode)"
8006 [(set (match_operand 0 "flags_reg_operand" "")
8007 (match_operator 1 "compare_operator"
8009 (match_operand 2 "nonimmediate_operand" "")
8010 (match_operand 3 "const_int_operand" "")
8011 (match_operand 4 "const_int_operand" ""))
8013 "ix86_match_ccmode (insn, CCNOmode)"
8014 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8016 rtx val = operands[2];
8017 HOST_WIDE_INT len = INTVAL (operands[3]);
8018 HOST_WIDE_INT pos = INTVAL (operands[4]);
8020 enum machine_mode mode, submode;
8022 mode = GET_MODE (val);
8023 if (GET_CODE (val) == MEM)
8025 /* ??? Combine likes to put non-volatile mem extractions in QImode
8026 no matter the size of the test. So find a mode that works. */
8027 if (! MEM_VOLATILE_P (val))
8029 mode = smallest_mode_for_size (pos + len, MODE_INT);
8030 val = adjust_address (val, mode, 0);
8033 else if (GET_CODE (val) == SUBREG
8034 && (submode = GET_MODE (SUBREG_REG (val)),
8035 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8036 && pos + len <= GET_MODE_BITSIZE (submode))
8038 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8040 val = SUBREG_REG (val);
8042 else if (mode == HImode && pos + len <= 8)
8044 /* Small HImode tests can be converted to QImode. */
8046 val = gen_lowpart (QImode, val);
8049 if (len == HOST_BITS_PER_WIDE_INT)
8052 mask = ((HOST_WIDE_INT)1 << len) - 1;
8055 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8058 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8059 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8060 ;; this is relatively important trick.
8061 ;; Do the conversion only post-reload to avoid limiting of the register class
8064 [(set (match_operand 0 "flags_reg_operand" "")
8065 (match_operator 1 "compare_operator"
8066 [(and (match_operand 2 "register_operand" "")
8067 (match_operand 3 "const_int_operand" ""))
8070 && QI_REG_P (operands[2])
8071 && GET_MODE (operands[2]) != QImode
8072 && ((ix86_match_ccmode (insn, CCZmode)
8073 && !(INTVAL (operands[3]) & ~(255 << 8)))
8074 || (ix86_match_ccmode (insn, CCNOmode)
8075 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8078 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8081 "operands[2] = gen_lowpart (SImode, operands[2]);
8082 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8085 [(set (match_operand 0 "flags_reg_operand" "")
8086 (match_operator 1 "compare_operator"
8087 [(and (match_operand 2 "nonimmediate_operand" "")
8088 (match_operand 3 "const_int_operand" ""))
8091 && GET_MODE (operands[2]) != QImode
8092 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8093 && ((ix86_match_ccmode (insn, CCZmode)
8094 && !(INTVAL (operands[3]) & ~255))
8095 || (ix86_match_ccmode (insn, CCNOmode)
8096 && !(INTVAL (operands[3]) & ~127)))"
8098 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8100 "operands[2] = gen_lowpart (QImode, operands[2]);
8101 operands[3] = gen_lowpart (QImode, operands[3]);")
8104 ;; %%% This used to optimize known byte-wide and operations to memory,
8105 ;; and sometimes to QImode registers. If this is considered useful,
8106 ;; it should be done with splitters.
8108 (define_expand "anddi3"
8109 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8110 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8111 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8112 (clobber (reg:CC FLAGS_REG))]
8114 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8116 (define_insn "*anddi_1_rex64"
8117 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8118 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8119 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8120 (clobber (reg:CC FLAGS_REG))]
8121 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8123 switch (get_attr_type (insn))
8127 enum machine_mode mode;
8129 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8130 if (INTVAL (operands[2]) == 0xff)
8134 gcc_assert (INTVAL (operands[2]) == 0xffff);
8138 operands[1] = gen_lowpart (mode, operands[1]);
8140 return "movz{bq|x}\t{%1,%0|%0, %1}";
8142 return "movz{wq|x}\t{%1,%0|%0, %1}";
8146 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8147 if (get_attr_mode (insn) == MODE_SI)
8148 return "and{l}\t{%k2, %k0|%k0, %k2}";
8150 return "and{q}\t{%2, %0|%0, %2}";
8153 [(set_attr "type" "alu,alu,alu,imovx")
8154 (set_attr "length_immediate" "*,*,*,0")
8155 (set_attr "mode" "SI,DI,DI,DI")])
8157 (define_insn "*anddi_2"
8158 [(set (reg FLAGS_REG)
8159 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8160 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8162 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8163 (and:DI (match_dup 1) (match_dup 2)))]
8164 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8165 && ix86_binary_operator_ok (AND, DImode, operands)"
8167 and{l}\t{%k2, %k0|%k0, %k2}
8168 and{q}\t{%2, %0|%0, %2}
8169 and{q}\t{%2, %0|%0, %2}"
8170 [(set_attr "type" "alu")
8171 (set_attr "mode" "SI,DI,DI")])
8173 (define_expand "andsi3"
8174 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8175 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8176 (match_operand:SI 2 "general_operand" "")))
8177 (clobber (reg:CC FLAGS_REG))]
8179 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8181 (define_insn "*andsi_1"
8182 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8183 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8184 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8185 (clobber (reg:CC FLAGS_REG))]
8186 "ix86_binary_operator_ok (AND, SImode, operands)"
8188 switch (get_attr_type (insn))
8192 enum machine_mode mode;
8194 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8195 if (INTVAL (operands[2]) == 0xff)
8199 gcc_assert (INTVAL (operands[2]) == 0xffff);
8203 operands[1] = gen_lowpart (mode, operands[1]);
8205 return "movz{bl|x}\t{%1,%0|%0, %1}";
8207 return "movz{wl|x}\t{%1,%0|%0, %1}";
8211 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8212 return "and{l}\t{%2, %0|%0, %2}";
8215 [(set_attr "type" "alu,alu,imovx")
8216 (set_attr "length_immediate" "*,*,0")
8217 (set_attr "mode" "SI")])
8220 [(set (match_operand 0 "register_operand" "")
8222 (const_int -65536)))
8223 (clobber (reg:CC FLAGS_REG))]
8224 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8225 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8226 "operands[1] = gen_lowpart (HImode, operands[0]);")
8229 [(set (match_operand 0 "ext_register_operand" "")
8232 (clobber (reg:CC FLAGS_REG))]
8233 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8234 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8235 "operands[1] = gen_lowpart (QImode, operands[0]);")
8238 [(set (match_operand 0 "ext_register_operand" "")
8240 (const_int -65281)))
8241 (clobber (reg:CC FLAGS_REG))]
8242 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8243 [(parallel [(set (zero_extract:SI (match_dup 0)
8247 (zero_extract:SI (match_dup 0)
8250 (zero_extract:SI (match_dup 0)
8253 (clobber (reg:CC FLAGS_REG))])]
8254 "operands[0] = gen_lowpart (SImode, operands[0]);")
8256 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8257 (define_insn "*andsi_1_zext"
8258 [(set (match_operand:DI 0 "register_operand" "=r")
8260 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8261 (match_operand:SI 2 "general_operand" "rim"))))
8262 (clobber (reg:CC FLAGS_REG))]
8263 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8264 "and{l}\t{%2, %k0|%k0, %2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "mode" "SI")])
8268 (define_insn "*andsi_2"
8269 [(set (reg FLAGS_REG)
8270 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8271 (match_operand:SI 2 "general_operand" "rim,ri"))
8273 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8274 (and:SI (match_dup 1) (match_dup 2)))]
8275 "ix86_match_ccmode (insn, CCNOmode)
8276 && ix86_binary_operator_ok (AND, SImode, operands)"
8277 "and{l}\t{%2, %0|%0, %2}"
8278 [(set_attr "type" "alu")
8279 (set_attr "mode" "SI")])
8281 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8282 (define_insn "*andsi_2_zext"
8283 [(set (reg FLAGS_REG)
8284 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8285 (match_operand:SI 2 "general_operand" "rim"))
8287 (set (match_operand:DI 0 "register_operand" "=r")
8288 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8289 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8290 && ix86_binary_operator_ok (AND, SImode, operands)"
8291 "and{l}\t{%2, %k0|%k0, %2}"
8292 [(set_attr "type" "alu")
8293 (set_attr "mode" "SI")])
8295 (define_expand "andhi3"
8296 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8297 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8298 (match_operand:HI 2 "general_operand" "")))
8299 (clobber (reg:CC FLAGS_REG))]
8300 "TARGET_HIMODE_MATH"
8301 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8303 (define_insn "*andhi_1"
8304 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8305 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8306 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8307 (clobber (reg:CC FLAGS_REG))]
8308 "ix86_binary_operator_ok (AND, HImode, operands)"
8310 switch (get_attr_type (insn))
8313 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8314 gcc_assert (INTVAL (operands[2]) == 0xff);
8315 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8318 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8320 return "and{w}\t{%2, %0|%0, %2}";
8323 [(set_attr "type" "alu,alu,imovx")
8324 (set_attr "length_immediate" "*,*,0")
8325 (set_attr "mode" "HI,HI,SI")])
8327 (define_insn "*andhi_2"
8328 [(set (reg FLAGS_REG)
8329 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8330 (match_operand:HI 2 "general_operand" "rim,ri"))
8332 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8333 (and:HI (match_dup 1) (match_dup 2)))]
8334 "ix86_match_ccmode (insn, CCNOmode)
8335 && ix86_binary_operator_ok (AND, HImode, operands)"
8336 "and{w}\t{%2, %0|%0, %2}"
8337 [(set_attr "type" "alu")
8338 (set_attr "mode" "HI")])
8340 (define_expand "andqi3"
8341 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8342 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8343 (match_operand:QI 2 "general_operand" "")))
8344 (clobber (reg:CC FLAGS_REG))]
8345 "TARGET_QIMODE_MATH"
8346 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8348 ;; %%% Potential partial reg stall on alternative 2. What to do?
8349 (define_insn "*andqi_1"
8350 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8351 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8352 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8353 (clobber (reg:CC FLAGS_REG))]
8354 "ix86_binary_operator_ok (AND, QImode, operands)"
8356 and{b}\t{%2, %0|%0, %2}
8357 and{b}\t{%2, %0|%0, %2}
8358 and{l}\t{%k2, %k0|%k0, %k2}"
8359 [(set_attr "type" "alu")
8360 (set_attr "mode" "QI,QI,SI")])
8362 (define_insn "*andqi_1_slp"
8363 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8364 (and:QI (match_dup 0)
8365 (match_operand:QI 1 "general_operand" "qi,qmi")))
8366 (clobber (reg:CC FLAGS_REG))]
8367 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8368 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8369 "and{b}\t{%1, %0|%0, %1}"
8370 [(set_attr "type" "alu1")
8371 (set_attr "mode" "QI")])
8373 (define_insn "*andqi_2_maybe_si"
8374 [(set (reg FLAGS_REG)
8376 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8377 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8379 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8380 (and:QI (match_dup 1) (match_dup 2)))]
8381 "ix86_binary_operator_ok (AND, QImode, operands)
8382 && ix86_match_ccmode (insn,
8383 GET_CODE (operands[2]) == CONST_INT
8384 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8386 if (which_alternative == 2)
8388 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8389 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8390 return "and{l}\t{%2, %k0|%k0, %2}";
8392 return "and{b}\t{%2, %0|%0, %2}";
8394 [(set_attr "type" "alu")
8395 (set_attr "mode" "QI,QI,SI")])
8397 (define_insn "*andqi_2"
8398 [(set (reg FLAGS_REG)
8400 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8401 (match_operand:QI 2 "general_operand" "qim,qi"))
8403 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8404 (and:QI (match_dup 1) (match_dup 2)))]
8405 "ix86_match_ccmode (insn, CCNOmode)
8406 && ix86_binary_operator_ok (AND, QImode, operands)"
8407 "and{b}\t{%2, %0|%0, %2}"
8408 [(set_attr "type" "alu")
8409 (set_attr "mode" "QI")])
8411 (define_insn "*andqi_2_slp"
8412 [(set (reg FLAGS_REG)
8414 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8415 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8417 (set (strict_low_part (match_dup 0))
8418 (and:QI (match_dup 0) (match_dup 1)))]
8419 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8420 && ix86_match_ccmode (insn, CCNOmode)
8421 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8422 "and{b}\t{%1, %0|%0, %1}"
8423 [(set_attr "type" "alu1")
8424 (set_attr "mode" "QI")])
8426 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8427 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8428 ;; for a QImode operand, which of course failed.
8430 (define_insn "andqi_ext_0"
8431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8436 (match_operand 1 "ext_register_operand" "0")
8439 (match_operand 2 "const_int_operand" "n")))
8440 (clobber (reg:CC FLAGS_REG))]
8442 "and{b}\t{%2, %h0|%h0, %2}"
8443 [(set_attr "type" "alu")
8444 (set_attr "length_immediate" "1")
8445 (set_attr "mode" "QI")])
8447 ;; Generated by peephole translating test to and. This shows up
8448 ;; often in fp comparisons.
8450 (define_insn "*andqi_ext_0_cc"
8451 [(set (reg FLAGS_REG)
8455 (match_operand 1 "ext_register_operand" "0")
8458 (match_operand 2 "const_int_operand" "n"))
8460 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8469 "ix86_match_ccmode (insn, CCNOmode)"
8470 "and{b}\t{%2, %h0|%h0, %2}"
8471 [(set_attr "type" "alu")
8472 (set_attr "length_immediate" "1")
8473 (set_attr "mode" "QI")])
8475 (define_insn "*andqi_ext_1"
8476 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8481 (match_operand 1 "ext_register_operand" "0")
8485 (match_operand:QI 2 "general_operand" "Qm"))))
8486 (clobber (reg:CC FLAGS_REG))]
8488 "and{b}\t{%2, %h0|%h0, %2}"
8489 [(set_attr "type" "alu")
8490 (set_attr "length_immediate" "0")
8491 (set_attr "mode" "QI")])
8493 (define_insn "*andqi_ext_1_rex64"
8494 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8499 (match_operand 1 "ext_register_operand" "0")
8503 (match_operand 2 "ext_register_operand" "Q"))))
8504 (clobber (reg:CC FLAGS_REG))]
8506 "and{b}\t{%2, %h0|%h0, %2}"
8507 [(set_attr "type" "alu")
8508 (set_attr "length_immediate" "0")
8509 (set_attr "mode" "QI")])
8511 (define_insn "*andqi_ext_2"
8512 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8517 (match_operand 1 "ext_register_operand" "%0")
8521 (match_operand 2 "ext_register_operand" "Q")
8524 (clobber (reg:CC FLAGS_REG))]
8526 "and{b}\t{%h2, %h0|%h0, %h2}"
8527 [(set_attr "type" "alu")
8528 (set_attr "length_immediate" "0")
8529 (set_attr "mode" "QI")])
8531 ;; Convert wide AND instructions with immediate operand to shorter QImode
8532 ;; equivalents when possible.
8533 ;; Don't do the splitting with memory operands, since it introduces risk
8534 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8535 ;; for size, but that can (should?) be handled by generic code instead.
8537 [(set (match_operand 0 "register_operand" "")
8538 (and (match_operand 1 "register_operand" "")
8539 (match_operand 2 "const_int_operand" "")))
8540 (clobber (reg:CC FLAGS_REG))]
8542 && QI_REG_P (operands[0])
8543 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8544 && !(~INTVAL (operands[2]) & ~(255 << 8))
8545 && GET_MODE (operands[0]) != QImode"
8546 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8547 (and:SI (zero_extract:SI (match_dup 1)
8548 (const_int 8) (const_int 8))
8550 (clobber (reg:CC FLAGS_REG))])]
8551 "operands[0] = gen_lowpart (SImode, operands[0]);
8552 operands[1] = gen_lowpart (SImode, operands[1]);
8553 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8555 ;; Since AND can be encoded with sign extended immediate, this is only
8556 ;; profitable when 7th bit is not set.
8558 [(set (match_operand 0 "register_operand" "")
8559 (and (match_operand 1 "general_operand" "")
8560 (match_operand 2 "const_int_operand" "")))
8561 (clobber (reg:CC FLAGS_REG))]
8563 && ANY_QI_REG_P (operands[0])
8564 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8565 && !(~INTVAL (operands[2]) & ~255)
8566 && !(INTVAL (operands[2]) & 128)
8567 && GET_MODE (operands[0]) != QImode"
8568 [(parallel [(set (strict_low_part (match_dup 0))
8569 (and:QI (match_dup 1)
8571 (clobber (reg:CC FLAGS_REG))])]
8572 "operands[0] = gen_lowpart (QImode, operands[0]);
8573 operands[1] = gen_lowpart (QImode, operands[1]);
8574 operands[2] = gen_lowpart (QImode, operands[2]);")
8576 ;; Logical inclusive OR instructions
8578 ;; %%% This used to optimize known byte-wide and operations to memory.
8579 ;; If this is considered useful, it should be done with splitters.
8581 (define_expand "iordi3"
8582 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8583 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8584 (match_operand:DI 2 "x86_64_general_operand" "")))
8585 (clobber (reg:CC FLAGS_REG))]
8587 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8589 (define_insn "*iordi_1_rex64"
8590 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8591 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8592 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8593 (clobber (reg:CC FLAGS_REG))]
8595 && ix86_binary_operator_ok (IOR, DImode, operands)"
8596 "or{q}\t{%2, %0|%0, %2}"
8597 [(set_attr "type" "alu")
8598 (set_attr "mode" "DI")])
8600 (define_insn "*iordi_2_rex64"
8601 [(set (reg FLAGS_REG)
8602 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8603 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8605 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8606 (ior:DI (match_dup 1) (match_dup 2)))]
8608 && ix86_match_ccmode (insn, CCNOmode)
8609 && ix86_binary_operator_ok (IOR, DImode, operands)"
8610 "or{q}\t{%2, %0|%0, %2}"
8611 [(set_attr "type" "alu")
8612 (set_attr "mode" "DI")])
8614 (define_insn "*iordi_3_rex64"
8615 [(set (reg FLAGS_REG)
8616 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8617 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8619 (clobber (match_scratch:DI 0 "=r"))]
8621 && ix86_match_ccmode (insn, CCNOmode)
8622 && ix86_binary_operator_ok (IOR, DImode, operands)"
8623 "or{q}\t{%2, %0|%0, %2}"
8624 [(set_attr "type" "alu")
8625 (set_attr "mode" "DI")])
8628 (define_expand "iorsi3"
8629 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8630 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8631 (match_operand:SI 2 "general_operand" "")))
8632 (clobber (reg:CC FLAGS_REG))]
8634 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8636 (define_insn "*iorsi_1"
8637 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8638 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8639 (match_operand:SI 2 "general_operand" "ri,rmi")))
8640 (clobber (reg:CC FLAGS_REG))]
8641 "ix86_binary_operator_ok (IOR, SImode, operands)"
8642 "or{l}\t{%2, %0|%0, %2}"
8643 [(set_attr "type" "alu")
8644 (set_attr "mode" "SI")])
8646 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8647 (define_insn "*iorsi_1_zext"
8648 [(set (match_operand:DI 0 "register_operand" "=rm")
8650 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8651 (match_operand:SI 2 "general_operand" "rim"))))
8652 (clobber (reg:CC FLAGS_REG))]
8653 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8654 "or{l}\t{%2, %k0|%k0, %2}"
8655 [(set_attr "type" "alu")
8656 (set_attr "mode" "SI")])
8658 (define_insn "*iorsi_1_zext_imm"
8659 [(set (match_operand:DI 0 "register_operand" "=rm")
8660 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8661 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8662 (clobber (reg:CC FLAGS_REG))]
8664 "or{l}\t{%2, %k0|%k0, %2}"
8665 [(set_attr "type" "alu")
8666 (set_attr "mode" "SI")])
8668 (define_insn "*iorsi_2"
8669 [(set (reg FLAGS_REG)
8670 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8671 (match_operand:SI 2 "general_operand" "rim,ri"))
8673 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8674 (ior:SI (match_dup 1) (match_dup 2)))]
8675 "ix86_match_ccmode (insn, CCNOmode)
8676 && ix86_binary_operator_ok (IOR, SImode, operands)"
8677 "or{l}\t{%2, %0|%0, %2}"
8678 [(set_attr "type" "alu")
8679 (set_attr "mode" "SI")])
8681 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8682 ;; ??? Special case for immediate operand is missing - it is tricky.
8683 (define_insn "*iorsi_2_zext"
8684 [(set (reg FLAGS_REG)
8685 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8686 (match_operand:SI 2 "general_operand" "rim"))
8688 (set (match_operand:DI 0 "register_operand" "=r")
8689 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8690 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8691 && ix86_binary_operator_ok (IOR, SImode, operands)"
8692 "or{l}\t{%2, %k0|%k0, %2}"
8693 [(set_attr "type" "alu")
8694 (set_attr "mode" "SI")])
8696 (define_insn "*iorsi_2_zext_imm"
8697 [(set (reg FLAGS_REG)
8698 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8699 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8701 (set (match_operand:DI 0 "register_operand" "=r")
8702 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8703 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8704 && ix86_binary_operator_ok (IOR, SImode, operands)"
8705 "or{l}\t{%2, %k0|%k0, %2}"
8706 [(set_attr "type" "alu")
8707 (set_attr "mode" "SI")])
8709 (define_insn "*iorsi_3"
8710 [(set (reg FLAGS_REG)
8711 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8712 (match_operand:SI 2 "general_operand" "rim"))
8714 (clobber (match_scratch:SI 0 "=r"))]
8715 "ix86_match_ccmode (insn, CCNOmode)
8716 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8717 "or{l}\t{%2, %0|%0, %2}"
8718 [(set_attr "type" "alu")
8719 (set_attr "mode" "SI")])
8721 (define_expand "iorhi3"
8722 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8723 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8724 (match_operand:HI 2 "general_operand" "")))
8725 (clobber (reg:CC FLAGS_REG))]
8726 "TARGET_HIMODE_MATH"
8727 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8729 (define_insn "*iorhi_1"
8730 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8731 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8732 (match_operand:HI 2 "general_operand" "rmi,ri")))
8733 (clobber (reg:CC FLAGS_REG))]
8734 "ix86_binary_operator_ok (IOR, HImode, operands)"
8735 "or{w}\t{%2, %0|%0, %2}"
8736 [(set_attr "type" "alu")
8737 (set_attr "mode" "HI")])
8739 (define_insn "*iorhi_2"
8740 [(set (reg FLAGS_REG)
8741 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8742 (match_operand:HI 2 "general_operand" "rim,ri"))
8744 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8745 (ior:HI (match_dup 1) (match_dup 2)))]
8746 "ix86_match_ccmode (insn, CCNOmode)
8747 && ix86_binary_operator_ok (IOR, HImode, operands)"
8748 "or{w}\t{%2, %0|%0, %2}"
8749 [(set_attr "type" "alu")
8750 (set_attr "mode" "HI")])
8752 (define_insn "*iorhi_3"
8753 [(set (reg FLAGS_REG)
8754 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8755 (match_operand:HI 2 "general_operand" "rim"))
8757 (clobber (match_scratch:HI 0 "=r"))]
8758 "ix86_match_ccmode (insn, CCNOmode)
8759 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760 "or{w}\t{%2, %0|%0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "mode" "HI")])
8764 (define_expand "iorqi3"
8765 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8766 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8767 (match_operand:QI 2 "general_operand" "")))
8768 (clobber (reg:CC FLAGS_REG))]
8769 "TARGET_QIMODE_MATH"
8770 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8772 ;; %%% Potential partial reg stall on alternative 2. What to do?
8773 (define_insn "*iorqi_1"
8774 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8775 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8776 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8777 (clobber (reg:CC FLAGS_REG))]
8778 "ix86_binary_operator_ok (IOR, QImode, operands)"
8780 or{b}\t{%2, %0|%0, %2}
8781 or{b}\t{%2, %0|%0, %2}
8782 or{l}\t{%k2, %k0|%k0, %k2}"
8783 [(set_attr "type" "alu")
8784 (set_attr "mode" "QI,QI,SI")])
8786 (define_insn "*iorqi_1_slp"
8787 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8788 (ior:QI (match_dup 0)
8789 (match_operand:QI 1 "general_operand" "qmi,qi")))
8790 (clobber (reg:CC FLAGS_REG))]
8791 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8792 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8793 "or{b}\t{%1, %0|%0, %1}"
8794 [(set_attr "type" "alu1")
8795 (set_attr "mode" "QI")])
8797 (define_insn "*iorqi_2"
8798 [(set (reg FLAGS_REG)
8799 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8800 (match_operand:QI 2 "general_operand" "qim,qi"))
8802 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8803 (ior:QI (match_dup 1) (match_dup 2)))]
8804 "ix86_match_ccmode (insn, CCNOmode)
8805 && ix86_binary_operator_ok (IOR, QImode, operands)"
8806 "or{b}\t{%2, %0|%0, %2}"
8807 [(set_attr "type" "alu")
8808 (set_attr "mode" "QI")])
8810 (define_insn "*iorqi_2_slp"
8811 [(set (reg FLAGS_REG)
8812 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8813 (match_operand:QI 1 "general_operand" "qim,qi"))
8815 (set (strict_low_part (match_dup 0))
8816 (ior:QI (match_dup 0) (match_dup 1)))]
8817 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8818 && ix86_match_ccmode (insn, CCNOmode)
8819 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8820 "or{b}\t{%1, %0|%0, %1}"
8821 [(set_attr "type" "alu1")
8822 (set_attr "mode" "QI")])
8824 (define_insn "*iorqi_3"
8825 [(set (reg FLAGS_REG)
8826 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8827 (match_operand:QI 2 "general_operand" "qim"))
8829 (clobber (match_scratch:QI 0 "=q"))]
8830 "ix86_match_ccmode (insn, CCNOmode)
8831 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8832 "or{b}\t{%2, %0|%0, %2}"
8833 [(set_attr "type" "alu")
8834 (set_attr "mode" "QI")])
8836 (define_insn "iorqi_ext_0"
8837 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8842 (match_operand 1 "ext_register_operand" "0")
8845 (match_operand 2 "const_int_operand" "n")))
8846 (clobber (reg:CC FLAGS_REG))]
8847 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8848 "or{b}\t{%2, %h0|%h0, %2}"
8849 [(set_attr "type" "alu")
8850 (set_attr "length_immediate" "1")
8851 (set_attr "mode" "QI")])
8853 (define_insn "*iorqi_ext_1"
8854 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8859 (match_operand 1 "ext_register_operand" "0")
8863 (match_operand:QI 2 "general_operand" "Qm"))))
8864 (clobber (reg:CC FLAGS_REG))]
8866 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8867 "or{b}\t{%2, %h0|%h0, %2}"
8868 [(set_attr "type" "alu")
8869 (set_attr "length_immediate" "0")
8870 (set_attr "mode" "QI")])
8872 (define_insn "*iorqi_ext_1_rex64"
8873 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8878 (match_operand 1 "ext_register_operand" "0")
8882 (match_operand 2 "ext_register_operand" "Q"))))
8883 (clobber (reg:CC FLAGS_REG))]
8885 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8886 "or{b}\t{%2, %h0|%h0, %2}"
8887 [(set_attr "type" "alu")
8888 (set_attr "length_immediate" "0")
8889 (set_attr "mode" "QI")])
8891 (define_insn "*iorqi_ext_2"
8892 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8896 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8899 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8902 (clobber (reg:CC FLAGS_REG))]
8903 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8904 "ior{b}\t{%h2, %h0|%h0, %h2}"
8905 [(set_attr "type" "alu")
8906 (set_attr "length_immediate" "0")
8907 (set_attr "mode" "QI")])
8910 [(set (match_operand 0 "register_operand" "")
8911 (ior (match_operand 1 "register_operand" "")
8912 (match_operand 2 "const_int_operand" "")))
8913 (clobber (reg:CC FLAGS_REG))]
8915 && QI_REG_P (operands[0])
8916 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8917 && !(INTVAL (operands[2]) & ~(255 << 8))
8918 && GET_MODE (operands[0]) != QImode"
8919 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8920 (ior:SI (zero_extract:SI (match_dup 1)
8921 (const_int 8) (const_int 8))
8923 (clobber (reg:CC FLAGS_REG))])]
8924 "operands[0] = gen_lowpart (SImode, operands[0]);
8925 operands[1] = gen_lowpart (SImode, operands[1]);
8926 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8928 ;; Since OR can be encoded with sign extended immediate, this is only
8929 ;; profitable when 7th bit is set.
8931 [(set (match_operand 0 "register_operand" "")
8932 (ior (match_operand 1 "general_operand" "")
8933 (match_operand 2 "const_int_operand" "")))
8934 (clobber (reg:CC FLAGS_REG))]
8936 && ANY_QI_REG_P (operands[0])
8937 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8938 && !(INTVAL (operands[2]) & ~255)
8939 && (INTVAL (operands[2]) & 128)
8940 && GET_MODE (operands[0]) != QImode"
8941 [(parallel [(set (strict_low_part (match_dup 0))
8942 (ior:QI (match_dup 1)
8944 (clobber (reg:CC FLAGS_REG))])]
8945 "operands[0] = gen_lowpart (QImode, operands[0]);
8946 operands[1] = gen_lowpart (QImode, operands[1]);
8947 operands[2] = gen_lowpart (QImode, operands[2]);")
8949 ;; Logical XOR instructions
8951 ;; %%% This used to optimize known byte-wide and operations to memory.
8952 ;; If this is considered useful, it should be done with splitters.
8954 (define_expand "xordi3"
8955 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8956 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8957 (match_operand:DI 2 "x86_64_general_operand" "")))
8958 (clobber (reg:CC FLAGS_REG))]
8960 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8962 (define_insn "*xordi_1_rex64"
8963 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8964 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8965 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8966 (clobber (reg:CC FLAGS_REG))]
8968 && ix86_binary_operator_ok (XOR, DImode, operands)"
8970 xor{q}\t{%2, %0|%0, %2}
8971 xor{q}\t{%2, %0|%0, %2}"
8972 [(set_attr "type" "alu")
8973 (set_attr "mode" "DI,DI")])
8975 (define_insn "*xordi_2_rex64"
8976 [(set (reg FLAGS_REG)
8977 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8978 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8980 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8981 (xor:DI (match_dup 1) (match_dup 2)))]
8983 && ix86_match_ccmode (insn, CCNOmode)
8984 && ix86_binary_operator_ok (XOR, DImode, operands)"
8986 xor{q}\t{%2, %0|%0, %2}
8987 xor{q}\t{%2, %0|%0, %2}"
8988 [(set_attr "type" "alu")
8989 (set_attr "mode" "DI,DI")])
8991 (define_insn "*xordi_3_rex64"
8992 [(set (reg FLAGS_REG)
8993 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8994 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8996 (clobber (match_scratch:DI 0 "=r"))]
8998 && ix86_match_ccmode (insn, CCNOmode)
8999 && ix86_binary_operator_ok (XOR, DImode, operands)"
9000 "xor{q}\t{%2, %0|%0, %2}"
9001 [(set_attr "type" "alu")
9002 (set_attr "mode" "DI")])
9004 (define_expand "xorsi3"
9005 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9006 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9007 (match_operand:SI 2 "general_operand" "")))
9008 (clobber (reg:CC FLAGS_REG))]
9010 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9012 (define_insn "*xorsi_1"
9013 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9014 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9015 (match_operand:SI 2 "general_operand" "ri,rm")))
9016 (clobber (reg:CC FLAGS_REG))]
9017 "ix86_binary_operator_ok (XOR, SImode, operands)"
9018 "xor{l}\t{%2, %0|%0, %2}"
9019 [(set_attr "type" "alu")
9020 (set_attr "mode" "SI")])
9022 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9023 ;; Add speccase for immediates
9024 (define_insn "*xorsi_1_zext"
9025 [(set (match_operand:DI 0 "register_operand" "=r")
9027 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9028 (match_operand:SI 2 "general_operand" "rim"))))
9029 (clobber (reg:CC FLAGS_REG))]
9030 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9031 "xor{l}\t{%2, %k0|%k0, %2}"
9032 [(set_attr "type" "alu")
9033 (set_attr "mode" "SI")])
9035 (define_insn "*xorsi_1_zext_imm"
9036 [(set (match_operand:DI 0 "register_operand" "=r")
9037 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9038 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9039 (clobber (reg:CC FLAGS_REG))]
9040 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9041 "xor{l}\t{%2, %k0|%k0, %2}"
9042 [(set_attr "type" "alu")
9043 (set_attr "mode" "SI")])
9045 (define_insn "*xorsi_2"
9046 [(set (reg FLAGS_REG)
9047 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9048 (match_operand:SI 2 "general_operand" "rim,ri"))
9050 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9051 (xor:SI (match_dup 1) (match_dup 2)))]
9052 "ix86_match_ccmode (insn, CCNOmode)
9053 && ix86_binary_operator_ok (XOR, SImode, operands)"
9054 "xor{l}\t{%2, %0|%0, %2}"
9055 [(set_attr "type" "alu")
9056 (set_attr "mode" "SI")])
9058 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9059 ;; ??? Special case for immediate operand is missing - it is tricky.
9060 (define_insn "*xorsi_2_zext"
9061 [(set (reg FLAGS_REG)
9062 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9063 (match_operand:SI 2 "general_operand" "rim"))
9065 (set (match_operand:DI 0 "register_operand" "=r")
9066 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9067 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9068 && ix86_binary_operator_ok (XOR, SImode, operands)"
9069 "xor{l}\t{%2, %k0|%k0, %2}"
9070 [(set_attr "type" "alu")
9071 (set_attr "mode" "SI")])
9073 (define_insn "*xorsi_2_zext_imm"
9074 [(set (reg FLAGS_REG)
9075 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9076 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9078 (set (match_operand:DI 0 "register_operand" "=r")
9079 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9080 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9081 && ix86_binary_operator_ok (XOR, SImode, operands)"
9082 "xor{l}\t{%2, %k0|%k0, %2}"
9083 [(set_attr "type" "alu")
9084 (set_attr "mode" "SI")])
9086 (define_insn "*xorsi_3"
9087 [(set (reg FLAGS_REG)
9088 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9089 (match_operand:SI 2 "general_operand" "rim"))
9091 (clobber (match_scratch:SI 0 "=r"))]
9092 "ix86_match_ccmode (insn, CCNOmode)
9093 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9094 "xor{l}\t{%2, %0|%0, %2}"
9095 [(set_attr "type" "alu")
9096 (set_attr "mode" "SI")])
9098 (define_expand "xorhi3"
9099 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9100 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9101 (match_operand:HI 2 "general_operand" "")))
9102 (clobber (reg:CC FLAGS_REG))]
9103 "TARGET_HIMODE_MATH"
9104 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9106 (define_insn "*xorhi_1"
9107 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9108 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9109 (match_operand:HI 2 "general_operand" "rmi,ri")))
9110 (clobber (reg:CC FLAGS_REG))]
9111 "ix86_binary_operator_ok (XOR, HImode, operands)"
9112 "xor{w}\t{%2, %0|%0, %2}"
9113 [(set_attr "type" "alu")
9114 (set_attr "mode" "HI")])
9116 (define_insn "*xorhi_2"
9117 [(set (reg FLAGS_REG)
9118 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9119 (match_operand:HI 2 "general_operand" "rim,ri"))
9121 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9122 (xor:HI (match_dup 1) (match_dup 2)))]
9123 "ix86_match_ccmode (insn, CCNOmode)
9124 && ix86_binary_operator_ok (XOR, HImode, operands)"
9125 "xor{w}\t{%2, %0|%0, %2}"
9126 [(set_attr "type" "alu")
9127 (set_attr "mode" "HI")])
9129 (define_insn "*xorhi_3"
9130 [(set (reg FLAGS_REG)
9131 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9132 (match_operand:HI 2 "general_operand" "rim"))
9134 (clobber (match_scratch:HI 0 "=r"))]
9135 "ix86_match_ccmode (insn, CCNOmode)
9136 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9137 "xor{w}\t{%2, %0|%0, %2}"
9138 [(set_attr "type" "alu")
9139 (set_attr "mode" "HI")])
9141 (define_expand "xorqi3"
9142 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9143 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9144 (match_operand:QI 2 "general_operand" "")))
9145 (clobber (reg:CC FLAGS_REG))]
9146 "TARGET_QIMODE_MATH"
9147 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9149 ;; %%% Potential partial reg stall on alternative 2. What to do?
9150 (define_insn "*xorqi_1"
9151 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9152 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9153 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9154 (clobber (reg:CC FLAGS_REG))]
9155 "ix86_binary_operator_ok (XOR, QImode, operands)"
9157 xor{b}\t{%2, %0|%0, %2}
9158 xor{b}\t{%2, %0|%0, %2}
9159 xor{l}\t{%k2, %k0|%k0, %k2}"
9160 [(set_attr "type" "alu")
9161 (set_attr "mode" "QI,QI,SI")])
9163 (define_insn "*xorqi_1_slp"
9164 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9165 (xor:QI (match_dup 0)
9166 (match_operand:QI 1 "general_operand" "qi,qmi")))
9167 (clobber (reg:CC FLAGS_REG))]
9168 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9169 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9170 "xor{b}\t{%1, %0|%0, %1}"
9171 [(set_attr "type" "alu1")
9172 (set_attr "mode" "QI")])
9174 (define_insn "xorqi_ext_0"
9175 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9180 (match_operand 1 "ext_register_operand" "0")
9183 (match_operand 2 "const_int_operand" "n")))
9184 (clobber (reg:CC FLAGS_REG))]
9185 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9186 "xor{b}\t{%2, %h0|%h0, %2}"
9187 [(set_attr "type" "alu")
9188 (set_attr "length_immediate" "1")
9189 (set_attr "mode" "QI")])
9191 (define_insn "*xorqi_ext_1"
9192 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9197 (match_operand 1 "ext_register_operand" "0")
9201 (match_operand:QI 2 "general_operand" "Qm"))))
9202 (clobber (reg:CC FLAGS_REG))]
9204 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9205 "xor{b}\t{%2, %h0|%h0, %2}"
9206 [(set_attr "type" "alu")
9207 (set_attr "length_immediate" "0")
9208 (set_attr "mode" "QI")])
9210 (define_insn "*xorqi_ext_1_rex64"
9211 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9216 (match_operand 1 "ext_register_operand" "0")
9220 (match_operand 2 "ext_register_operand" "Q"))))
9221 (clobber (reg:CC FLAGS_REG))]
9223 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9224 "xor{b}\t{%2, %h0|%h0, %2}"
9225 [(set_attr "type" "alu")
9226 (set_attr "length_immediate" "0")
9227 (set_attr "mode" "QI")])
9229 (define_insn "*xorqi_ext_2"
9230 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9234 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9237 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9240 (clobber (reg:CC FLAGS_REG))]
9241 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9242 "xor{b}\t{%h2, %h0|%h0, %h2}"
9243 [(set_attr "type" "alu")
9244 (set_attr "length_immediate" "0")
9245 (set_attr "mode" "QI")])
9247 (define_insn "*xorqi_cc_1"
9248 [(set (reg FLAGS_REG)
9250 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9251 (match_operand:QI 2 "general_operand" "qim,qi"))
9253 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9254 (xor:QI (match_dup 1) (match_dup 2)))]
9255 "ix86_match_ccmode (insn, CCNOmode)
9256 && ix86_binary_operator_ok (XOR, QImode, operands)"
9257 "xor{b}\t{%2, %0|%0, %2}"
9258 [(set_attr "type" "alu")
9259 (set_attr "mode" "QI")])
9261 (define_insn "*xorqi_2_slp"
9262 [(set (reg FLAGS_REG)
9263 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9264 (match_operand:QI 1 "general_operand" "qim,qi"))
9266 (set (strict_low_part (match_dup 0))
9267 (xor:QI (match_dup 0) (match_dup 1)))]
9268 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9269 && ix86_match_ccmode (insn, CCNOmode)
9270 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9271 "xor{b}\t{%1, %0|%0, %1}"
9272 [(set_attr "type" "alu1")
9273 (set_attr "mode" "QI")])
9275 (define_insn "*xorqi_cc_2"
9276 [(set (reg FLAGS_REG)
9278 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9279 (match_operand:QI 2 "general_operand" "qim"))
9281 (clobber (match_scratch:QI 0 "=q"))]
9282 "ix86_match_ccmode (insn, CCNOmode)
9283 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9284 "xor{b}\t{%2, %0|%0, %2}"
9285 [(set_attr "type" "alu")
9286 (set_attr "mode" "QI")])
9288 (define_insn "*xorqi_cc_ext_1"
9289 [(set (reg FLAGS_REG)
9293 (match_operand 1 "ext_register_operand" "0")
9296 (match_operand:QI 2 "general_operand" "qmn"))
9298 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9302 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9304 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9305 "xor{b}\t{%2, %h0|%h0, %2}"
9306 [(set_attr "type" "alu")
9307 (set_attr "mode" "QI")])
9309 (define_insn "*xorqi_cc_ext_1_rex64"
9310 [(set (reg FLAGS_REG)
9314 (match_operand 1 "ext_register_operand" "0")
9317 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9319 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9323 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9325 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9326 "xor{b}\t{%2, %h0|%h0, %2}"
9327 [(set_attr "type" "alu")
9328 (set_attr "mode" "QI")])
9330 (define_expand "xorqi_cc_ext_1"
9332 (set (reg:CCNO FLAGS_REG)
9336 (match_operand 1 "ext_register_operand" "")
9339 (match_operand:QI 2 "general_operand" ""))
9341 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9345 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9351 [(set (match_operand 0 "register_operand" "")
9352 (xor (match_operand 1 "register_operand" "")
9353 (match_operand 2 "const_int_operand" "")))
9354 (clobber (reg:CC FLAGS_REG))]
9356 && QI_REG_P (operands[0])
9357 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9358 && !(INTVAL (operands[2]) & ~(255 << 8))
9359 && GET_MODE (operands[0]) != QImode"
9360 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9361 (xor:SI (zero_extract:SI (match_dup 1)
9362 (const_int 8) (const_int 8))
9364 (clobber (reg:CC FLAGS_REG))])]
9365 "operands[0] = gen_lowpart (SImode, operands[0]);
9366 operands[1] = gen_lowpart (SImode, operands[1]);
9367 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9369 ;; Since XOR can be encoded with sign extended immediate, this is only
9370 ;; profitable when 7th bit is set.
9372 [(set (match_operand 0 "register_operand" "")
9373 (xor (match_operand 1 "general_operand" "")
9374 (match_operand 2 "const_int_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))]
9377 && ANY_QI_REG_P (operands[0])
9378 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9379 && !(INTVAL (operands[2]) & ~255)
9380 && (INTVAL (operands[2]) & 128)
9381 && GET_MODE (operands[0]) != QImode"
9382 [(parallel [(set (strict_low_part (match_dup 0))
9383 (xor:QI (match_dup 1)
9385 (clobber (reg:CC FLAGS_REG))])]
9386 "operands[0] = gen_lowpart (QImode, operands[0]);
9387 operands[1] = gen_lowpart (QImode, operands[1]);
9388 operands[2] = gen_lowpart (QImode, operands[2]);")
9390 ;; Negation instructions
9392 (define_expand "negti2"
9393 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9394 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9395 (clobber (reg:CC FLAGS_REG))])]
9397 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9399 (define_insn "*negti2_1"
9400 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9401 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9402 (clobber (reg:CC FLAGS_REG))]
9404 && ix86_unary_operator_ok (NEG, TImode, operands)"
9408 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9409 (neg:TI (match_operand:TI 1 "general_operand" "")))
9410 (clobber (reg:CC FLAGS_REG))]
9411 "TARGET_64BIT && reload_completed"
9413 [(set (reg:CCZ FLAGS_REG)
9414 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9415 (set (match_dup 0) (neg:DI (match_dup 2)))])
9418 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9421 (clobber (reg:CC FLAGS_REG))])
9424 (neg:DI (match_dup 1)))
9425 (clobber (reg:CC FLAGS_REG))])]
9426 "split_ti (operands+1, 1, operands+2, operands+3);
9427 split_ti (operands+0, 1, operands+0, operands+1);")
9429 (define_expand "negdi2"
9430 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9431 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9432 (clobber (reg:CC FLAGS_REG))])]
9434 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9436 (define_insn "*negdi2_1"
9437 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9438 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9439 (clobber (reg:CC FLAGS_REG))]
9441 && ix86_unary_operator_ok (NEG, DImode, operands)"
9445 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9446 (neg:DI (match_operand:DI 1 "general_operand" "")))
9447 (clobber (reg:CC FLAGS_REG))]
9448 "!TARGET_64BIT && reload_completed"
9450 [(set (reg:CCZ FLAGS_REG)
9451 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9452 (set (match_dup 0) (neg:SI (match_dup 2)))])
9455 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9458 (clobber (reg:CC FLAGS_REG))])
9461 (neg:SI (match_dup 1)))
9462 (clobber (reg:CC FLAGS_REG))])]
9463 "split_di (operands+1, 1, operands+2, operands+3);
9464 split_di (operands+0, 1, operands+0, operands+1);")
9466 (define_insn "*negdi2_1_rex64"
9467 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9468 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9469 (clobber (reg:CC FLAGS_REG))]
9470 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9472 [(set_attr "type" "negnot")
9473 (set_attr "mode" "DI")])
9475 ;; The problem with neg is that it does not perform (compare x 0),
9476 ;; it really performs (compare 0 x), which leaves us with the zero
9477 ;; flag being the only useful item.
9479 (define_insn "*negdi2_cmpz_rex64"
9480 [(set (reg:CCZ FLAGS_REG)
9481 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9483 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9484 (neg:DI (match_dup 1)))]
9485 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9487 [(set_attr "type" "negnot")
9488 (set_attr "mode" "DI")])
9491 (define_expand "negsi2"
9492 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9493 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9494 (clobber (reg:CC FLAGS_REG))])]
9496 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9498 (define_insn "*negsi2_1"
9499 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9500 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9501 (clobber (reg:CC FLAGS_REG))]
9502 "ix86_unary_operator_ok (NEG, SImode, operands)"
9504 [(set_attr "type" "negnot")
9505 (set_attr "mode" "SI")])
9507 ;; Combine is quite creative about this pattern.
9508 (define_insn "*negsi2_1_zext"
9509 [(set (match_operand:DI 0 "register_operand" "=r")
9510 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9513 (clobber (reg:CC FLAGS_REG))]
9514 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9516 [(set_attr "type" "negnot")
9517 (set_attr "mode" "SI")])
9519 ;; The problem with neg is that it does not perform (compare x 0),
9520 ;; it really performs (compare 0 x), which leaves us with the zero
9521 ;; flag being the only useful item.
9523 (define_insn "*negsi2_cmpz"
9524 [(set (reg:CCZ FLAGS_REG)
9525 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9527 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9528 (neg:SI (match_dup 1)))]
9529 "ix86_unary_operator_ok (NEG, SImode, operands)"
9531 [(set_attr "type" "negnot")
9532 (set_attr "mode" "SI")])
9534 (define_insn "*negsi2_cmpz_zext"
9535 [(set (reg:CCZ FLAGS_REG)
9536 (compare:CCZ (lshiftrt:DI
9538 (match_operand:DI 1 "register_operand" "0")
9542 (set (match_operand:DI 0 "register_operand" "=r")
9543 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9546 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9548 [(set_attr "type" "negnot")
9549 (set_attr "mode" "SI")])
9551 (define_expand "neghi2"
9552 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9553 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9554 (clobber (reg:CC FLAGS_REG))])]
9555 "TARGET_HIMODE_MATH"
9556 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9558 (define_insn "*neghi2_1"
9559 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9560 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9561 (clobber (reg:CC FLAGS_REG))]
9562 "ix86_unary_operator_ok (NEG, HImode, operands)"
9564 [(set_attr "type" "negnot")
9565 (set_attr "mode" "HI")])
9567 (define_insn "*neghi2_cmpz"
9568 [(set (reg:CCZ FLAGS_REG)
9569 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9571 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9572 (neg:HI (match_dup 1)))]
9573 "ix86_unary_operator_ok (NEG, HImode, operands)"
9575 [(set_attr "type" "negnot")
9576 (set_attr "mode" "HI")])
9578 (define_expand "negqi2"
9579 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9580 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9581 (clobber (reg:CC FLAGS_REG))])]
9582 "TARGET_QIMODE_MATH"
9583 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9585 (define_insn "*negqi2_1"
9586 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9587 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9588 (clobber (reg:CC FLAGS_REG))]
9589 "ix86_unary_operator_ok (NEG, QImode, operands)"
9591 [(set_attr "type" "negnot")
9592 (set_attr "mode" "QI")])
9594 (define_insn "*negqi2_cmpz"
9595 [(set (reg:CCZ FLAGS_REG)
9596 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9598 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9599 (neg:QI (match_dup 1)))]
9600 "ix86_unary_operator_ok (NEG, QImode, operands)"
9602 [(set_attr "type" "negnot")
9603 (set_attr "mode" "QI")])
9605 ;; Changing of sign for FP values is doable using integer unit too.
9607 (define_expand "negsf2"
9608 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9609 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9610 "TARGET_80387 || TARGET_SSE_MATH"
9611 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9613 (define_expand "abssf2"
9614 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9615 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9616 "TARGET_80387 || TARGET_SSE_MATH"
9617 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9619 (define_insn "*absnegsf2_mixed"
9620 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9621 (match_operator:SF 3 "absneg_operator"
9622 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9623 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9624 (clobber (reg:CC FLAGS_REG))]
9625 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9626 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9629 (define_insn "*absnegsf2_sse"
9630 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9631 (match_operator:SF 3 "absneg_operator"
9632 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9633 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9634 (clobber (reg:CC FLAGS_REG))]
9636 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9639 (define_insn "*absnegsf2_i387"
9640 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9641 (match_operator:SF 3 "absneg_operator"
9642 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9643 (use (match_operand 2 "" ""))
9644 (clobber (reg:CC FLAGS_REG))]
9645 "TARGET_80387 && !TARGET_SSE_MATH
9646 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9649 (define_expand "copysignsf3"
9650 [(match_operand:SF 0 "register_operand" "")
9651 (match_operand:SF 1 "nonmemory_operand" "")
9652 (match_operand:SF 2 "register_operand" "")]
9655 ix86_expand_copysign (operands);
9659 (define_insn_and_split "copysignsf3_const"
9660 [(set (match_operand:SF 0 "register_operand" "=x")
9662 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9663 (match_operand:SF 2 "register_operand" "0")
9664 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9668 "&& reload_completed"
9671 ix86_split_copysign_const (operands);
9675 (define_insn "copysignsf3_var"
9676 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9678 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9679 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9680 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9681 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9683 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9688 [(set (match_operand:SF 0 "register_operand" "")
9690 [(match_operand:SF 2 "register_operand" "")
9691 (match_operand:SF 3 "register_operand" "")
9692 (match_operand:V4SF 4 "" "")
9693 (match_operand:V4SF 5 "" "")]
9695 (clobber (match_scratch:V4SF 1 ""))]
9696 "TARGET_SSE_MATH && reload_completed"
9699 ix86_split_copysign_var (operands);
9703 (define_expand "negdf2"
9704 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9705 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9706 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9707 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9709 (define_expand "absdf2"
9710 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9711 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9712 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9713 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9715 (define_insn "*absnegdf2_mixed"
9716 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9717 (match_operator:DF 3 "absneg_operator"
9718 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9719 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9720 (clobber (reg:CC FLAGS_REG))]
9721 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9722 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9725 (define_insn "*absnegdf2_sse"
9726 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9727 (match_operator:DF 3 "absneg_operator"
9728 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9729 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9730 (clobber (reg:CC FLAGS_REG))]
9731 "TARGET_SSE2 && TARGET_SSE_MATH
9732 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9735 (define_insn "*absnegdf2_i387"
9736 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9737 (match_operator:DF 3 "absneg_operator"
9738 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9739 (use (match_operand 2 "" ""))
9740 (clobber (reg:CC FLAGS_REG))]
9741 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9742 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9745 (define_expand "copysigndf3"
9746 [(match_operand:DF 0 "register_operand" "")
9747 (match_operand:DF 1 "nonmemory_operand" "")
9748 (match_operand:DF 2 "register_operand" "")]
9749 "TARGET_SSE2 && TARGET_SSE_MATH"
9751 ix86_expand_copysign (operands);
9755 (define_insn_and_split "copysigndf3_const"
9756 [(set (match_operand:DF 0 "register_operand" "=x")
9758 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9759 (match_operand:DF 2 "register_operand" "0")
9760 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9762 "TARGET_SSE2 && TARGET_SSE_MATH"
9764 "&& reload_completed"
9767 ix86_split_copysign_const (operands);
9771 (define_insn "copysigndf3_var"
9772 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9774 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9775 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9776 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9777 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9779 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9780 "TARGET_SSE2 && TARGET_SSE_MATH"
9784 [(set (match_operand:DF 0 "register_operand" "")
9786 [(match_operand:DF 2 "register_operand" "")
9787 (match_operand:DF 3 "register_operand" "")
9788 (match_operand:V2DF 4 "" "")
9789 (match_operand:V2DF 5 "" "")]
9791 (clobber (match_scratch:V2DF 1 ""))]
9792 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9795 ix86_split_copysign_var (operands);
9799 (define_expand "negxf2"
9800 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9801 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9803 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9805 (define_expand "absxf2"
9806 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9807 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9809 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9811 (define_insn "*absnegxf2_i387"
9812 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9813 (match_operator:XF 3 "absneg_operator"
9814 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9815 (use (match_operand 2 "" ""))
9816 (clobber (reg:CC FLAGS_REG))]
9818 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9821 ;; Splitters for fp abs and neg.
9824 [(set (match_operand 0 "fp_register_operand" "")
9825 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9826 (use (match_operand 2 "" ""))
9827 (clobber (reg:CC FLAGS_REG))]
9829 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9832 [(set (match_operand 0 "register_operand" "")
9833 (match_operator 3 "absneg_operator"
9834 [(match_operand 1 "register_operand" "")]))
9835 (use (match_operand 2 "nonimmediate_operand" ""))
9836 (clobber (reg:CC FLAGS_REG))]
9837 "reload_completed && SSE_REG_P (operands[0])"
9838 [(set (match_dup 0) (match_dup 3))]
9840 enum machine_mode mode = GET_MODE (operands[0]);
9841 enum machine_mode vmode = GET_MODE (operands[2]);
9844 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9845 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9846 if (operands_match_p (operands[0], operands[2]))
9849 operands[1] = operands[2];
9852 if (GET_CODE (operands[3]) == ABS)
9853 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9855 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9860 [(set (match_operand:SF 0 "register_operand" "")
9861 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9862 (use (match_operand:V4SF 2 "" ""))
9863 (clobber (reg:CC FLAGS_REG))]
9865 [(parallel [(set (match_dup 0) (match_dup 1))
9866 (clobber (reg:CC FLAGS_REG))])]
9869 operands[0] = gen_lowpart (SImode, operands[0]);
9870 if (GET_CODE (operands[1]) == ABS)
9872 tmp = gen_int_mode (0x7fffffff, SImode);
9873 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9877 tmp = gen_int_mode (0x80000000, SImode);
9878 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9884 [(set (match_operand:DF 0 "register_operand" "")
9885 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9886 (use (match_operand 2 "" ""))
9887 (clobber (reg:CC FLAGS_REG))]
9889 [(parallel [(set (match_dup 0) (match_dup 1))
9890 (clobber (reg:CC FLAGS_REG))])]
9895 tmp = gen_lowpart (DImode, operands[0]);
9896 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9899 if (GET_CODE (operands[1]) == ABS)
9902 tmp = gen_rtx_NOT (DImode, tmp);
9906 operands[0] = gen_highpart (SImode, operands[0]);
9907 if (GET_CODE (operands[1]) == ABS)
9909 tmp = gen_int_mode (0x7fffffff, SImode);
9910 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9914 tmp = gen_int_mode (0x80000000, SImode);
9915 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9922 [(set (match_operand:XF 0 "register_operand" "")
9923 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9924 (use (match_operand 2 "" ""))
9925 (clobber (reg:CC FLAGS_REG))]
9927 [(parallel [(set (match_dup 0) (match_dup 1))
9928 (clobber (reg:CC FLAGS_REG))])]
9931 operands[0] = gen_rtx_REG (SImode,
9932 true_regnum (operands[0])
9933 + (TARGET_64BIT ? 1 : 2));
9934 if (GET_CODE (operands[1]) == ABS)
9936 tmp = GEN_INT (0x7fff);
9937 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9941 tmp = GEN_INT (0x8000);
9942 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9948 [(set (match_operand 0 "memory_operand" "")
9949 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9950 (use (match_operand 2 "" ""))
9951 (clobber (reg:CC FLAGS_REG))]
9953 [(parallel [(set (match_dup 0) (match_dup 1))
9954 (clobber (reg:CC FLAGS_REG))])]
9956 enum machine_mode mode = GET_MODE (operands[0]);
9957 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9960 operands[0] = adjust_address (operands[0], QImode, size - 1);
9961 if (GET_CODE (operands[1]) == ABS)
9963 tmp = gen_int_mode (0x7f, QImode);
9964 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9968 tmp = gen_int_mode (0x80, QImode);
9969 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9974 ;; Conditionalize these after reload. If they match before reload, we
9975 ;; lose the clobber and ability to use integer instructions.
9977 (define_insn "*negsf2_1"
9978 [(set (match_operand:SF 0 "register_operand" "=f")
9979 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9980 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9982 [(set_attr "type" "fsgn")
9983 (set_attr "mode" "SF")])
9985 (define_insn "*negdf2_1"
9986 [(set (match_operand:DF 0 "register_operand" "=f")
9987 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9988 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9990 [(set_attr "type" "fsgn")
9991 (set_attr "mode" "DF")])
9993 (define_insn "*negxf2_1"
9994 [(set (match_operand:XF 0 "register_operand" "=f")
9995 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9998 [(set_attr "type" "fsgn")
9999 (set_attr "mode" "XF")])
10001 (define_insn "*abssf2_1"
10002 [(set (match_operand:SF 0 "register_operand" "=f")
10003 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10004 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10006 [(set_attr "type" "fsgn")
10007 (set_attr "mode" "SF")])
10009 (define_insn "*absdf2_1"
10010 [(set (match_operand:DF 0 "register_operand" "=f")
10011 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10012 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10014 [(set_attr "type" "fsgn")
10015 (set_attr "mode" "DF")])
10017 (define_insn "*absxf2_1"
10018 [(set (match_operand:XF 0 "register_operand" "=f")
10019 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10022 [(set_attr "type" "fsgn")
10023 (set_attr "mode" "DF")])
10025 (define_insn "*negextendsfdf2"
10026 [(set (match_operand:DF 0 "register_operand" "=f")
10027 (neg:DF (float_extend:DF
10028 (match_operand:SF 1 "register_operand" "0"))))]
10029 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10031 [(set_attr "type" "fsgn")
10032 (set_attr "mode" "DF")])
10034 (define_insn "*negextenddfxf2"
10035 [(set (match_operand:XF 0 "register_operand" "=f")
10036 (neg:XF (float_extend:XF
10037 (match_operand:DF 1 "register_operand" "0"))))]
10040 [(set_attr "type" "fsgn")
10041 (set_attr "mode" "XF")])
10043 (define_insn "*negextendsfxf2"
10044 [(set (match_operand:XF 0 "register_operand" "=f")
10045 (neg:XF (float_extend:XF
10046 (match_operand:SF 1 "register_operand" "0"))))]
10049 [(set_attr "type" "fsgn")
10050 (set_attr "mode" "XF")])
10052 (define_insn "*absextendsfdf2"
10053 [(set (match_operand:DF 0 "register_operand" "=f")
10054 (abs:DF (float_extend:DF
10055 (match_operand:SF 1 "register_operand" "0"))))]
10056 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10058 [(set_attr "type" "fsgn")
10059 (set_attr "mode" "DF")])
10061 (define_insn "*absextenddfxf2"
10062 [(set (match_operand:XF 0 "register_operand" "=f")
10063 (abs:XF (float_extend:XF
10064 (match_operand:DF 1 "register_operand" "0"))))]
10067 [(set_attr "type" "fsgn")
10068 (set_attr "mode" "XF")])
10070 (define_insn "*absextendsfxf2"
10071 [(set (match_operand:XF 0 "register_operand" "=f")
10072 (abs:XF (float_extend:XF
10073 (match_operand:SF 1 "register_operand" "0"))))]
10076 [(set_attr "type" "fsgn")
10077 (set_attr "mode" "XF")])
10079 ;; One complement instructions
10081 (define_expand "one_cmpldi2"
10082 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10083 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10085 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10087 (define_insn "*one_cmpldi2_1_rex64"
10088 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10089 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10090 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10092 [(set_attr "type" "negnot")
10093 (set_attr "mode" "DI")])
10095 (define_insn "*one_cmpldi2_2_rex64"
10096 [(set (reg FLAGS_REG)
10097 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10099 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10100 (not:DI (match_dup 1)))]
10101 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10102 && ix86_unary_operator_ok (NOT, DImode, operands)"
10104 [(set_attr "type" "alu1")
10105 (set_attr "mode" "DI")])
10108 [(set (match_operand 0 "flags_reg_operand" "")
10109 (match_operator 2 "compare_operator"
10110 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10112 (set (match_operand:DI 1 "nonimmediate_operand" "")
10113 (not:DI (match_dup 3)))]
10114 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10115 [(parallel [(set (match_dup 0)
10117 [(xor:DI (match_dup 3) (const_int -1))
10120 (xor:DI (match_dup 3) (const_int -1)))])]
10123 (define_expand "one_cmplsi2"
10124 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10125 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10127 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10129 (define_insn "*one_cmplsi2_1"
10130 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10131 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10132 "ix86_unary_operator_ok (NOT, SImode, operands)"
10134 [(set_attr "type" "negnot")
10135 (set_attr "mode" "SI")])
10137 ;; ??? Currently never generated - xor is used instead.
10138 (define_insn "*one_cmplsi2_1_zext"
10139 [(set (match_operand:DI 0 "register_operand" "=r")
10140 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10141 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10143 [(set_attr "type" "negnot")
10144 (set_attr "mode" "SI")])
10146 (define_insn "*one_cmplsi2_2"
10147 [(set (reg FLAGS_REG)
10148 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10150 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10151 (not:SI (match_dup 1)))]
10152 "ix86_match_ccmode (insn, CCNOmode)
10153 && ix86_unary_operator_ok (NOT, SImode, operands)"
10155 [(set_attr "type" "alu1")
10156 (set_attr "mode" "SI")])
10159 [(set (match_operand 0 "flags_reg_operand" "")
10160 (match_operator 2 "compare_operator"
10161 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10163 (set (match_operand:SI 1 "nonimmediate_operand" "")
10164 (not:SI (match_dup 3)))]
10165 "ix86_match_ccmode (insn, CCNOmode)"
10166 [(parallel [(set (match_dup 0)
10167 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10170 (xor:SI (match_dup 3) (const_int -1)))])]
10173 ;; ??? Currently never generated - xor is used instead.
10174 (define_insn "*one_cmplsi2_2_zext"
10175 [(set (reg FLAGS_REG)
10176 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10178 (set (match_operand:DI 0 "register_operand" "=r")
10179 (zero_extend:DI (not:SI (match_dup 1))))]
10180 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10181 && ix86_unary_operator_ok (NOT, SImode, operands)"
10183 [(set_attr "type" "alu1")
10184 (set_attr "mode" "SI")])
10187 [(set (match_operand 0 "flags_reg_operand" "")
10188 (match_operator 2 "compare_operator"
10189 [(not:SI (match_operand:SI 3 "register_operand" ""))
10191 (set (match_operand:DI 1 "register_operand" "")
10192 (zero_extend:DI (not:SI (match_dup 3))))]
10193 "ix86_match_ccmode (insn, CCNOmode)"
10194 [(parallel [(set (match_dup 0)
10195 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10198 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10201 (define_expand "one_cmplhi2"
10202 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10203 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10204 "TARGET_HIMODE_MATH"
10205 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10207 (define_insn "*one_cmplhi2_1"
10208 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10209 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10210 "ix86_unary_operator_ok (NOT, HImode, operands)"
10212 [(set_attr "type" "negnot")
10213 (set_attr "mode" "HI")])
10215 (define_insn "*one_cmplhi2_2"
10216 [(set (reg FLAGS_REG)
10217 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10219 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10220 (not:HI (match_dup 1)))]
10221 "ix86_match_ccmode (insn, CCNOmode)
10222 && ix86_unary_operator_ok (NEG, HImode, operands)"
10224 [(set_attr "type" "alu1")
10225 (set_attr "mode" "HI")])
10228 [(set (match_operand 0 "flags_reg_operand" "")
10229 (match_operator 2 "compare_operator"
10230 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10232 (set (match_operand:HI 1 "nonimmediate_operand" "")
10233 (not:HI (match_dup 3)))]
10234 "ix86_match_ccmode (insn, CCNOmode)"
10235 [(parallel [(set (match_dup 0)
10236 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10239 (xor:HI (match_dup 3) (const_int -1)))])]
10242 ;; %%% Potential partial reg stall on alternative 1. What to do?
10243 (define_expand "one_cmplqi2"
10244 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10245 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10246 "TARGET_QIMODE_MATH"
10247 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10249 (define_insn "*one_cmplqi2_1"
10250 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10251 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10252 "ix86_unary_operator_ok (NOT, QImode, operands)"
10256 [(set_attr "type" "negnot")
10257 (set_attr "mode" "QI,SI")])
10259 (define_insn "*one_cmplqi2_2"
10260 [(set (reg FLAGS_REG)
10261 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10263 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10264 (not:QI (match_dup 1)))]
10265 "ix86_match_ccmode (insn, CCNOmode)
10266 && ix86_unary_operator_ok (NOT, QImode, operands)"
10268 [(set_attr "type" "alu1")
10269 (set_attr "mode" "QI")])
10272 [(set (match_operand 0 "flags_reg_operand" "")
10273 (match_operator 2 "compare_operator"
10274 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10276 (set (match_operand:QI 1 "nonimmediate_operand" "")
10277 (not:QI (match_dup 3)))]
10278 "ix86_match_ccmode (insn, CCNOmode)"
10279 [(parallel [(set (match_dup 0)
10280 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10283 (xor:QI (match_dup 3) (const_int -1)))])]
10286 ;; Arithmetic shift instructions
10288 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10289 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10290 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10291 ;; from the assembler input.
10293 ;; This instruction shifts the target reg/mem as usual, but instead of
10294 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10295 ;; is a left shift double, bits are taken from the high order bits of
10296 ;; reg, else if the insn is a shift right double, bits are taken from the
10297 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10298 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10300 ;; Since sh[lr]d does not change the `reg' operand, that is done
10301 ;; separately, making all shifts emit pairs of shift double and normal
10302 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10303 ;; support a 63 bit shift, each shift where the count is in a reg expands
10304 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10306 ;; If the shift count is a constant, we need never emit more than one
10307 ;; shift pair, instead using moves and sign extension for counts greater
10310 (define_expand "ashlti3"
10311 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10312 (ashift:TI (match_operand:TI 1 "register_operand" "")
10313 (match_operand:QI 2 "nonmemory_operand" "")))
10314 (clobber (reg:CC FLAGS_REG))])]
10317 if (! immediate_operand (operands[2], QImode))
10319 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10322 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10326 (define_insn "ashlti3_1"
10327 [(set (match_operand:TI 0 "register_operand" "=r")
10328 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10329 (match_operand:QI 2 "register_operand" "c")))
10330 (clobber (match_scratch:DI 3 "=&r"))
10331 (clobber (reg:CC FLAGS_REG))]
10334 [(set_attr "type" "multi")])
10336 (define_insn "*ashlti3_2"
10337 [(set (match_operand:TI 0 "register_operand" "=r")
10338 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10339 (match_operand:QI 2 "immediate_operand" "O")))
10340 (clobber (reg:CC FLAGS_REG))]
10343 [(set_attr "type" "multi")])
10346 [(set (match_operand:TI 0 "register_operand" "")
10347 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10348 (match_operand:QI 2 "register_operand" "")))
10349 (clobber (match_scratch:DI 3 ""))
10350 (clobber (reg:CC FLAGS_REG))]
10351 "TARGET_64BIT && reload_completed"
10353 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10356 [(set (match_operand:TI 0 "register_operand" "")
10357 (ashift:TI (match_operand:TI 1 "register_operand" "")
10358 (match_operand:QI 2 "immediate_operand" "")))
10359 (clobber (reg:CC FLAGS_REG))]
10360 "TARGET_64BIT && reload_completed"
10362 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10364 (define_insn "x86_64_shld"
10365 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10366 (ior:DI (ashift:DI (match_dup 0)
10367 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10368 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10369 (minus:QI (const_int 64) (match_dup 2)))))
10370 (clobber (reg:CC FLAGS_REG))]
10373 shld{q}\t{%2, %1, %0|%0, %1, %2}
10374 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10375 [(set_attr "type" "ishift")
10376 (set_attr "prefix_0f" "1")
10377 (set_attr "mode" "DI")
10378 (set_attr "athlon_decode" "vector")])
10380 (define_expand "x86_64_shift_adj"
10381 [(set (reg:CCZ FLAGS_REG)
10382 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10385 (set (match_operand:DI 0 "register_operand" "")
10386 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10387 (match_operand:DI 1 "register_operand" "")
10390 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10391 (match_operand:DI 3 "register_operand" "r")
10396 (define_expand "ashldi3"
10397 [(set (match_operand:DI 0 "shiftdi_operand" "")
10398 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10399 (match_operand:QI 2 "nonmemory_operand" "")))]
10401 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10403 (define_insn "*ashldi3_1_rex64"
10404 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10405 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10406 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10410 switch (get_attr_type (insn))
10413 gcc_assert (operands[2] == const1_rtx);
10414 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10415 return "add{q}\t{%0, %0|%0, %0}";
10418 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10419 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10420 operands[1] = gen_rtx_MULT (DImode, operands[1],
10421 GEN_INT (1 << INTVAL (operands[2])));
10422 return "lea{q}\t{%a1, %0|%0, %a1}";
10425 if (REG_P (operands[2]))
10426 return "sal{q}\t{%b2, %0|%0, %b2}";
10427 else if (operands[2] == const1_rtx
10428 && (TARGET_SHIFT1 || optimize_size))
10429 return "sal{q}\t%0";
10431 return "sal{q}\t{%2, %0|%0, %2}";
10434 [(set (attr "type")
10435 (cond [(eq_attr "alternative" "1")
10436 (const_string "lea")
10437 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10439 (match_operand 0 "register_operand" ""))
10440 (match_operand 2 "const1_operand" ""))
10441 (const_string "alu")
10443 (const_string "ishift")))
10444 (set_attr "mode" "DI")])
10446 ;; Convert lea to the lea pattern to avoid flags dependency.
10448 [(set (match_operand:DI 0 "register_operand" "")
10449 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10450 (match_operand:QI 2 "immediate_operand" "")))
10451 (clobber (reg:CC FLAGS_REG))]
10452 "TARGET_64BIT && reload_completed
10453 && true_regnum (operands[0]) != true_regnum (operands[1])"
10454 [(set (match_dup 0)
10455 (mult:DI (match_dup 1)
10457 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10459 ;; This pattern can't accept a variable shift count, since shifts by
10460 ;; zero don't affect the flags. We assume that shifts by constant
10461 ;; zero are optimized away.
10462 (define_insn "*ashldi3_cmp_rex64"
10463 [(set (reg FLAGS_REG)
10465 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10466 (match_operand:QI 2 "immediate_operand" "e"))
10468 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10469 (ashift:DI (match_dup 1) (match_dup 2)))]
10470 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10471 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10473 || !TARGET_PARTIAL_FLAG_REG_STALL
10474 || (operands[2] == const1_rtx
10476 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10478 switch (get_attr_type (insn))
10481 gcc_assert (operands[2] == const1_rtx);
10482 return "add{q}\t{%0, %0|%0, %0}";
10485 if (REG_P (operands[2]))
10486 return "sal{q}\t{%b2, %0|%0, %b2}";
10487 else if (operands[2] == const1_rtx
10488 && (TARGET_SHIFT1 || optimize_size))
10489 return "sal{q}\t%0";
10491 return "sal{q}\t{%2, %0|%0, %2}";
10494 [(set (attr "type")
10495 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10497 (match_operand 0 "register_operand" ""))
10498 (match_operand 2 "const1_operand" ""))
10499 (const_string "alu")
10501 (const_string "ishift")))
10502 (set_attr "mode" "DI")])
10504 (define_insn "*ashldi3_cconly_rex64"
10505 [(set (reg FLAGS_REG)
10507 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10508 (match_operand:QI 2 "immediate_operand" "e"))
10510 (clobber (match_scratch:DI 0 "=r"))]
10511 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10512 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10514 || !TARGET_PARTIAL_FLAG_REG_STALL
10515 || (operands[2] == const1_rtx
10517 || TARGET_DOUBLE_WITH_ADD)))"
10519 switch (get_attr_type (insn))
10522 gcc_assert (operands[2] == const1_rtx);
10523 return "add{q}\t{%0, %0|%0, %0}";
10526 if (REG_P (operands[2]))
10527 return "sal{q}\t{%b2, %0|%0, %b2}";
10528 else if (operands[2] == const1_rtx
10529 && (TARGET_SHIFT1 || optimize_size))
10530 return "sal{q}\t%0";
10532 return "sal{q}\t{%2, %0|%0, %2}";
10535 [(set (attr "type")
10536 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10538 (match_operand 0 "register_operand" ""))
10539 (match_operand 2 "const1_operand" ""))
10540 (const_string "alu")
10542 (const_string "ishift")))
10543 (set_attr "mode" "DI")])
10545 (define_insn "*ashldi3_1"
10546 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10547 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10548 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10549 (clobber (reg:CC FLAGS_REG))]
10552 [(set_attr "type" "multi")])
10554 ;; By default we don't ask for a scratch register, because when DImode
10555 ;; values are manipulated, registers are already at a premium. But if
10556 ;; we have one handy, we won't turn it away.
10558 [(match_scratch:SI 3 "r")
10559 (parallel [(set (match_operand:DI 0 "register_operand" "")
10560 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10561 (match_operand:QI 2 "nonmemory_operand" "")))
10562 (clobber (reg:CC FLAGS_REG))])
10564 "!TARGET_64BIT && TARGET_CMOVE"
10566 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10569 [(set (match_operand:DI 0 "register_operand" "")
10570 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10571 (match_operand:QI 2 "nonmemory_operand" "")))
10572 (clobber (reg:CC FLAGS_REG))]
10573 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10574 ? flow2_completed : reload_completed)"
10576 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10578 (define_insn "x86_shld_1"
10579 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10580 (ior:SI (ashift:SI (match_dup 0)
10581 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10582 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10583 (minus:QI (const_int 32) (match_dup 2)))))
10584 (clobber (reg:CC FLAGS_REG))]
10587 shld{l}\t{%2, %1, %0|%0, %1, %2}
10588 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10589 [(set_attr "type" "ishift")
10590 (set_attr "prefix_0f" "1")
10591 (set_attr "mode" "SI")
10592 (set_attr "pent_pair" "np")
10593 (set_attr "athlon_decode" "vector")])
10595 (define_expand "x86_shift_adj_1"
10596 [(set (reg:CCZ FLAGS_REG)
10597 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10600 (set (match_operand:SI 0 "register_operand" "")
10601 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10602 (match_operand:SI 1 "register_operand" "")
10605 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10606 (match_operand:SI 3 "register_operand" "r")
10611 (define_expand "x86_shift_adj_2"
10612 [(use (match_operand:SI 0 "register_operand" ""))
10613 (use (match_operand:SI 1 "register_operand" ""))
10614 (use (match_operand:QI 2 "register_operand" ""))]
10617 rtx label = gen_label_rtx ();
10620 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10622 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10623 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10624 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10625 gen_rtx_LABEL_REF (VOIDmode, label),
10627 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10628 JUMP_LABEL (tmp) = label;
10630 emit_move_insn (operands[0], operands[1]);
10631 ix86_expand_clear (operands[1]);
10633 emit_label (label);
10634 LABEL_NUSES (label) = 1;
10639 (define_expand "ashlsi3"
10640 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10641 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10642 (match_operand:QI 2 "nonmemory_operand" "")))
10643 (clobber (reg:CC FLAGS_REG))]
10645 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10647 (define_insn "*ashlsi3_1"
10648 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10649 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10650 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10651 (clobber (reg:CC FLAGS_REG))]
10652 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10654 switch (get_attr_type (insn))
10657 gcc_assert (operands[2] == const1_rtx);
10658 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10659 return "add{l}\t{%0, %0|%0, %0}";
10665 if (REG_P (operands[2]))
10666 return "sal{l}\t{%b2, %0|%0, %b2}";
10667 else if (operands[2] == const1_rtx
10668 && (TARGET_SHIFT1 || optimize_size))
10669 return "sal{l}\t%0";
10671 return "sal{l}\t{%2, %0|%0, %2}";
10674 [(set (attr "type")
10675 (cond [(eq_attr "alternative" "1")
10676 (const_string "lea")
10677 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10679 (match_operand 0 "register_operand" ""))
10680 (match_operand 2 "const1_operand" ""))
10681 (const_string "alu")
10683 (const_string "ishift")))
10684 (set_attr "mode" "SI")])
10686 ;; Convert lea to the lea pattern to avoid flags dependency.
10688 [(set (match_operand 0 "register_operand" "")
10689 (ashift (match_operand 1 "index_register_operand" "")
10690 (match_operand:QI 2 "const_int_operand" "")))
10691 (clobber (reg:CC FLAGS_REG))]
10693 && true_regnum (operands[0]) != true_regnum (operands[1])
10694 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10698 enum machine_mode mode = GET_MODE (operands[0]);
10700 if (GET_MODE_SIZE (mode) < 4)
10701 operands[0] = gen_lowpart (SImode, operands[0]);
10703 operands[1] = gen_lowpart (Pmode, operands[1]);
10704 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10706 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10707 if (Pmode != SImode)
10708 pat = gen_rtx_SUBREG (SImode, pat, 0);
10709 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10713 ;; Rare case of shifting RSP is handled by generating move and shift
10715 [(set (match_operand 0 "register_operand" "")
10716 (ashift (match_operand 1 "register_operand" "")
10717 (match_operand:QI 2 "const_int_operand" "")))
10718 (clobber (reg:CC FLAGS_REG))]
10720 && true_regnum (operands[0]) != true_regnum (operands[1])"
10724 emit_move_insn (operands[0], operands[1]);
10725 pat = gen_rtx_SET (VOIDmode, operands[0],
10726 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10727 operands[0], operands[2]));
10728 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10729 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10733 (define_insn "*ashlsi3_1_zext"
10734 [(set (match_operand:DI 0 "register_operand" "=r,r")
10735 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10736 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10737 (clobber (reg:CC FLAGS_REG))]
10738 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10740 switch (get_attr_type (insn))
10743 gcc_assert (operands[2] == const1_rtx);
10744 return "add{l}\t{%k0, %k0|%k0, %k0}";
10750 if (REG_P (operands[2]))
10751 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10752 else if (operands[2] == const1_rtx
10753 && (TARGET_SHIFT1 || optimize_size))
10754 return "sal{l}\t%k0";
10756 return "sal{l}\t{%2, %k0|%k0, %2}";
10759 [(set (attr "type")
10760 (cond [(eq_attr "alternative" "1")
10761 (const_string "lea")
10762 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10764 (match_operand 2 "const1_operand" ""))
10765 (const_string "alu")
10767 (const_string "ishift")))
10768 (set_attr "mode" "SI")])
10770 ;; Convert lea to the lea pattern to avoid flags dependency.
10772 [(set (match_operand:DI 0 "register_operand" "")
10773 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10774 (match_operand:QI 2 "const_int_operand" ""))))
10775 (clobber (reg:CC FLAGS_REG))]
10776 "TARGET_64BIT && reload_completed
10777 && true_regnum (operands[0]) != true_regnum (operands[1])"
10778 [(set (match_dup 0) (zero_extend:DI
10779 (subreg:SI (mult:SI (match_dup 1)
10780 (match_dup 2)) 0)))]
10782 operands[1] = gen_lowpart (Pmode, operands[1]);
10783 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10786 ;; This pattern can't accept a variable shift count, since shifts by
10787 ;; zero don't affect the flags. We assume that shifts by constant
10788 ;; zero are optimized away.
10789 (define_insn "*ashlsi3_cmp"
10790 [(set (reg FLAGS_REG)
10792 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10793 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10795 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10796 (ashift:SI (match_dup 1) (match_dup 2)))]
10797 "ix86_match_ccmode (insn, CCGOCmode)
10798 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10800 || !TARGET_PARTIAL_FLAG_REG_STALL
10801 || (operands[2] == const1_rtx
10803 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10805 switch (get_attr_type (insn))
10808 gcc_assert (operands[2] == const1_rtx);
10809 return "add{l}\t{%0, %0|%0, %0}";
10812 if (REG_P (operands[2]))
10813 return "sal{l}\t{%b2, %0|%0, %b2}";
10814 else if (operands[2] == const1_rtx
10815 && (TARGET_SHIFT1 || optimize_size))
10816 return "sal{l}\t%0";
10818 return "sal{l}\t{%2, %0|%0, %2}";
10821 [(set (attr "type")
10822 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10824 (match_operand 0 "register_operand" ""))
10825 (match_operand 2 "const1_operand" ""))
10826 (const_string "alu")
10828 (const_string "ishift")))
10829 (set_attr "mode" "SI")])
10831 (define_insn "*ashlsi3_cconly"
10832 [(set (reg FLAGS_REG)
10834 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10835 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10837 (clobber (match_scratch:SI 0 "=r"))]
10838 "ix86_match_ccmode (insn, CCGOCmode)
10839 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10841 || !TARGET_PARTIAL_FLAG_REG_STALL
10842 || (operands[2] == const1_rtx
10844 || TARGET_DOUBLE_WITH_ADD)))"
10846 switch (get_attr_type (insn))
10849 gcc_assert (operands[2] == const1_rtx);
10850 return "add{l}\t{%0, %0|%0, %0}";
10853 if (REG_P (operands[2]))
10854 return "sal{l}\t{%b2, %0|%0, %b2}";
10855 else if (operands[2] == const1_rtx
10856 && (TARGET_SHIFT1 || optimize_size))
10857 return "sal{l}\t%0";
10859 return "sal{l}\t{%2, %0|%0, %2}";
10862 [(set (attr "type")
10863 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10865 (match_operand 0 "register_operand" ""))
10866 (match_operand 2 "const1_operand" ""))
10867 (const_string "alu")
10869 (const_string "ishift")))
10870 (set_attr "mode" "SI")])
10872 (define_insn "*ashlsi3_cmp_zext"
10873 [(set (reg FLAGS_REG)
10875 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10876 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10878 (set (match_operand:DI 0 "register_operand" "=r")
10879 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10880 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10881 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10883 || !TARGET_PARTIAL_FLAG_REG_STALL
10884 || (operands[2] == const1_rtx
10886 || TARGET_DOUBLE_WITH_ADD)))"
10888 switch (get_attr_type (insn))
10891 gcc_assert (operands[2] == const1_rtx);
10892 return "add{l}\t{%k0, %k0|%k0, %k0}";
10895 if (REG_P (operands[2]))
10896 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10897 else if (operands[2] == const1_rtx
10898 && (TARGET_SHIFT1 || optimize_size))
10899 return "sal{l}\t%k0";
10901 return "sal{l}\t{%2, %k0|%k0, %2}";
10904 [(set (attr "type")
10905 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10907 (match_operand 2 "const1_operand" ""))
10908 (const_string "alu")
10910 (const_string "ishift")))
10911 (set_attr "mode" "SI")])
10913 (define_expand "ashlhi3"
10914 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10915 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10916 (match_operand:QI 2 "nonmemory_operand" "")))
10917 (clobber (reg:CC FLAGS_REG))]
10918 "TARGET_HIMODE_MATH"
10919 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10921 (define_insn "*ashlhi3_1_lea"
10922 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10923 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10924 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10925 (clobber (reg:CC FLAGS_REG))]
10926 "!TARGET_PARTIAL_REG_STALL
10927 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10929 switch (get_attr_type (insn))
10934 gcc_assert (operands[2] == const1_rtx);
10935 return "add{w}\t{%0, %0|%0, %0}";
10938 if (REG_P (operands[2]))
10939 return "sal{w}\t{%b2, %0|%0, %b2}";
10940 else if (operands[2] == const1_rtx
10941 && (TARGET_SHIFT1 || optimize_size))
10942 return "sal{w}\t%0";
10944 return "sal{w}\t{%2, %0|%0, %2}";
10947 [(set (attr "type")
10948 (cond [(eq_attr "alternative" "1")
10949 (const_string "lea")
10950 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10952 (match_operand 0 "register_operand" ""))
10953 (match_operand 2 "const1_operand" ""))
10954 (const_string "alu")
10956 (const_string "ishift")))
10957 (set_attr "mode" "HI,SI")])
10959 (define_insn "*ashlhi3_1"
10960 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10961 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10962 (match_operand:QI 2 "nonmemory_operand" "cI")))
10963 (clobber (reg:CC FLAGS_REG))]
10964 "TARGET_PARTIAL_REG_STALL
10965 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10967 switch (get_attr_type (insn))
10970 gcc_assert (operands[2] == const1_rtx);
10971 return "add{w}\t{%0, %0|%0, %0}";
10974 if (REG_P (operands[2]))
10975 return "sal{w}\t{%b2, %0|%0, %b2}";
10976 else if (operands[2] == const1_rtx
10977 && (TARGET_SHIFT1 || optimize_size))
10978 return "sal{w}\t%0";
10980 return "sal{w}\t{%2, %0|%0, %2}";
10983 [(set (attr "type")
10984 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10986 (match_operand 0 "register_operand" ""))
10987 (match_operand 2 "const1_operand" ""))
10988 (const_string "alu")
10990 (const_string "ishift")))
10991 (set_attr "mode" "HI")])
10993 ;; This pattern can't accept a variable shift count, since shifts by
10994 ;; zero don't affect the flags. We assume that shifts by constant
10995 ;; zero are optimized away.
10996 (define_insn "*ashlhi3_cmp"
10997 [(set (reg FLAGS_REG)
10999 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11000 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11002 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11003 (ashift:HI (match_dup 1) (match_dup 2)))]
11004 "ix86_match_ccmode (insn, CCGOCmode)
11005 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11007 || !TARGET_PARTIAL_FLAG_REG_STALL
11008 || (operands[2] == const1_rtx
11010 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11012 switch (get_attr_type (insn))
11015 gcc_assert (operands[2] == const1_rtx);
11016 return "add{w}\t{%0, %0|%0, %0}";
11019 if (REG_P (operands[2]))
11020 return "sal{w}\t{%b2, %0|%0, %b2}";
11021 else if (operands[2] == const1_rtx
11022 && (TARGET_SHIFT1 || optimize_size))
11023 return "sal{w}\t%0";
11025 return "sal{w}\t{%2, %0|%0, %2}";
11028 [(set (attr "type")
11029 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11031 (match_operand 0 "register_operand" ""))
11032 (match_operand 2 "const1_operand" ""))
11033 (const_string "alu")
11035 (const_string "ishift")))
11036 (set_attr "mode" "HI")])
11038 (define_insn "*ashlhi3_cconly"
11039 [(set (reg FLAGS_REG)
11041 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11042 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11044 (clobber (match_scratch:HI 0 "=r"))]
11045 "ix86_match_ccmode (insn, CCGOCmode)
11046 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11048 || !TARGET_PARTIAL_FLAG_REG_STALL
11049 || (operands[2] == const1_rtx
11051 || TARGET_DOUBLE_WITH_ADD)))"
11053 switch (get_attr_type (insn))
11056 gcc_assert (operands[2] == const1_rtx);
11057 return "add{w}\t{%0, %0|%0, %0}";
11060 if (REG_P (operands[2]))
11061 return "sal{w}\t{%b2, %0|%0, %b2}";
11062 else if (operands[2] == const1_rtx
11063 && (TARGET_SHIFT1 || optimize_size))
11064 return "sal{w}\t%0";
11066 return "sal{w}\t{%2, %0|%0, %2}";
11069 [(set (attr "type")
11070 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11072 (match_operand 0 "register_operand" ""))
11073 (match_operand 2 "const1_operand" ""))
11074 (const_string "alu")
11076 (const_string "ishift")))
11077 (set_attr "mode" "HI")])
11079 (define_expand "ashlqi3"
11080 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11081 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11082 (match_operand:QI 2 "nonmemory_operand" "")))
11083 (clobber (reg:CC FLAGS_REG))]
11084 "TARGET_QIMODE_MATH"
11085 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11087 ;; %%% Potential partial reg stall on alternative 2. What to do?
11089 (define_insn "*ashlqi3_1_lea"
11090 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11091 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11092 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11093 (clobber (reg:CC FLAGS_REG))]
11094 "!TARGET_PARTIAL_REG_STALL
11095 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11097 switch (get_attr_type (insn))
11102 gcc_assert (operands[2] == const1_rtx);
11103 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11104 return "add{l}\t{%k0, %k0|%k0, %k0}";
11106 return "add{b}\t{%0, %0|%0, %0}";
11109 if (REG_P (operands[2]))
11111 if (get_attr_mode (insn) == MODE_SI)
11112 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11114 return "sal{b}\t{%b2, %0|%0, %b2}";
11116 else if (operands[2] == const1_rtx
11117 && (TARGET_SHIFT1 || optimize_size))
11119 if (get_attr_mode (insn) == MODE_SI)
11120 return "sal{l}\t%0";
11122 return "sal{b}\t%0";
11126 if (get_attr_mode (insn) == MODE_SI)
11127 return "sal{l}\t{%2, %k0|%k0, %2}";
11129 return "sal{b}\t{%2, %0|%0, %2}";
11133 [(set (attr "type")
11134 (cond [(eq_attr "alternative" "2")
11135 (const_string "lea")
11136 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11138 (match_operand 0 "register_operand" ""))
11139 (match_operand 2 "const1_operand" ""))
11140 (const_string "alu")
11142 (const_string "ishift")))
11143 (set_attr "mode" "QI,SI,SI")])
11145 (define_insn "*ashlqi3_1"
11146 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11147 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11148 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11149 (clobber (reg:CC FLAGS_REG))]
11150 "TARGET_PARTIAL_REG_STALL
11151 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11153 switch (get_attr_type (insn))
11156 gcc_assert (operands[2] == const1_rtx);
11157 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11158 return "add{l}\t{%k0, %k0|%k0, %k0}";
11160 return "add{b}\t{%0, %0|%0, %0}";
11163 if (REG_P (operands[2]))
11165 if (get_attr_mode (insn) == MODE_SI)
11166 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11168 return "sal{b}\t{%b2, %0|%0, %b2}";
11170 else if (operands[2] == const1_rtx
11171 && (TARGET_SHIFT1 || optimize_size))
11173 if (get_attr_mode (insn) == MODE_SI)
11174 return "sal{l}\t%0";
11176 return "sal{b}\t%0";
11180 if (get_attr_mode (insn) == MODE_SI)
11181 return "sal{l}\t{%2, %k0|%k0, %2}";
11183 return "sal{b}\t{%2, %0|%0, %2}";
11187 [(set (attr "type")
11188 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11190 (match_operand 0 "register_operand" ""))
11191 (match_operand 2 "const1_operand" ""))
11192 (const_string "alu")
11194 (const_string "ishift")))
11195 (set_attr "mode" "QI,SI")])
11197 ;; This pattern can't accept a variable shift count, since shifts by
11198 ;; zero don't affect the flags. We assume that shifts by constant
11199 ;; zero are optimized away.
11200 (define_insn "*ashlqi3_cmp"
11201 [(set (reg FLAGS_REG)
11203 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11204 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11206 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11207 (ashift:QI (match_dup 1) (match_dup 2)))]
11208 "ix86_match_ccmode (insn, CCGOCmode)
11209 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11211 || !TARGET_PARTIAL_FLAG_REG_STALL
11212 || (operands[2] == const1_rtx
11214 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11216 switch (get_attr_type (insn))
11219 gcc_assert (operands[2] == const1_rtx);
11220 return "add{b}\t{%0, %0|%0, %0}";
11223 if (REG_P (operands[2]))
11224 return "sal{b}\t{%b2, %0|%0, %b2}";
11225 else if (operands[2] == const1_rtx
11226 && (TARGET_SHIFT1 || optimize_size))
11227 return "sal{b}\t%0";
11229 return "sal{b}\t{%2, %0|%0, %2}";
11232 [(set (attr "type")
11233 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11235 (match_operand 0 "register_operand" ""))
11236 (match_operand 2 "const1_operand" ""))
11237 (const_string "alu")
11239 (const_string "ishift")))
11240 (set_attr "mode" "QI")])
11242 (define_insn "*ashlqi3_cconly"
11243 [(set (reg FLAGS_REG)
11245 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11246 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11248 (clobber (match_scratch:QI 0 "=q"))]
11249 "ix86_match_ccmode (insn, CCGOCmode)
11250 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11252 || !TARGET_PARTIAL_FLAG_REG_STALL
11253 || (operands[2] == const1_rtx
11255 || TARGET_DOUBLE_WITH_ADD)))"
11257 switch (get_attr_type (insn))
11260 gcc_assert (operands[2] == const1_rtx);
11261 return "add{b}\t{%0, %0|%0, %0}";
11264 if (REG_P (operands[2]))
11265 return "sal{b}\t{%b2, %0|%0, %b2}";
11266 else if (operands[2] == const1_rtx
11267 && (TARGET_SHIFT1 || optimize_size))
11268 return "sal{b}\t%0";
11270 return "sal{b}\t{%2, %0|%0, %2}";
11273 [(set (attr "type")
11274 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11276 (match_operand 0 "register_operand" ""))
11277 (match_operand 2 "const1_operand" ""))
11278 (const_string "alu")
11280 (const_string "ishift")))
11281 (set_attr "mode" "QI")])
11283 ;; See comment above `ashldi3' about how this works.
11285 (define_expand "ashrti3"
11286 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11287 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11288 (match_operand:QI 2 "nonmemory_operand" "")))
11289 (clobber (reg:CC FLAGS_REG))])]
11292 if (! immediate_operand (operands[2], QImode))
11294 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11297 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11301 (define_insn "ashrti3_1"
11302 [(set (match_operand:TI 0 "register_operand" "=r")
11303 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11304 (match_operand:QI 2 "register_operand" "c")))
11305 (clobber (match_scratch:DI 3 "=&r"))
11306 (clobber (reg:CC FLAGS_REG))]
11309 [(set_attr "type" "multi")])
11311 (define_insn "*ashrti3_2"
11312 [(set (match_operand:TI 0 "register_operand" "=r")
11313 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11314 (match_operand:QI 2 "immediate_operand" "O")))
11315 (clobber (reg:CC FLAGS_REG))]
11318 [(set_attr "type" "multi")])
11321 [(set (match_operand:TI 0 "register_operand" "")
11322 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11323 (match_operand:QI 2 "register_operand" "")))
11324 (clobber (match_scratch:DI 3 ""))
11325 (clobber (reg:CC FLAGS_REG))]
11326 "TARGET_64BIT && reload_completed"
11328 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11331 [(set (match_operand:TI 0 "register_operand" "")
11332 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11333 (match_operand:QI 2 "immediate_operand" "")))
11334 (clobber (reg:CC FLAGS_REG))]
11335 "TARGET_64BIT && reload_completed"
11337 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11339 (define_insn "x86_64_shrd"
11340 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11341 (ior:DI (ashiftrt:DI (match_dup 0)
11342 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11343 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11344 (minus:QI (const_int 64) (match_dup 2)))))
11345 (clobber (reg:CC FLAGS_REG))]
11348 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11349 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11350 [(set_attr "type" "ishift")
11351 (set_attr "prefix_0f" "1")
11352 (set_attr "mode" "DI")
11353 (set_attr "athlon_decode" "vector")])
11355 (define_expand "ashrdi3"
11356 [(set (match_operand:DI 0 "shiftdi_operand" "")
11357 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11358 (match_operand:QI 2 "nonmemory_operand" "")))]
11360 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11362 (define_insn "*ashrdi3_63_rex64"
11363 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11364 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11365 (match_operand:DI 2 "const_int_operand" "i,i")))
11366 (clobber (reg:CC FLAGS_REG))]
11367 "TARGET_64BIT && INTVAL (operands[2]) == 63
11368 && (TARGET_USE_CLTD || optimize_size)
11369 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11372 sar{q}\t{%2, %0|%0, %2}"
11373 [(set_attr "type" "imovx,ishift")
11374 (set_attr "prefix_0f" "0,*")
11375 (set_attr "length_immediate" "0,*")
11376 (set_attr "modrm" "0,1")
11377 (set_attr "mode" "DI")])
11379 (define_insn "*ashrdi3_1_one_bit_rex64"
11380 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11381 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11382 (match_operand:QI 2 "const1_operand" "")))
11383 (clobber (reg:CC FLAGS_REG))]
11384 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11385 && (TARGET_SHIFT1 || optimize_size)"
11387 [(set_attr "type" "ishift")
11388 (set (attr "length")
11389 (if_then_else (match_operand:DI 0 "register_operand" "")
11391 (const_string "*")))])
11393 (define_insn "*ashrdi3_1_rex64"
11394 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11395 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11396 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11397 (clobber (reg:CC FLAGS_REG))]
11398 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11400 sar{q}\t{%2, %0|%0, %2}
11401 sar{q}\t{%b2, %0|%0, %b2}"
11402 [(set_attr "type" "ishift")
11403 (set_attr "mode" "DI")])
11405 ;; This pattern can't accept a variable shift count, since shifts by
11406 ;; zero don't affect the flags. We assume that shifts by constant
11407 ;; zero are optimized away.
11408 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11409 [(set (reg FLAGS_REG)
11411 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412 (match_operand:QI 2 "const1_operand" ""))
11414 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11415 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11416 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11417 && (TARGET_SHIFT1 || optimize_size)
11418 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11420 [(set_attr "type" "ishift")
11421 (set (attr "length")
11422 (if_then_else (match_operand:DI 0 "register_operand" "")
11424 (const_string "*")))])
11426 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11427 [(set (reg FLAGS_REG)
11429 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11430 (match_operand:QI 2 "const1_operand" ""))
11432 (clobber (match_scratch:DI 0 "=r"))]
11433 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11434 && (TARGET_SHIFT1 || optimize_size)
11435 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11437 [(set_attr "type" "ishift")
11438 (set_attr "length" "2")])
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 "*ashrdi3_cmp_rex64"
11444 [(set (reg FLAGS_REG)
11446 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11447 (match_operand:QI 2 "const_int_operand" "n"))
11449 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11450 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11451 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11452 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11454 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11455 "sar{q}\t{%2, %0|%0, %2}"
11456 [(set_attr "type" "ishift")
11457 (set_attr "mode" "DI")])
11459 (define_insn "*ashrdi3_cconly_rex64"
11460 [(set (reg FLAGS_REG)
11462 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11463 (match_operand:QI 2 "const_int_operand" "n"))
11465 (clobber (match_scratch:DI 0 "=r"))]
11466 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11467 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11469 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11470 "sar{q}\t{%2, %0|%0, %2}"
11471 [(set_attr "type" "ishift")
11472 (set_attr "mode" "DI")])
11474 (define_insn "*ashrdi3_1"
11475 [(set (match_operand:DI 0 "register_operand" "=r")
11476 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11477 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11478 (clobber (reg:CC FLAGS_REG))]
11481 [(set_attr "type" "multi")])
11483 ;; By default we don't ask for a scratch register, because when DImode
11484 ;; values are manipulated, registers are already at a premium. But if
11485 ;; we have one handy, we won't turn it away.
11487 [(match_scratch:SI 3 "r")
11488 (parallel [(set (match_operand:DI 0 "register_operand" "")
11489 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11490 (match_operand:QI 2 "nonmemory_operand" "")))
11491 (clobber (reg:CC FLAGS_REG))])
11493 "!TARGET_64BIT && TARGET_CMOVE"
11495 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11498 [(set (match_operand:DI 0 "register_operand" "")
11499 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11500 (match_operand:QI 2 "nonmemory_operand" "")))
11501 (clobber (reg:CC FLAGS_REG))]
11502 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11503 ? flow2_completed : reload_completed)"
11505 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11507 (define_insn "x86_shrd_1"
11508 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11509 (ior:SI (ashiftrt:SI (match_dup 0)
11510 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11511 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11512 (minus:QI (const_int 32) (match_dup 2)))))
11513 (clobber (reg:CC FLAGS_REG))]
11516 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11517 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11518 [(set_attr "type" "ishift")
11519 (set_attr "prefix_0f" "1")
11520 (set_attr "pent_pair" "np")
11521 (set_attr "mode" "SI")])
11523 (define_expand "x86_shift_adj_3"
11524 [(use (match_operand:SI 0 "register_operand" ""))
11525 (use (match_operand:SI 1 "register_operand" ""))
11526 (use (match_operand:QI 2 "register_operand" ""))]
11529 rtx label = gen_label_rtx ();
11532 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11534 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11535 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11536 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11537 gen_rtx_LABEL_REF (VOIDmode, label),
11539 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11540 JUMP_LABEL (tmp) = label;
11542 emit_move_insn (operands[0], operands[1]);
11543 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11545 emit_label (label);
11546 LABEL_NUSES (label) = 1;
11551 (define_insn "ashrsi3_31"
11552 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11553 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11554 (match_operand:SI 2 "const_int_operand" "i,i")))
11555 (clobber (reg:CC FLAGS_REG))]
11556 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11557 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11560 sar{l}\t{%2, %0|%0, %2}"
11561 [(set_attr "type" "imovx,ishift")
11562 (set_attr "prefix_0f" "0,*")
11563 (set_attr "length_immediate" "0,*")
11564 (set_attr "modrm" "0,1")
11565 (set_attr "mode" "SI")])
11567 (define_insn "*ashrsi3_31_zext"
11568 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11569 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11570 (match_operand:SI 2 "const_int_operand" "i,i"))))
11571 (clobber (reg:CC FLAGS_REG))]
11572 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11573 && INTVAL (operands[2]) == 31
11574 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11577 sar{l}\t{%2, %k0|%k0, %2}"
11578 [(set_attr "type" "imovx,ishift")
11579 (set_attr "prefix_0f" "0,*")
11580 (set_attr "length_immediate" "0,*")
11581 (set_attr "modrm" "0,1")
11582 (set_attr "mode" "SI")])
11584 (define_expand "ashrsi3"
11585 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11586 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11587 (match_operand:QI 2 "nonmemory_operand" "")))
11588 (clobber (reg:CC FLAGS_REG))]
11590 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11592 (define_insn "*ashrsi3_1_one_bit"
11593 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11594 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11595 (match_operand:QI 2 "const1_operand" "")))
11596 (clobber (reg:CC FLAGS_REG))]
11597 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11598 && (TARGET_SHIFT1 || optimize_size)"
11600 [(set_attr "type" "ishift")
11601 (set (attr "length")
11602 (if_then_else (match_operand:SI 0 "register_operand" "")
11604 (const_string "*")))])
11606 (define_insn "*ashrsi3_1_one_bit_zext"
11607 [(set (match_operand:DI 0 "register_operand" "=r")
11608 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11609 (match_operand:QI 2 "const1_operand" ""))))
11610 (clobber (reg:CC FLAGS_REG))]
11611 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11612 && (TARGET_SHIFT1 || optimize_size)"
11614 [(set_attr "type" "ishift")
11615 (set_attr "length" "2")])
11617 (define_insn "*ashrsi3_1"
11618 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11619 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11620 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11621 (clobber (reg:CC FLAGS_REG))]
11622 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11624 sar{l}\t{%2, %0|%0, %2}
11625 sar{l}\t{%b2, %0|%0, %b2}"
11626 [(set_attr "type" "ishift")
11627 (set_attr "mode" "SI")])
11629 (define_insn "*ashrsi3_1_zext"
11630 [(set (match_operand:DI 0 "register_operand" "=r,r")
11631 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11632 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11633 (clobber (reg:CC FLAGS_REG))]
11634 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11636 sar{l}\t{%2, %k0|%k0, %2}
11637 sar{l}\t{%b2, %k0|%k0, %b2}"
11638 [(set_attr "type" "ishift")
11639 (set_attr "mode" "SI")])
11641 ;; This pattern can't accept a variable shift count, since shifts by
11642 ;; zero don't affect the flags. We assume that shifts by constant
11643 ;; zero are optimized away.
11644 (define_insn "*ashrsi3_one_bit_cmp"
11645 [(set (reg FLAGS_REG)
11647 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11648 (match_operand:QI 2 "const1_operand" ""))
11650 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11651 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11652 "ix86_match_ccmode (insn, CCGOCmode)
11653 && (TARGET_SHIFT1 || optimize_size)
11654 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11656 [(set_attr "type" "ishift")
11657 (set (attr "length")
11658 (if_then_else (match_operand:SI 0 "register_operand" "")
11660 (const_string "*")))])
11662 (define_insn "*ashrsi3_one_bit_cconly"
11663 [(set (reg FLAGS_REG)
11665 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11666 (match_operand:QI 2 "const1_operand" ""))
11668 (clobber (match_scratch:SI 0 "=r"))]
11669 "ix86_match_ccmode (insn, CCGOCmode)
11670 && (TARGET_SHIFT1 || optimize_size)
11671 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11673 [(set_attr "type" "ishift")
11674 (set_attr "length" "2")])
11676 (define_insn "*ashrsi3_one_bit_cmp_zext"
11677 [(set (reg FLAGS_REG)
11679 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11680 (match_operand:QI 2 "const1_operand" ""))
11682 (set (match_operand:DI 0 "register_operand" "=r")
11683 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11684 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11685 && (TARGET_SHIFT1 || optimize_size)
11686 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11688 [(set_attr "type" "ishift")
11689 (set_attr "length" "2")])
11691 ;; This pattern can't accept a variable shift count, since shifts by
11692 ;; zero don't affect the flags. We assume that shifts by constant
11693 ;; zero are optimized away.
11694 (define_insn "*ashrsi3_cmp"
11695 [(set (reg FLAGS_REG)
11697 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11698 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11700 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11701 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11702 "ix86_match_ccmode (insn, CCGOCmode)
11703 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11705 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11706 "sar{l}\t{%2, %0|%0, %2}"
11707 [(set_attr "type" "ishift")
11708 (set_attr "mode" "SI")])
11710 (define_insn "*ashrsi3_cconly"
11711 [(set (reg FLAGS_REG)
11713 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11714 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11716 (clobber (match_scratch:SI 0 "=r"))]
11717 "ix86_match_ccmode (insn, CCGOCmode)
11718 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11720 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11721 "sar{l}\t{%2, %0|%0, %2}"
11722 [(set_attr "type" "ishift")
11723 (set_attr "mode" "SI")])
11725 (define_insn "*ashrsi3_cmp_zext"
11726 [(set (reg FLAGS_REG)
11728 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11729 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11731 (set (match_operand:DI 0 "register_operand" "=r")
11732 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11733 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11734 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11736 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11737 "sar{l}\t{%2, %k0|%k0, %2}"
11738 [(set_attr "type" "ishift")
11739 (set_attr "mode" "SI")])
11741 (define_expand "ashrhi3"
11742 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11743 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11744 (match_operand:QI 2 "nonmemory_operand" "")))
11745 (clobber (reg:CC FLAGS_REG))]
11746 "TARGET_HIMODE_MATH"
11747 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11749 (define_insn "*ashrhi3_1_one_bit"
11750 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11751 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11752 (match_operand:QI 2 "const1_operand" "")))
11753 (clobber (reg:CC FLAGS_REG))]
11754 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11755 && (TARGET_SHIFT1 || optimize_size)"
11757 [(set_attr "type" "ishift")
11758 (set (attr "length")
11759 (if_then_else (match_operand 0 "register_operand" "")
11761 (const_string "*")))])
11763 (define_insn "*ashrhi3_1"
11764 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11765 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11766 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11767 (clobber (reg:CC FLAGS_REG))]
11768 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11770 sar{w}\t{%2, %0|%0, %2}
11771 sar{w}\t{%b2, %0|%0, %b2}"
11772 [(set_attr "type" "ishift")
11773 (set_attr "mode" "HI")])
11775 ;; This pattern can't accept a variable shift count, since shifts by
11776 ;; zero don't affect the flags. We assume that shifts by constant
11777 ;; zero are optimized away.
11778 (define_insn "*ashrhi3_one_bit_cmp"
11779 [(set (reg FLAGS_REG)
11781 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782 (match_operand:QI 2 "const1_operand" ""))
11784 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11785 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11786 "ix86_match_ccmode (insn, CCGOCmode)
11787 && (TARGET_SHIFT1 || optimize_size)
11788 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11790 [(set_attr "type" "ishift")
11791 (set (attr "length")
11792 (if_then_else (match_operand 0 "register_operand" "")
11794 (const_string "*")))])
11796 (define_insn "*ashrhi3_one_bit_cconly"
11797 [(set (reg FLAGS_REG)
11799 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11800 (match_operand:QI 2 "const1_operand" ""))
11802 (clobber (match_scratch:HI 0 "=r"))]
11803 "ix86_match_ccmode (insn, CCGOCmode)
11804 && (TARGET_SHIFT1 || optimize_size)
11805 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11807 [(set_attr "type" "ishift")
11808 (set_attr "length" "2")])
11810 ;; This pattern can't accept a variable shift count, since shifts by
11811 ;; zero don't affect the flags. We assume that shifts by constant
11812 ;; zero are optimized away.
11813 (define_insn "*ashrhi3_cmp"
11814 [(set (reg FLAGS_REG)
11816 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11817 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11819 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11820 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11821 "ix86_match_ccmode (insn, CCGOCmode)
11822 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11824 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11825 "sar{w}\t{%2, %0|%0, %2}"
11826 [(set_attr "type" "ishift")
11827 (set_attr "mode" "HI")])
11829 (define_insn "*ashrhi3_cconly"
11830 [(set (reg FLAGS_REG)
11832 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11833 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11835 (clobber (match_scratch:HI 0 "=r"))]
11836 "ix86_match_ccmode (insn, CCGOCmode)
11837 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11839 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11840 "sar{w}\t{%2, %0|%0, %2}"
11841 [(set_attr "type" "ishift")
11842 (set_attr "mode" "HI")])
11844 (define_expand "ashrqi3"
11845 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11846 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11847 (match_operand:QI 2 "nonmemory_operand" "")))
11848 (clobber (reg:CC FLAGS_REG))]
11849 "TARGET_QIMODE_MATH"
11850 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11852 (define_insn "*ashrqi3_1_one_bit"
11853 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11854 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11855 (match_operand:QI 2 "const1_operand" "")))
11856 (clobber (reg:CC FLAGS_REG))]
11857 "ix86_binary_operator_ok (ASHIFTRT, QImode, 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 "*ashrqi3_1_one_bit_slp"
11867 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11868 (ashiftrt:QI (match_dup 0)
11869 (match_operand:QI 1 "const1_operand" "")))
11870 (clobber (reg:CC FLAGS_REG))]
11871 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11872 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11873 && (TARGET_SHIFT1 || optimize_size)"
11875 [(set_attr "type" "ishift1")
11876 (set (attr "length")
11877 (if_then_else (match_operand 0 "register_operand" "")
11879 (const_string "*")))])
11881 (define_insn "*ashrqi3_1"
11882 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11883 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11884 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11885 (clobber (reg:CC FLAGS_REG))]
11886 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11888 sar{b}\t{%2, %0|%0, %2}
11889 sar{b}\t{%b2, %0|%0, %b2}"
11890 [(set_attr "type" "ishift")
11891 (set_attr "mode" "QI")])
11893 (define_insn "*ashrqi3_1_slp"
11894 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11895 (ashiftrt:QI (match_dup 0)
11896 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11897 (clobber (reg:CC FLAGS_REG))]
11898 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11899 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11901 sar{b}\t{%1, %0|%0, %1}
11902 sar{b}\t{%b1, %0|%0, %b1}"
11903 [(set_attr "type" "ishift1")
11904 (set_attr "mode" "QI")])
11906 ;; This pattern can't accept a variable shift count, since shifts by
11907 ;; zero don't affect the flags. We assume that shifts by constant
11908 ;; zero are optimized away.
11909 (define_insn "*ashrqi3_one_bit_cmp"
11910 [(set (reg FLAGS_REG)
11912 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11913 (match_operand:QI 2 "const1_operand" "I"))
11915 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11916 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11917 "ix86_match_ccmode (insn, CCGOCmode)
11918 && (TARGET_SHIFT1 || optimize_size)
11919 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11921 [(set_attr "type" "ishift")
11922 (set (attr "length")
11923 (if_then_else (match_operand 0 "register_operand" "")
11925 (const_string "*")))])
11927 (define_insn "*ashrqi3_one_bit_cconly"
11928 [(set (reg FLAGS_REG)
11930 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11931 (match_operand:QI 2 "const1_operand" "I"))
11933 (clobber (match_scratch:QI 0 "=q"))]
11934 "ix86_match_ccmode (insn, CCGOCmode)
11935 && (TARGET_SHIFT1 || optimize_size)
11936 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11938 [(set_attr "type" "ishift")
11939 (set_attr "length" "2")])
11941 ;; This pattern can't accept a variable shift count, since shifts by
11942 ;; zero don't affect the flags. We assume that shifts by constant
11943 ;; zero are optimized away.
11944 (define_insn "*ashrqi3_cmp"
11945 [(set (reg FLAGS_REG)
11947 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11950 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11951 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11952 "ix86_match_ccmode (insn, CCGOCmode)
11953 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11955 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11956 "sar{b}\t{%2, %0|%0, %2}"
11957 [(set_attr "type" "ishift")
11958 (set_attr "mode" "QI")])
11960 (define_insn "*ashrqi3_cconly"
11961 [(set (reg FLAGS_REG)
11963 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11964 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11966 (clobber (match_scratch:QI 0 "=q"))]
11967 "ix86_match_ccmode (insn, CCGOCmode)
11968 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11970 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11971 "sar{b}\t{%2, %0|%0, %2}"
11972 [(set_attr "type" "ishift")
11973 (set_attr "mode" "QI")])
11976 ;; Logical shift instructions
11978 ;; See comment above `ashldi3' about how this works.
11980 (define_expand "lshrti3"
11981 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11982 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11983 (match_operand:QI 2 "nonmemory_operand" "")))
11984 (clobber (reg:CC FLAGS_REG))])]
11987 if (! immediate_operand (operands[2], QImode))
11989 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11992 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11996 (define_insn "lshrti3_1"
11997 [(set (match_operand:TI 0 "register_operand" "=r")
11998 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11999 (match_operand:QI 2 "register_operand" "c")))
12000 (clobber (match_scratch:DI 3 "=&r"))
12001 (clobber (reg:CC FLAGS_REG))]
12004 [(set_attr "type" "multi")])
12006 (define_insn "*lshrti3_2"
12007 [(set (match_operand:TI 0 "register_operand" "=r")
12008 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12009 (match_operand:QI 2 "immediate_operand" "O")))
12010 (clobber (reg:CC FLAGS_REG))]
12013 [(set_attr "type" "multi")])
12016 [(set (match_operand:TI 0 "register_operand" "")
12017 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12018 (match_operand:QI 2 "register_operand" "")))
12019 (clobber (match_scratch:DI 3 ""))
12020 (clobber (reg:CC FLAGS_REG))]
12021 "TARGET_64BIT && reload_completed"
12023 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12026 [(set (match_operand:TI 0 "register_operand" "")
12027 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12028 (match_operand:QI 2 "immediate_operand" "")))
12029 (clobber (reg:CC FLAGS_REG))]
12030 "TARGET_64BIT && reload_completed"
12032 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12034 (define_expand "lshrdi3"
12035 [(set (match_operand:DI 0 "shiftdi_operand" "")
12036 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12037 (match_operand:QI 2 "nonmemory_operand" "")))]
12039 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12041 (define_insn "*lshrdi3_1_one_bit_rex64"
12042 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12043 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12044 (match_operand:QI 2 "const1_operand" "")))
12045 (clobber (reg:CC FLAGS_REG))]
12046 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12047 && (TARGET_SHIFT1 || optimize_size)"
12049 [(set_attr "type" "ishift")
12050 (set (attr "length")
12051 (if_then_else (match_operand:DI 0 "register_operand" "")
12053 (const_string "*")))])
12055 (define_insn "*lshrdi3_1_rex64"
12056 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12057 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12058 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12059 (clobber (reg:CC FLAGS_REG))]
12060 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12062 shr{q}\t{%2, %0|%0, %2}
12063 shr{q}\t{%b2, %0|%0, %b2}"
12064 [(set_attr "type" "ishift")
12065 (set_attr "mode" "DI")])
12067 ;; This pattern can't accept a variable shift count, since shifts by
12068 ;; zero don't affect the flags. We assume that shifts by constant
12069 ;; zero are optimized away.
12070 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12071 [(set (reg FLAGS_REG)
12073 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074 (match_operand:QI 2 "const1_operand" ""))
12076 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12077 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12078 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12079 && (TARGET_SHIFT1 || optimize_size)
12080 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12082 [(set_attr "type" "ishift")
12083 (set (attr "length")
12084 (if_then_else (match_operand:DI 0 "register_operand" "")
12086 (const_string "*")))])
12088 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12089 [(set (reg FLAGS_REG)
12091 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12092 (match_operand:QI 2 "const1_operand" ""))
12094 (clobber (match_scratch:DI 0 "=r"))]
12095 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12096 && (TARGET_SHIFT1 || optimize_size)
12097 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12099 [(set_attr "type" "ishift")
12100 (set_attr "length" "2")])
12102 ;; This pattern can't accept a variable shift count, since shifts by
12103 ;; zero don't affect the flags. We assume that shifts by constant
12104 ;; zero are optimized away.
12105 (define_insn "*lshrdi3_cmp_rex64"
12106 [(set (reg FLAGS_REG)
12108 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12109 (match_operand:QI 2 "const_int_operand" "e"))
12111 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12112 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12113 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12114 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12116 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12117 "shr{q}\t{%2, %0|%0, %2}"
12118 [(set_attr "type" "ishift")
12119 (set_attr "mode" "DI")])
12121 (define_insn "*lshrdi3_cconly_rex64"
12122 [(set (reg FLAGS_REG)
12124 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12125 (match_operand:QI 2 "const_int_operand" "e"))
12127 (clobber (match_scratch:DI 0 "=r"))]
12128 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12129 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12131 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12132 "shr{q}\t{%2, %0|%0, %2}"
12133 [(set_attr "type" "ishift")
12134 (set_attr "mode" "DI")])
12136 (define_insn "*lshrdi3_1"
12137 [(set (match_operand:DI 0 "register_operand" "=r")
12138 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12139 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12140 (clobber (reg:CC FLAGS_REG))]
12143 [(set_attr "type" "multi")])
12145 ;; By default we don't ask for a scratch register, because when DImode
12146 ;; values are manipulated, registers are already at a premium. But if
12147 ;; we have one handy, we won't turn it away.
12149 [(match_scratch:SI 3 "r")
12150 (parallel [(set (match_operand:DI 0 "register_operand" "")
12151 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12152 (match_operand:QI 2 "nonmemory_operand" "")))
12153 (clobber (reg:CC FLAGS_REG))])
12155 "!TARGET_64BIT && TARGET_CMOVE"
12157 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12160 [(set (match_operand:DI 0 "register_operand" "")
12161 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12162 (match_operand:QI 2 "nonmemory_operand" "")))
12163 (clobber (reg:CC FLAGS_REG))]
12164 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12165 ? flow2_completed : reload_completed)"
12167 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12169 (define_expand "lshrsi3"
12170 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12171 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12172 (match_operand:QI 2 "nonmemory_operand" "")))
12173 (clobber (reg:CC FLAGS_REG))]
12175 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12177 (define_insn "*lshrsi3_1_one_bit"
12178 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12179 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12180 (match_operand:QI 2 "const1_operand" "")))
12181 (clobber (reg:CC FLAGS_REG))]
12182 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12183 && (TARGET_SHIFT1 || optimize_size)"
12185 [(set_attr "type" "ishift")
12186 (set (attr "length")
12187 (if_then_else (match_operand:SI 0 "register_operand" "")
12189 (const_string "*")))])
12191 (define_insn "*lshrsi3_1_one_bit_zext"
12192 [(set (match_operand:DI 0 "register_operand" "=r")
12193 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12194 (match_operand:QI 2 "const1_operand" "")))
12195 (clobber (reg:CC FLAGS_REG))]
12196 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12197 && (TARGET_SHIFT1 || optimize_size)"
12199 [(set_attr "type" "ishift")
12200 (set_attr "length" "2")])
12202 (define_insn "*lshrsi3_1"
12203 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12204 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12205 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12206 (clobber (reg:CC FLAGS_REG))]
12207 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12209 shr{l}\t{%2, %0|%0, %2}
12210 shr{l}\t{%b2, %0|%0, %b2}"
12211 [(set_attr "type" "ishift")
12212 (set_attr "mode" "SI")])
12214 (define_insn "*lshrsi3_1_zext"
12215 [(set (match_operand:DI 0 "register_operand" "=r,r")
12217 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12218 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12219 (clobber (reg:CC FLAGS_REG))]
12220 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12222 shr{l}\t{%2, %k0|%k0, %2}
12223 shr{l}\t{%b2, %k0|%k0, %b2}"
12224 [(set_attr "type" "ishift")
12225 (set_attr "mode" "SI")])
12227 ;; This pattern can't accept a variable shift count, since shifts by
12228 ;; zero don't affect the flags. We assume that shifts by constant
12229 ;; zero are optimized away.
12230 (define_insn "*lshrsi3_one_bit_cmp"
12231 [(set (reg FLAGS_REG)
12233 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const1_operand" ""))
12236 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12237 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12238 "ix86_match_ccmode (insn, CCGOCmode)
12239 && (TARGET_SHIFT1 || optimize_size)
12240 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12242 [(set_attr "type" "ishift")
12243 (set (attr "length")
12244 (if_then_else (match_operand:SI 0 "register_operand" "")
12246 (const_string "*")))])
12248 (define_insn "*lshrsi3_one_bit_cconly"
12249 [(set (reg FLAGS_REG)
12251 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12252 (match_operand:QI 2 "const1_operand" ""))
12254 (clobber (match_scratch:SI 0 "=r"))]
12255 "ix86_match_ccmode (insn, CCGOCmode)
12256 && (TARGET_SHIFT1 || optimize_size)
12257 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12259 [(set_attr "type" "ishift")
12260 (set_attr "length" "2")])
12262 (define_insn "*lshrsi3_cmp_one_bit_zext"
12263 [(set (reg FLAGS_REG)
12265 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12266 (match_operand:QI 2 "const1_operand" ""))
12268 (set (match_operand:DI 0 "register_operand" "=r")
12269 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12270 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12271 && (TARGET_SHIFT1 || optimize_size)
12272 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12274 [(set_attr "type" "ishift")
12275 (set_attr "length" "2")])
12277 ;; This pattern can't accept a variable shift count, since shifts by
12278 ;; zero don't affect the flags. We assume that shifts by constant
12279 ;; zero are optimized away.
12280 (define_insn "*lshrsi3_cmp"
12281 [(set (reg FLAGS_REG)
12283 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12284 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12286 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12287 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12288 "ix86_match_ccmode (insn, CCGOCmode)
12289 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12291 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12292 "shr{l}\t{%2, %0|%0, %2}"
12293 [(set_attr "type" "ishift")
12294 (set_attr "mode" "SI")])
12296 (define_insn "*lshrsi3_cconly"
12297 [(set (reg FLAGS_REG)
12299 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12300 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12302 (clobber (match_scratch:SI 0 "=r"))]
12303 "ix86_match_ccmode (insn, CCGOCmode)
12304 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12306 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12307 "shr{l}\t{%2, %0|%0, %2}"
12308 [(set_attr "type" "ishift")
12309 (set_attr "mode" "SI")])
12311 (define_insn "*lshrsi3_cmp_zext"
12312 [(set (reg FLAGS_REG)
12314 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12315 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12317 (set (match_operand:DI 0 "register_operand" "=r")
12318 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12319 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12320 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12322 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12323 "shr{l}\t{%2, %k0|%k0, %2}"
12324 [(set_attr "type" "ishift")
12325 (set_attr "mode" "SI")])
12327 (define_expand "lshrhi3"
12328 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12329 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12330 (match_operand:QI 2 "nonmemory_operand" "")))
12331 (clobber (reg:CC FLAGS_REG))]
12332 "TARGET_HIMODE_MATH"
12333 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12335 (define_insn "*lshrhi3_1_one_bit"
12336 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12337 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12338 (match_operand:QI 2 "const1_operand" "")))
12339 (clobber (reg:CC FLAGS_REG))]
12340 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12341 && (TARGET_SHIFT1 || optimize_size)"
12343 [(set_attr "type" "ishift")
12344 (set (attr "length")
12345 (if_then_else (match_operand 0 "register_operand" "")
12347 (const_string "*")))])
12349 (define_insn "*lshrhi3_1"
12350 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12351 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12352 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12353 (clobber (reg:CC FLAGS_REG))]
12354 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12356 shr{w}\t{%2, %0|%0, %2}
12357 shr{w}\t{%b2, %0|%0, %b2}"
12358 [(set_attr "type" "ishift")
12359 (set_attr "mode" "HI")])
12361 ;; This pattern can't accept a variable shift count, since shifts by
12362 ;; zero don't affect the flags. We assume that shifts by constant
12363 ;; zero are optimized away.
12364 (define_insn "*lshrhi3_one_bit_cmp"
12365 [(set (reg FLAGS_REG)
12367 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const1_operand" ""))
12370 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12371 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12372 "ix86_match_ccmode (insn, CCGOCmode)
12373 && (TARGET_SHIFT1 || optimize_size)
12374 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12376 [(set_attr "type" "ishift")
12377 (set (attr "length")
12378 (if_then_else (match_operand:SI 0 "register_operand" "")
12380 (const_string "*")))])
12382 (define_insn "*lshrhi3_one_bit_cconly"
12383 [(set (reg FLAGS_REG)
12385 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12386 (match_operand:QI 2 "const1_operand" ""))
12388 (clobber (match_scratch:HI 0 "=r"))]
12389 "ix86_match_ccmode (insn, CCGOCmode)
12390 && (TARGET_SHIFT1 || optimize_size)
12391 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12393 [(set_attr "type" "ishift")
12394 (set_attr "length" "2")])
12396 ;; This pattern can't accept a variable shift count, since shifts by
12397 ;; zero don't affect the flags. We assume that shifts by constant
12398 ;; zero are optimized away.
12399 (define_insn "*lshrhi3_cmp"
12400 [(set (reg FLAGS_REG)
12402 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12403 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12405 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12406 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12407 "ix86_match_ccmode (insn, CCGOCmode)
12408 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12410 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12411 "shr{w}\t{%2, %0|%0, %2}"
12412 [(set_attr "type" "ishift")
12413 (set_attr "mode" "HI")])
12415 (define_insn "*lshrhi3_cconly"
12416 [(set (reg FLAGS_REG)
12418 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12419 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12421 (clobber (match_scratch:HI 0 "=r"))]
12422 "ix86_match_ccmode (insn, CCGOCmode)
12423 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12425 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12426 "shr{w}\t{%2, %0|%0, %2}"
12427 [(set_attr "type" "ishift")
12428 (set_attr "mode" "HI")])
12430 (define_expand "lshrqi3"
12431 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12432 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12433 (match_operand:QI 2 "nonmemory_operand" "")))
12434 (clobber (reg:CC FLAGS_REG))]
12435 "TARGET_QIMODE_MATH"
12436 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12438 (define_insn "*lshrqi3_1_one_bit"
12439 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12440 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12441 (match_operand:QI 2 "const1_operand" "")))
12442 (clobber (reg:CC FLAGS_REG))]
12443 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12444 && (TARGET_SHIFT1 || optimize_size)"
12446 [(set_attr "type" "ishift")
12447 (set (attr "length")
12448 (if_then_else (match_operand 0 "register_operand" "")
12450 (const_string "*")))])
12452 (define_insn "*lshrqi3_1_one_bit_slp"
12453 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12454 (lshiftrt:QI (match_dup 0)
12455 (match_operand:QI 1 "const1_operand" "")))
12456 (clobber (reg:CC FLAGS_REG))]
12457 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12458 && (TARGET_SHIFT1 || optimize_size)"
12460 [(set_attr "type" "ishift1")
12461 (set (attr "length")
12462 (if_then_else (match_operand 0 "register_operand" "")
12464 (const_string "*")))])
12466 (define_insn "*lshrqi3_1"
12467 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12468 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12469 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12470 (clobber (reg:CC FLAGS_REG))]
12471 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12473 shr{b}\t{%2, %0|%0, %2}
12474 shr{b}\t{%b2, %0|%0, %b2}"
12475 [(set_attr "type" "ishift")
12476 (set_attr "mode" "QI")])
12478 (define_insn "*lshrqi3_1_slp"
12479 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12480 (lshiftrt:QI (match_dup 0)
12481 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12482 (clobber (reg:CC FLAGS_REG))]
12483 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12484 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12486 shr{b}\t{%1, %0|%0, %1}
12487 shr{b}\t{%b1, %0|%0, %b1}"
12488 [(set_attr "type" "ishift1")
12489 (set_attr "mode" "QI")])
12491 ;; This pattern can't accept a variable shift count, since shifts by
12492 ;; zero don't affect the flags. We assume that shifts by constant
12493 ;; zero are optimized away.
12494 (define_insn "*lshrqi2_one_bit_cmp"
12495 [(set (reg FLAGS_REG)
12497 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12498 (match_operand:QI 2 "const1_operand" ""))
12500 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12501 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12502 "ix86_match_ccmode (insn, CCGOCmode)
12503 && (TARGET_SHIFT1 || optimize_size)
12504 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12506 [(set_attr "type" "ishift")
12507 (set (attr "length")
12508 (if_then_else (match_operand:SI 0 "register_operand" "")
12510 (const_string "*")))])
12512 (define_insn "*lshrqi2_one_bit_cconly"
12513 [(set (reg FLAGS_REG)
12515 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12516 (match_operand:QI 2 "const1_operand" ""))
12518 (clobber (match_scratch:QI 0 "=q"))]
12519 "ix86_match_ccmode (insn, CCGOCmode)
12520 && (TARGET_SHIFT1 || optimize_size)
12521 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12523 [(set_attr "type" "ishift")
12524 (set_attr "length" "2")])
12526 ;; This pattern can't accept a variable shift count, since shifts by
12527 ;; zero don't affect the flags. We assume that shifts by constant
12528 ;; zero are optimized away.
12529 (define_insn "*lshrqi2_cmp"
12530 [(set (reg FLAGS_REG)
12532 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12533 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12535 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12536 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12537 "ix86_match_ccmode (insn, CCGOCmode)
12538 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12540 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12541 "shr{b}\t{%2, %0|%0, %2}"
12542 [(set_attr "type" "ishift")
12543 (set_attr "mode" "QI")])
12545 (define_insn "*lshrqi2_cconly"
12546 [(set (reg FLAGS_REG)
12548 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12549 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12551 (clobber (match_scratch:QI 0 "=q"))]
12552 "ix86_match_ccmode (insn, CCGOCmode)
12553 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12555 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12556 "shr{b}\t{%2, %0|%0, %2}"
12557 [(set_attr "type" "ishift")
12558 (set_attr "mode" "QI")])
12560 ;; Rotate instructions
12562 (define_expand "rotldi3"
12563 [(set (match_operand:DI 0 "shiftdi_operand" "")
12564 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12565 (match_operand:QI 2 "nonmemory_operand" "")))
12566 (clobber (reg:CC FLAGS_REG))]
12571 ix86_expand_binary_operator (ROTATE, DImode, operands);
12574 if (!const_1_to_31_operand (operands[2], VOIDmode))
12576 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12580 ;; Implement rotation using two double-precision shift instructions
12581 ;; and a scratch register.
12582 (define_insn_and_split "ix86_rotldi3"
12583 [(set (match_operand:DI 0 "register_operand" "=r")
12584 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12585 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12586 (clobber (reg:CC FLAGS_REG))
12587 (clobber (match_scratch:SI 3 "=&r"))]
12590 "&& reload_completed"
12591 [(set (match_dup 3) (match_dup 4))
12593 [(set (match_dup 4)
12594 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12595 (lshiftrt:SI (match_dup 5)
12596 (minus:QI (const_int 32) (match_dup 2)))))
12597 (clobber (reg:CC FLAGS_REG))])
12599 [(set (match_dup 5)
12600 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12601 (lshiftrt:SI (match_dup 3)
12602 (minus:QI (const_int 32) (match_dup 2)))))
12603 (clobber (reg:CC FLAGS_REG))])]
12604 "split_di (operands, 1, operands + 4, operands + 5);")
12606 (define_insn "*rotlsi3_1_one_bit_rex64"
12607 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12608 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12609 (match_operand:QI 2 "const1_operand" "")))
12610 (clobber (reg:CC FLAGS_REG))]
12611 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12612 && (TARGET_SHIFT1 || optimize_size)"
12614 [(set_attr "type" "rotate")
12615 (set (attr "length")
12616 (if_then_else (match_operand:DI 0 "register_operand" "")
12618 (const_string "*")))])
12620 (define_insn "*rotldi3_1_rex64"
12621 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12622 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12623 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12624 (clobber (reg:CC FLAGS_REG))]
12625 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12627 rol{q}\t{%2, %0|%0, %2}
12628 rol{q}\t{%b2, %0|%0, %b2}"
12629 [(set_attr "type" "rotate")
12630 (set_attr "mode" "DI")])
12632 (define_expand "rotlsi3"
12633 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12634 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12635 (match_operand:QI 2 "nonmemory_operand" "")))
12636 (clobber (reg:CC FLAGS_REG))]
12638 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12640 (define_insn "*rotlsi3_1_one_bit"
12641 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12642 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12643 (match_operand:QI 2 "const1_operand" "")))
12644 (clobber (reg:CC FLAGS_REG))]
12645 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12646 && (TARGET_SHIFT1 || optimize_size)"
12648 [(set_attr "type" "rotate")
12649 (set (attr "length")
12650 (if_then_else (match_operand:SI 0 "register_operand" "")
12652 (const_string "*")))])
12654 (define_insn "*rotlsi3_1_one_bit_zext"
12655 [(set (match_operand:DI 0 "register_operand" "=r")
12657 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12658 (match_operand:QI 2 "const1_operand" ""))))
12659 (clobber (reg:CC FLAGS_REG))]
12660 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12661 && (TARGET_SHIFT1 || optimize_size)"
12663 [(set_attr "type" "rotate")
12664 (set_attr "length" "2")])
12666 (define_insn "*rotlsi3_1"
12667 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12668 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12669 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12670 (clobber (reg:CC FLAGS_REG))]
12671 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12673 rol{l}\t{%2, %0|%0, %2}
12674 rol{l}\t{%b2, %0|%0, %b2}"
12675 [(set_attr "type" "rotate")
12676 (set_attr "mode" "SI")])
12678 (define_insn "*rotlsi3_1_zext"
12679 [(set (match_operand:DI 0 "register_operand" "=r,r")
12681 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12682 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12683 (clobber (reg:CC FLAGS_REG))]
12684 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12686 rol{l}\t{%2, %k0|%k0, %2}
12687 rol{l}\t{%b2, %k0|%k0, %b2}"
12688 [(set_attr "type" "rotate")
12689 (set_attr "mode" "SI")])
12691 (define_expand "rotlhi3"
12692 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12693 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12694 (match_operand:QI 2 "nonmemory_operand" "")))
12695 (clobber (reg:CC FLAGS_REG))]
12696 "TARGET_HIMODE_MATH"
12697 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12699 (define_insn "*rotlhi3_1_one_bit"
12700 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12701 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12702 (match_operand:QI 2 "const1_operand" "")))
12703 (clobber (reg:CC FLAGS_REG))]
12704 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12705 && (TARGET_SHIFT1 || optimize_size)"
12707 [(set_attr "type" "rotate")
12708 (set (attr "length")
12709 (if_then_else (match_operand 0 "register_operand" "")
12711 (const_string "*")))])
12713 (define_insn "*rotlhi3_1"
12714 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12715 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12716 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12717 (clobber (reg:CC FLAGS_REG))]
12718 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12720 rol{w}\t{%2, %0|%0, %2}
12721 rol{w}\t{%b2, %0|%0, %b2}"
12722 [(set_attr "type" "rotate")
12723 (set_attr "mode" "HI")])
12725 (define_expand "rotlqi3"
12726 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12727 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12728 (match_operand:QI 2 "nonmemory_operand" "")))
12729 (clobber (reg:CC FLAGS_REG))]
12730 "TARGET_QIMODE_MATH"
12731 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12733 (define_insn "*rotlqi3_1_one_bit_slp"
12734 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12735 (rotate:QI (match_dup 0)
12736 (match_operand:QI 1 "const1_operand" "")))
12737 (clobber (reg:CC FLAGS_REG))]
12738 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12739 && (TARGET_SHIFT1 || optimize_size)"
12741 [(set_attr "type" "rotate1")
12742 (set (attr "length")
12743 (if_then_else (match_operand 0 "register_operand" "")
12745 (const_string "*")))])
12747 (define_insn "*rotlqi3_1_one_bit"
12748 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12749 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12750 (match_operand:QI 2 "const1_operand" "")))
12751 (clobber (reg:CC FLAGS_REG))]
12752 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12753 && (TARGET_SHIFT1 || optimize_size)"
12755 [(set_attr "type" "rotate")
12756 (set (attr "length")
12757 (if_then_else (match_operand 0 "register_operand" "")
12759 (const_string "*")))])
12761 (define_insn "*rotlqi3_1_slp"
12762 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12763 (rotate:QI (match_dup 0)
12764 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12765 (clobber (reg:CC FLAGS_REG))]
12766 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12767 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12769 rol{b}\t{%1, %0|%0, %1}
12770 rol{b}\t{%b1, %0|%0, %b1}"
12771 [(set_attr "type" "rotate1")
12772 (set_attr "mode" "QI")])
12774 (define_insn "*rotlqi3_1"
12775 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12776 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12777 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12778 (clobber (reg:CC FLAGS_REG))]
12779 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12781 rol{b}\t{%2, %0|%0, %2}
12782 rol{b}\t{%b2, %0|%0, %b2}"
12783 [(set_attr "type" "rotate")
12784 (set_attr "mode" "QI")])
12786 (define_expand "rotrdi3"
12787 [(set (match_operand:DI 0 "shiftdi_operand" "")
12788 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12789 (match_operand:QI 2 "nonmemory_operand" "")))
12790 (clobber (reg:CC FLAGS_REG))]
12795 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12798 if (!const_1_to_31_operand (operands[2], VOIDmode))
12800 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12804 ;; Implement rotation using two double-precision shift instructions
12805 ;; and a scratch register.
12806 (define_insn_and_split "ix86_rotrdi3"
12807 [(set (match_operand:DI 0 "register_operand" "=r")
12808 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12809 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12810 (clobber (reg:CC FLAGS_REG))
12811 (clobber (match_scratch:SI 3 "=&r"))]
12814 "&& reload_completed"
12815 [(set (match_dup 3) (match_dup 4))
12817 [(set (match_dup 4)
12818 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12819 (ashift:SI (match_dup 5)
12820 (minus:QI (const_int 32) (match_dup 2)))))
12821 (clobber (reg:CC FLAGS_REG))])
12823 [(set (match_dup 5)
12824 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12825 (ashift:SI (match_dup 3)
12826 (minus:QI (const_int 32) (match_dup 2)))))
12827 (clobber (reg:CC FLAGS_REG))])]
12828 "split_di (operands, 1, operands + 4, operands + 5);")
12830 (define_insn "*rotrdi3_1_one_bit_rex64"
12831 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12832 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12833 (match_operand:QI 2 "const1_operand" "")))
12834 (clobber (reg:CC FLAGS_REG))]
12835 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12836 && (TARGET_SHIFT1 || optimize_size)"
12838 [(set_attr "type" "rotate")
12839 (set (attr "length")
12840 (if_then_else (match_operand:DI 0 "register_operand" "")
12842 (const_string "*")))])
12844 (define_insn "*rotrdi3_1_rex64"
12845 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12846 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12847 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12848 (clobber (reg:CC FLAGS_REG))]
12849 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12851 ror{q}\t{%2, %0|%0, %2}
12852 ror{q}\t{%b2, %0|%0, %b2}"
12853 [(set_attr "type" "rotate")
12854 (set_attr "mode" "DI")])
12856 (define_expand "rotrsi3"
12857 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12858 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12859 (match_operand:QI 2 "nonmemory_operand" "")))
12860 (clobber (reg:CC FLAGS_REG))]
12862 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12864 (define_insn "*rotrsi3_1_one_bit"
12865 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12866 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12867 (match_operand:QI 2 "const1_operand" "")))
12868 (clobber (reg:CC FLAGS_REG))]
12869 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12870 && (TARGET_SHIFT1 || optimize_size)"
12872 [(set_attr "type" "rotate")
12873 (set (attr "length")
12874 (if_then_else (match_operand:SI 0 "register_operand" "")
12876 (const_string "*")))])
12878 (define_insn "*rotrsi3_1_one_bit_zext"
12879 [(set (match_operand:DI 0 "register_operand" "=r")
12881 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12882 (match_operand:QI 2 "const1_operand" ""))))
12883 (clobber (reg:CC FLAGS_REG))]
12884 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12885 && (TARGET_SHIFT1 || optimize_size)"
12887 [(set_attr "type" "rotate")
12888 (set (attr "length")
12889 (if_then_else (match_operand:SI 0 "register_operand" "")
12891 (const_string "*")))])
12893 (define_insn "*rotrsi3_1"
12894 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12895 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12896 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12897 (clobber (reg:CC FLAGS_REG))]
12898 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12900 ror{l}\t{%2, %0|%0, %2}
12901 ror{l}\t{%b2, %0|%0, %b2}"
12902 [(set_attr "type" "rotate")
12903 (set_attr "mode" "SI")])
12905 (define_insn "*rotrsi3_1_zext"
12906 [(set (match_operand:DI 0 "register_operand" "=r,r")
12908 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12909 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12910 (clobber (reg:CC FLAGS_REG))]
12911 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12913 ror{l}\t{%2, %k0|%k0, %2}
12914 ror{l}\t{%b2, %k0|%k0, %b2}"
12915 [(set_attr "type" "rotate")
12916 (set_attr "mode" "SI")])
12918 (define_expand "rotrhi3"
12919 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12920 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12921 (match_operand:QI 2 "nonmemory_operand" "")))
12922 (clobber (reg:CC FLAGS_REG))]
12923 "TARGET_HIMODE_MATH"
12924 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12926 (define_insn "*rotrhi3_one_bit"
12927 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12928 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12929 (match_operand:QI 2 "const1_operand" "")))
12930 (clobber (reg:CC FLAGS_REG))]
12931 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12932 && (TARGET_SHIFT1 || optimize_size)"
12934 [(set_attr "type" "rotate")
12935 (set (attr "length")
12936 (if_then_else (match_operand 0 "register_operand" "")
12938 (const_string "*")))])
12940 (define_insn "*rotrhi3"
12941 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12942 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12943 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12944 (clobber (reg:CC FLAGS_REG))]
12945 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12947 ror{w}\t{%2, %0|%0, %2}
12948 ror{w}\t{%b2, %0|%0, %b2}"
12949 [(set_attr "type" "rotate")
12950 (set_attr "mode" "HI")])
12952 (define_expand "rotrqi3"
12953 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12954 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12955 (match_operand:QI 2 "nonmemory_operand" "")))
12956 (clobber (reg:CC FLAGS_REG))]
12957 "TARGET_QIMODE_MATH"
12958 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12960 (define_insn "*rotrqi3_1_one_bit"
12961 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12962 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12963 (match_operand:QI 2 "const1_operand" "")))
12964 (clobber (reg:CC FLAGS_REG))]
12965 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12966 && (TARGET_SHIFT1 || optimize_size)"
12968 [(set_attr "type" "rotate")
12969 (set (attr "length")
12970 (if_then_else (match_operand 0 "register_operand" "")
12972 (const_string "*")))])
12974 (define_insn "*rotrqi3_1_one_bit_slp"
12975 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12976 (rotatert:QI (match_dup 0)
12977 (match_operand:QI 1 "const1_operand" "")))
12978 (clobber (reg:CC FLAGS_REG))]
12979 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12980 && (TARGET_SHIFT1 || optimize_size)"
12982 [(set_attr "type" "rotate1")
12983 (set (attr "length")
12984 (if_then_else (match_operand 0 "register_operand" "")
12986 (const_string "*")))])
12988 (define_insn "*rotrqi3_1"
12989 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12990 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12991 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12992 (clobber (reg:CC FLAGS_REG))]
12993 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12995 ror{b}\t{%2, %0|%0, %2}
12996 ror{b}\t{%b2, %0|%0, %b2}"
12997 [(set_attr "type" "rotate")
12998 (set_attr "mode" "QI")])
13000 (define_insn "*rotrqi3_1_slp"
13001 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13002 (rotatert:QI (match_dup 0)
13003 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13004 (clobber (reg:CC FLAGS_REG))]
13005 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13006 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13008 ror{b}\t{%1, %0|%0, %1}
13009 ror{b}\t{%b1, %0|%0, %b1}"
13010 [(set_attr "type" "rotate1")
13011 (set_attr "mode" "QI")])
13013 ;; Bit set / bit test instructions
13015 (define_expand "extv"
13016 [(set (match_operand:SI 0 "register_operand" "")
13017 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13018 (match_operand:SI 2 "const8_operand" "")
13019 (match_operand:SI 3 "const8_operand" "")))]
13022 /* Handle extractions from %ah et al. */
13023 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13026 /* From mips.md: extract_bit_field doesn't verify that our source
13027 matches the predicate, so check it again here. */
13028 if (! ext_register_operand (operands[1], VOIDmode))
13032 (define_expand "extzv"
13033 [(set (match_operand:SI 0 "register_operand" "")
13034 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13035 (match_operand:SI 2 "const8_operand" "")
13036 (match_operand:SI 3 "const8_operand" "")))]
13039 /* Handle extractions from %ah et al. */
13040 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13043 /* From mips.md: extract_bit_field doesn't verify that our source
13044 matches the predicate, so check it again here. */
13045 if (! ext_register_operand (operands[1], VOIDmode))
13049 (define_expand "insv"
13050 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13051 (match_operand 1 "const8_operand" "")
13052 (match_operand 2 "const8_operand" ""))
13053 (match_operand 3 "register_operand" ""))]
13056 /* Handle insertions to %ah et al. */
13057 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13060 /* From mips.md: insert_bit_field doesn't verify that our source
13061 matches the predicate, so check it again here. */
13062 if (! ext_register_operand (operands[0], VOIDmode))
13066 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13068 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13073 ;; %%% bts, btr, btc, bt.
13074 ;; In general these instructions are *slow* when applied to memory,
13075 ;; since they enforce atomic operation. When applied to registers,
13076 ;; it depends on the cpu implementation. They're never faster than
13077 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13078 ;; no point. But in 64-bit, we can't hold the relevant immediates
13079 ;; within the instruction itself, so operating on bits in the high
13080 ;; 32-bits of a register becomes easier.
13082 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13083 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13084 ;; negdf respectively, so they can never be disabled entirely.
13086 (define_insn "*btsq"
13087 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13089 (match_operand:DI 1 "const_0_to_63_operand" ""))
13091 (clobber (reg:CC FLAGS_REG))]
13092 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13094 [(set_attr "type" "alu1")])
13096 (define_insn "*btrq"
13097 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13099 (match_operand:DI 1 "const_0_to_63_operand" ""))
13101 (clobber (reg:CC FLAGS_REG))]
13102 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13104 [(set_attr "type" "alu1")])
13106 (define_insn "*btcq"
13107 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13109 (match_operand:DI 1 "const_0_to_63_operand" ""))
13110 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13111 (clobber (reg:CC FLAGS_REG))]
13112 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13114 [(set_attr "type" "alu1")])
13116 ;; Allow Nocona to avoid these instructions if a register is available.
13119 [(match_scratch:DI 2 "r")
13120 (parallel [(set (zero_extract:DI
13121 (match_operand:DI 0 "register_operand" "")
13123 (match_operand:DI 1 "const_0_to_63_operand" ""))
13125 (clobber (reg:CC FLAGS_REG))])]
13126 "TARGET_64BIT && !TARGET_USE_BT"
13129 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13132 if (HOST_BITS_PER_WIDE_INT >= 64)
13133 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13134 else if (i < HOST_BITS_PER_WIDE_INT)
13135 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13137 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13139 op1 = immed_double_const (lo, hi, DImode);
13142 emit_move_insn (operands[2], op1);
13146 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13151 [(match_scratch:DI 2 "r")
13152 (parallel [(set (zero_extract:DI
13153 (match_operand:DI 0 "register_operand" "")
13155 (match_operand:DI 1 "const_0_to_63_operand" ""))
13157 (clobber (reg:CC FLAGS_REG))])]
13158 "TARGET_64BIT && !TARGET_USE_BT"
13161 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13164 if (HOST_BITS_PER_WIDE_INT >= 64)
13165 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13166 else if (i < HOST_BITS_PER_WIDE_INT)
13167 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13169 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13171 op1 = immed_double_const (~lo, ~hi, DImode);
13174 emit_move_insn (operands[2], op1);
13178 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13183 [(match_scratch:DI 2 "r")
13184 (parallel [(set (zero_extract:DI
13185 (match_operand:DI 0 "register_operand" "")
13187 (match_operand:DI 1 "const_0_to_63_operand" ""))
13188 (not:DI (zero_extract:DI
13189 (match_dup 0) (const_int 1) (match_dup 1))))
13190 (clobber (reg:CC FLAGS_REG))])]
13191 "TARGET_64BIT && !TARGET_USE_BT"
13194 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13197 if (HOST_BITS_PER_WIDE_INT >= 64)
13198 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13199 else if (i < HOST_BITS_PER_WIDE_INT)
13200 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13202 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13204 op1 = immed_double_const (lo, hi, DImode);
13207 emit_move_insn (operands[2], op1);
13211 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13215 ;; Store-flag instructions.
13217 ;; For all sCOND expanders, also expand the compare or test insn that
13218 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13220 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13221 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13222 ;; way, which can later delete the movzx if only QImode is needed.
13224 (define_expand "seq"
13225 [(set (match_operand:QI 0 "register_operand" "")
13226 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13230 (define_expand "sne"
13231 [(set (match_operand:QI 0 "register_operand" "")
13232 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13236 (define_expand "sgt"
13237 [(set (match_operand:QI 0 "register_operand" "")
13238 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13242 (define_expand "sgtu"
13243 [(set (match_operand:QI 0 "register_operand" "")
13244 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13248 (define_expand "slt"
13249 [(set (match_operand:QI 0 "register_operand" "")
13250 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13254 (define_expand "sltu"
13255 [(set (match_operand:QI 0 "register_operand" "")
13256 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13260 (define_expand "sge"
13261 [(set (match_operand:QI 0 "register_operand" "")
13262 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13266 (define_expand "sgeu"
13267 [(set (match_operand:QI 0 "register_operand" "")
13268 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13272 (define_expand "sle"
13273 [(set (match_operand:QI 0 "register_operand" "")
13274 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13278 (define_expand "sleu"
13279 [(set (match_operand:QI 0 "register_operand" "")
13280 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13284 (define_expand "sunordered"
13285 [(set (match_operand:QI 0 "register_operand" "")
13286 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13287 "TARGET_80387 || TARGET_SSE"
13288 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13290 (define_expand "sordered"
13291 [(set (match_operand:QI 0 "register_operand" "")
13292 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13296 (define_expand "suneq"
13297 [(set (match_operand:QI 0 "register_operand" "")
13298 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13299 "TARGET_80387 || TARGET_SSE"
13300 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13302 (define_expand "sunge"
13303 [(set (match_operand:QI 0 "register_operand" "")
13304 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13305 "TARGET_80387 || TARGET_SSE"
13306 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13308 (define_expand "sungt"
13309 [(set (match_operand:QI 0 "register_operand" "")
13310 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311 "TARGET_80387 || TARGET_SSE"
13312 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13314 (define_expand "sunle"
13315 [(set (match_operand:QI 0 "register_operand" "")
13316 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13317 "TARGET_80387 || TARGET_SSE"
13318 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13320 (define_expand "sunlt"
13321 [(set (match_operand:QI 0 "register_operand" "")
13322 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13323 "TARGET_80387 || TARGET_SSE"
13324 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13326 (define_expand "sltgt"
13327 [(set (match_operand:QI 0 "register_operand" "")
13328 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13329 "TARGET_80387 || TARGET_SSE"
13330 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13332 (define_insn "*setcc_1"
13333 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13334 (match_operator:QI 1 "ix86_comparison_operator"
13335 [(reg FLAGS_REG) (const_int 0)]))]
13338 [(set_attr "type" "setcc")
13339 (set_attr "mode" "QI")])
13341 (define_insn "*setcc_2"
13342 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13343 (match_operator:QI 1 "ix86_comparison_operator"
13344 [(reg FLAGS_REG) (const_int 0)]))]
13347 [(set_attr "type" "setcc")
13348 (set_attr "mode" "QI")])
13350 ;; In general it is not safe to assume too much about CCmode registers,
13351 ;; so simplify-rtx stops when it sees a second one. Under certain
13352 ;; conditions this is safe on x86, so help combine not create
13359 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13360 (ne:QI (match_operator 1 "ix86_comparison_operator"
13361 [(reg FLAGS_REG) (const_int 0)])
13364 [(set (match_dup 0) (match_dup 1))]
13366 PUT_MODE (operands[1], QImode);
13370 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13371 (ne:QI (match_operator 1 "ix86_comparison_operator"
13372 [(reg FLAGS_REG) (const_int 0)])
13375 [(set (match_dup 0) (match_dup 1))]
13377 PUT_MODE (operands[1], QImode);
13381 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13382 (eq:QI (match_operator 1 "ix86_comparison_operator"
13383 [(reg FLAGS_REG) (const_int 0)])
13386 [(set (match_dup 0) (match_dup 1))]
13388 rtx new_op1 = copy_rtx (operands[1]);
13389 operands[1] = new_op1;
13390 PUT_MODE (new_op1, QImode);
13391 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13392 GET_MODE (XEXP (new_op1, 0))));
13394 /* Make sure that (a) the CCmode we have for the flags is strong
13395 enough for the reversed compare or (b) we have a valid FP compare. */
13396 if (! ix86_comparison_operator (new_op1, VOIDmode))
13401 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13402 (eq:QI (match_operator 1 "ix86_comparison_operator"
13403 [(reg FLAGS_REG) (const_int 0)])
13406 [(set (match_dup 0) (match_dup 1))]
13408 rtx new_op1 = copy_rtx (operands[1]);
13409 operands[1] = new_op1;
13410 PUT_MODE (new_op1, QImode);
13411 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13412 GET_MODE (XEXP (new_op1, 0))));
13414 /* Make sure that (a) the CCmode we have for the flags is strong
13415 enough for the reversed compare or (b) we have a valid FP compare. */
13416 if (! ix86_comparison_operator (new_op1, VOIDmode))
13420 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13421 ;; subsequent logical operations are used to imitate conditional moves.
13422 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13425 (define_insn "*sse_setccsf"
13426 [(set (match_operand:SF 0 "register_operand" "=x")
13427 (match_operator:SF 1 "sse_comparison_operator"
13428 [(match_operand:SF 2 "register_operand" "0")
13429 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13431 "cmp%D1ss\t{%3, %0|%0, %3}"
13432 [(set_attr "type" "ssecmp")
13433 (set_attr "mode" "SF")])
13435 (define_insn "*sse_setccdf"
13436 [(set (match_operand:DF 0 "register_operand" "=Y")
13437 (match_operator:DF 1 "sse_comparison_operator"
13438 [(match_operand:DF 2 "register_operand" "0")
13439 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13441 "cmp%D1sd\t{%3, %0|%0, %3}"
13442 [(set_attr "type" "ssecmp")
13443 (set_attr "mode" "DF")])
13445 ;; Basic conditional jump instructions.
13446 ;; We ignore the overflow flag for signed branch instructions.
13448 ;; For all bCOND expanders, also expand the compare or test insn that
13449 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13451 (define_expand "beq"
13453 (if_then_else (match_dup 1)
13454 (label_ref (match_operand 0 "" ""))
13457 "ix86_expand_branch (EQ, operands[0]); DONE;")
13459 (define_expand "bne"
13461 (if_then_else (match_dup 1)
13462 (label_ref (match_operand 0 "" ""))
13465 "ix86_expand_branch (NE, operands[0]); DONE;")
13467 (define_expand "bgt"
13469 (if_then_else (match_dup 1)
13470 (label_ref (match_operand 0 "" ""))
13473 "ix86_expand_branch (GT, operands[0]); DONE;")
13475 (define_expand "bgtu"
13477 (if_then_else (match_dup 1)
13478 (label_ref (match_operand 0 "" ""))
13481 "ix86_expand_branch (GTU, operands[0]); DONE;")
13483 (define_expand "blt"
13485 (if_then_else (match_dup 1)
13486 (label_ref (match_operand 0 "" ""))
13489 "ix86_expand_branch (LT, operands[0]); DONE;")
13491 (define_expand "bltu"
13493 (if_then_else (match_dup 1)
13494 (label_ref (match_operand 0 "" ""))
13497 "ix86_expand_branch (LTU, operands[0]); DONE;")
13499 (define_expand "bge"
13501 (if_then_else (match_dup 1)
13502 (label_ref (match_operand 0 "" ""))
13505 "ix86_expand_branch (GE, operands[0]); DONE;")
13507 (define_expand "bgeu"
13509 (if_then_else (match_dup 1)
13510 (label_ref (match_operand 0 "" ""))
13513 "ix86_expand_branch (GEU, operands[0]); DONE;")
13515 (define_expand "ble"
13517 (if_then_else (match_dup 1)
13518 (label_ref (match_operand 0 "" ""))
13521 "ix86_expand_branch (LE, operands[0]); DONE;")
13523 (define_expand "bleu"
13525 (if_then_else (match_dup 1)
13526 (label_ref (match_operand 0 "" ""))
13529 "ix86_expand_branch (LEU, operands[0]); DONE;")
13531 (define_expand "bunordered"
13533 (if_then_else (match_dup 1)
13534 (label_ref (match_operand 0 "" ""))
13536 "TARGET_80387 || TARGET_SSE_MATH"
13537 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13539 (define_expand "bordered"
13541 (if_then_else (match_dup 1)
13542 (label_ref (match_operand 0 "" ""))
13544 "TARGET_80387 || TARGET_SSE_MATH"
13545 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13547 (define_expand "buneq"
13549 (if_then_else (match_dup 1)
13550 (label_ref (match_operand 0 "" ""))
13552 "TARGET_80387 || TARGET_SSE_MATH"
13553 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13555 (define_expand "bunge"
13557 (if_then_else (match_dup 1)
13558 (label_ref (match_operand 0 "" ""))
13560 "TARGET_80387 || TARGET_SSE_MATH"
13561 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13563 (define_expand "bungt"
13565 (if_then_else (match_dup 1)
13566 (label_ref (match_operand 0 "" ""))
13568 "TARGET_80387 || TARGET_SSE_MATH"
13569 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13571 (define_expand "bunle"
13573 (if_then_else (match_dup 1)
13574 (label_ref (match_operand 0 "" ""))
13576 "TARGET_80387 || TARGET_SSE_MATH"
13577 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13579 (define_expand "bunlt"
13581 (if_then_else (match_dup 1)
13582 (label_ref (match_operand 0 "" ""))
13584 "TARGET_80387 || TARGET_SSE_MATH"
13585 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13587 (define_expand "bltgt"
13589 (if_then_else (match_dup 1)
13590 (label_ref (match_operand 0 "" ""))
13592 "TARGET_80387 || TARGET_SSE_MATH"
13593 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13595 (define_insn "*jcc_1"
13597 (if_then_else (match_operator 1 "ix86_comparison_operator"
13598 [(reg FLAGS_REG) (const_int 0)])
13599 (label_ref (match_operand 0 "" ""))
13603 [(set_attr "type" "ibr")
13604 (set_attr "modrm" "0")
13605 (set (attr "length")
13606 (if_then_else (and (ge (minus (match_dup 0) (pc))
13608 (lt (minus (match_dup 0) (pc))
13613 (define_insn "*jcc_2"
13615 (if_then_else (match_operator 1 "ix86_comparison_operator"
13616 [(reg FLAGS_REG) (const_int 0)])
13618 (label_ref (match_operand 0 "" ""))))]
13621 [(set_attr "type" "ibr")
13622 (set_attr "modrm" "0")
13623 (set (attr "length")
13624 (if_then_else (and (ge (minus (match_dup 0) (pc))
13626 (lt (minus (match_dup 0) (pc))
13631 ;; In general it is not safe to assume too much about CCmode registers,
13632 ;; so simplify-rtx stops when it sees a second one. Under certain
13633 ;; conditions this is safe on x86, so help combine not create
13641 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13642 [(reg FLAGS_REG) (const_int 0)])
13644 (label_ref (match_operand 1 "" ""))
13648 (if_then_else (match_dup 0)
13649 (label_ref (match_dup 1))
13652 PUT_MODE (operands[0], VOIDmode);
13657 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13658 [(reg FLAGS_REG) (const_int 0)])
13660 (label_ref (match_operand 1 "" ""))
13664 (if_then_else (match_dup 0)
13665 (label_ref (match_dup 1))
13668 rtx new_op0 = copy_rtx (operands[0]);
13669 operands[0] = new_op0;
13670 PUT_MODE (new_op0, VOIDmode);
13671 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13672 GET_MODE (XEXP (new_op0, 0))));
13674 /* Make sure that (a) the CCmode we have for the flags is strong
13675 enough for the reversed compare or (b) we have a valid FP compare. */
13676 if (! ix86_comparison_operator (new_op0, VOIDmode))
13680 ;; Define combination compare-and-branch fp compare instructions to use
13681 ;; during early optimization. Splitting the operation apart early makes
13682 ;; for bad code when we want to reverse the operation.
13684 (define_insn "*fp_jcc_1_mixed"
13686 (if_then_else (match_operator 0 "comparison_operator"
13687 [(match_operand 1 "register_operand" "f,x")
13688 (match_operand 2 "nonimmediate_operand" "f,xm")])
13689 (label_ref (match_operand 3 "" ""))
13691 (clobber (reg:CCFP FPSR_REG))
13692 (clobber (reg:CCFP FLAGS_REG))]
13693 "TARGET_MIX_SSE_I387
13694 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13695 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13696 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13699 (define_insn "*fp_jcc_1_sse"
13701 (if_then_else (match_operator 0 "comparison_operator"
13702 [(match_operand 1 "register_operand" "x")
13703 (match_operand 2 "nonimmediate_operand" "xm")])
13704 (label_ref (match_operand 3 "" ""))
13706 (clobber (reg:CCFP FPSR_REG))
13707 (clobber (reg:CCFP FLAGS_REG))]
13709 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13710 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13711 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13714 (define_insn "*fp_jcc_1_387"
13716 (if_then_else (match_operator 0 "comparison_operator"
13717 [(match_operand 1 "register_operand" "f")
13718 (match_operand 2 "register_operand" "f")])
13719 (label_ref (match_operand 3 "" ""))
13721 (clobber (reg:CCFP FPSR_REG))
13722 (clobber (reg:CCFP FLAGS_REG))]
13723 "TARGET_CMOVE && TARGET_80387
13724 && FLOAT_MODE_P (GET_MODE (operands[1]))
13725 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13726 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13729 (define_insn "*fp_jcc_2_mixed"
13731 (if_then_else (match_operator 0 "comparison_operator"
13732 [(match_operand 1 "register_operand" "f,x")
13733 (match_operand 2 "nonimmediate_operand" "f,xm")])
13735 (label_ref (match_operand 3 "" ""))))
13736 (clobber (reg:CCFP FPSR_REG))
13737 (clobber (reg:CCFP FLAGS_REG))]
13738 "TARGET_MIX_SSE_I387
13739 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13740 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13741 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13744 (define_insn "*fp_jcc_2_sse"
13746 (if_then_else (match_operator 0 "comparison_operator"
13747 [(match_operand 1 "register_operand" "x")
13748 (match_operand 2 "nonimmediate_operand" "xm")])
13750 (label_ref (match_operand 3 "" ""))))
13751 (clobber (reg:CCFP FPSR_REG))
13752 (clobber (reg:CCFP FLAGS_REG))]
13754 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13755 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13756 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13759 (define_insn "*fp_jcc_2_387"
13761 (if_then_else (match_operator 0 "comparison_operator"
13762 [(match_operand 1 "register_operand" "f")
13763 (match_operand 2 "register_operand" "f")])
13765 (label_ref (match_operand 3 "" ""))))
13766 (clobber (reg:CCFP FPSR_REG))
13767 (clobber (reg:CCFP FLAGS_REG))]
13768 "TARGET_CMOVE && TARGET_80387
13769 && FLOAT_MODE_P (GET_MODE (operands[1]))
13770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13774 (define_insn "*fp_jcc_3_387"
13776 (if_then_else (match_operator 0 "comparison_operator"
13777 [(match_operand 1 "register_operand" "f")
13778 (match_operand 2 "nonimmediate_operand" "fm")])
13779 (label_ref (match_operand 3 "" ""))
13781 (clobber (reg:CCFP FPSR_REG))
13782 (clobber (reg:CCFP FLAGS_REG))
13783 (clobber (match_scratch:HI 4 "=a"))]
13785 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13786 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13787 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13788 && SELECT_CC_MODE (GET_CODE (operands[0]),
13789 operands[1], operands[2]) == CCFPmode
13790 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13793 (define_insn "*fp_jcc_4_387"
13795 (if_then_else (match_operator 0 "comparison_operator"
13796 [(match_operand 1 "register_operand" "f")
13797 (match_operand 2 "nonimmediate_operand" "fm")])
13799 (label_ref (match_operand 3 "" ""))))
13800 (clobber (reg:CCFP FPSR_REG))
13801 (clobber (reg:CCFP FLAGS_REG))
13802 (clobber (match_scratch:HI 4 "=a"))]
13804 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13805 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13806 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13807 && SELECT_CC_MODE (GET_CODE (operands[0]),
13808 operands[1], operands[2]) == CCFPmode
13809 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13812 (define_insn "*fp_jcc_5_387"
13814 (if_then_else (match_operator 0 "comparison_operator"
13815 [(match_operand 1 "register_operand" "f")
13816 (match_operand 2 "register_operand" "f")])
13817 (label_ref (match_operand 3 "" ""))
13819 (clobber (reg:CCFP FPSR_REG))
13820 (clobber (reg:CCFP FLAGS_REG))
13821 (clobber (match_scratch:HI 4 "=a"))]
13823 && FLOAT_MODE_P (GET_MODE (operands[1]))
13824 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13825 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13828 (define_insn "*fp_jcc_6_387"
13830 (if_then_else (match_operator 0 "comparison_operator"
13831 [(match_operand 1 "register_operand" "f")
13832 (match_operand 2 "register_operand" "f")])
13834 (label_ref (match_operand 3 "" ""))))
13835 (clobber (reg:CCFP FPSR_REG))
13836 (clobber (reg:CCFP FLAGS_REG))
13837 (clobber (match_scratch:HI 4 "=a"))]
13839 && FLOAT_MODE_P (GET_MODE (operands[1]))
13840 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13841 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13844 (define_insn "*fp_jcc_7_387"
13846 (if_then_else (match_operator 0 "comparison_operator"
13847 [(match_operand 1 "register_operand" "f")
13848 (match_operand 2 "const0_operand" "X")])
13849 (label_ref (match_operand 3 "" ""))
13851 (clobber (reg:CCFP FPSR_REG))
13852 (clobber (reg:CCFP FLAGS_REG))
13853 (clobber (match_scratch:HI 4 "=a"))]
13855 && FLOAT_MODE_P (GET_MODE (operands[1]))
13856 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13857 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13858 && SELECT_CC_MODE (GET_CODE (operands[0]),
13859 operands[1], operands[2]) == CCFPmode
13860 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13863 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13864 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13865 ;; with a precedence over other operators and is always put in the first
13866 ;; place. Swap condition and operands to match ficom instruction.
13868 (define_insn "*fp_jcc_8<mode>_387"
13870 (if_then_else (match_operator 0 "comparison_operator"
13871 [(match_operator 1 "float_operator"
13872 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13873 (match_operand 3 "register_operand" "f,f")])
13874 (label_ref (match_operand 4 "" ""))
13876 (clobber (reg:CCFP FPSR_REG))
13877 (clobber (reg:CCFP FLAGS_REG))
13878 (clobber (match_scratch:HI 5 "=a,a"))]
13879 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13880 && FLOAT_MODE_P (GET_MODE (operands[3]))
13881 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13882 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13883 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13884 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13889 (if_then_else (match_operator 0 "comparison_operator"
13890 [(match_operand 1 "register_operand" "")
13891 (match_operand 2 "nonimmediate_operand" "")])
13892 (match_operand 3 "" "")
13893 (match_operand 4 "" "")))
13894 (clobber (reg:CCFP FPSR_REG))
13895 (clobber (reg:CCFP FLAGS_REG))]
13899 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13900 operands[3], operands[4], NULL_RTX, NULL_RTX);
13906 (if_then_else (match_operator 0 "comparison_operator"
13907 [(match_operand 1 "register_operand" "")
13908 (match_operand 2 "general_operand" "")])
13909 (match_operand 3 "" "")
13910 (match_operand 4 "" "")))
13911 (clobber (reg:CCFP FPSR_REG))
13912 (clobber (reg:CCFP FLAGS_REG))
13913 (clobber (match_scratch:HI 5 "=a"))]
13917 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13918 operands[3], operands[4], operands[5], NULL_RTX);
13924 (if_then_else (match_operator 0 "comparison_operator"
13925 [(match_operator 1 "float_operator"
13926 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13927 (match_operand 3 "register_operand" "")])
13928 (match_operand 4 "" "")
13929 (match_operand 5 "" "")))
13930 (clobber (reg:CCFP FPSR_REG))
13931 (clobber (reg:CCFP FLAGS_REG))
13932 (clobber (match_scratch:HI 6 "=a"))]
13936 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13937 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13938 operands[3], operands[7],
13939 operands[4], operands[5], operands[6], NULL_RTX);
13943 ;; %%% Kill this when reload knows how to do it.
13946 (if_then_else (match_operator 0 "comparison_operator"
13947 [(match_operator 1 "float_operator"
13948 [(match_operand:X87MODEI12 2 "register_operand" "")])
13949 (match_operand 3 "register_operand" "")])
13950 (match_operand 4 "" "")
13951 (match_operand 5 "" "")))
13952 (clobber (reg:CCFP FPSR_REG))
13953 (clobber (reg:CCFP FLAGS_REG))
13954 (clobber (match_scratch:HI 6 "=a"))]
13958 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13959 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13960 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13961 operands[3], operands[7],
13962 operands[4], operands[5], operands[6], operands[2]);
13966 ;; Unconditional and other jump instructions
13968 (define_insn "jump"
13970 (label_ref (match_operand 0 "" "")))]
13973 [(set_attr "type" "ibr")
13974 (set (attr "length")
13975 (if_then_else (and (ge (minus (match_dup 0) (pc))
13977 (lt (minus (match_dup 0) (pc))
13981 (set_attr "modrm" "0")])
13983 (define_expand "indirect_jump"
13984 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13988 (define_insn "*indirect_jump"
13989 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13992 [(set_attr "type" "ibr")
13993 (set_attr "length_immediate" "0")])
13995 (define_insn "*indirect_jump_rtx64"
13996 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13999 [(set_attr "type" "ibr")
14000 (set_attr "length_immediate" "0")])
14002 (define_expand "tablejump"
14003 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14004 (use (label_ref (match_operand 1 "" "")))])]
14007 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14008 relative. Convert the relative address to an absolute address. */
14012 enum rtx_code code;
14018 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14020 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14024 op1 = pic_offset_table_rtx;
14029 op0 = pic_offset_table_rtx;
14033 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14038 (define_insn "*tablejump_1"
14039 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14040 (use (label_ref (match_operand 1 "" "")))]
14043 [(set_attr "type" "ibr")
14044 (set_attr "length_immediate" "0")])
14046 (define_insn "*tablejump_1_rtx64"
14047 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14048 (use (label_ref (match_operand 1 "" "")))]
14051 [(set_attr "type" "ibr")
14052 (set_attr "length_immediate" "0")])
14054 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14057 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14058 (set (match_operand:QI 1 "register_operand" "")
14059 (match_operator:QI 2 "ix86_comparison_operator"
14060 [(reg FLAGS_REG) (const_int 0)]))
14061 (set (match_operand 3 "q_regs_operand" "")
14062 (zero_extend (match_dup 1)))]
14063 "(peep2_reg_dead_p (3, operands[1])
14064 || operands_match_p (operands[1], operands[3]))
14065 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14066 [(set (match_dup 4) (match_dup 0))
14067 (set (strict_low_part (match_dup 5))
14070 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14071 operands[5] = gen_lowpart (QImode, operands[3]);
14072 ix86_expand_clear (operands[3]);
14075 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14078 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14079 (set (match_operand:QI 1 "register_operand" "")
14080 (match_operator:QI 2 "ix86_comparison_operator"
14081 [(reg FLAGS_REG) (const_int 0)]))
14082 (parallel [(set (match_operand 3 "q_regs_operand" "")
14083 (zero_extend (match_dup 1)))
14084 (clobber (reg:CC FLAGS_REG))])]
14085 "(peep2_reg_dead_p (3, operands[1])
14086 || operands_match_p (operands[1], operands[3]))
14087 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14088 [(set (match_dup 4) (match_dup 0))
14089 (set (strict_low_part (match_dup 5))
14092 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14093 operands[5] = gen_lowpart (QImode, operands[3]);
14094 ix86_expand_clear (operands[3]);
14097 ;; Call instructions.
14099 ;; The predicates normally associated with named expanders are not properly
14100 ;; checked for calls. This is a bug in the generic code, but it isn't that
14101 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14103 ;; Call subroutine returning no value.
14105 (define_expand "call_pop"
14106 [(parallel [(call (match_operand:QI 0 "" "")
14107 (match_operand:SI 1 "" ""))
14108 (set (reg:SI SP_REG)
14109 (plus:SI (reg:SI SP_REG)
14110 (match_operand:SI 3 "" "")))])]
14113 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14117 (define_insn "*call_pop_0"
14118 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14119 (match_operand:SI 1 "" ""))
14120 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14121 (match_operand:SI 2 "immediate_operand" "")))]
14124 if (SIBLING_CALL_P (insn))
14127 return "call\t%P0";
14129 [(set_attr "type" "call")])
14131 (define_insn "*call_pop_1"
14132 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14133 (match_operand:SI 1 "" ""))
14134 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14135 (match_operand:SI 2 "immediate_operand" "i")))]
14138 if (constant_call_address_operand (operands[0], Pmode))
14140 if (SIBLING_CALL_P (insn))
14143 return "call\t%P0";
14145 if (SIBLING_CALL_P (insn))
14148 return "call\t%A0";
14150 [(set_attr "type" "call")])
14152 (define_expand "call"
14153 [(call (match_operand:QI 0 "" "")
14154 (match_operand 1 "" ""))
14155 (use (match_operand 2 "" ""))]
14158 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14162 (define_expand "sibcall"
14163 [(call (match_operand:QI 0 "" "")
14164 (match_operand 1 "" ""))
14165 (use (match_operand 2 "" ""))]
14168 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14172 (define_insn "*call_0"
14173 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14174 (match_operand 1 "" ""))]
14177 if (SIBLING_CALL_P (insn))
14180 return "call\t%P0";
14182 [(set_attr "type" "call")])
14184 (define_insn "*call_1"
14185 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14186 (match_operand 1 "" ""))]
14187 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14189 if (constant_call_address_operand (operands[0], Pmode))
14190 return "call\t%P0";
14191 return "call\t%A0";
14193 [(set_attr "type" "call")])
14195 (define_insn "*sibcall_1"
14196 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14197 (match_operand 1 "" ""))]
14198 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14200 if (constant_call_address_operand (operands[0], Pmode))
14204 [(set_attr "type" "call")])
14206 (define_insn "*call_1_rex64"
14207 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14208 (match_operand 1 "" ""))]
14209 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14211 if (constant_call_address_operand (operands[0], Pmode))
14212 return "call\t%P0";
14213 return "call\t%A0";
14215 [(set_attr "type" "call")])
14217 (define_insn "*sibcall_1_rex64"
14218 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14219 (match_operand 1 "" ""))]
14220 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14222 [(set_attr "type" "call")])
14224 (define_insn "*sibcall_1_rex64_v"
14225 [(call (mem:QI (reg:DI R11_REG))
14226 (match_operand 0 "" ""))]
14227 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14229 [(set_attr "type" "call")])
14232 ;; Call subroutine, returning value in operand 0
14234 (define_expand "call_value_pop"
14235 [(parallel [(set (match_operand 0 "" "")
14236 (call (match_operand:QI 1 "" "")
14237 (match_operand:SI 2 "" "")))
14238 (set (reg:SI SP_REG)
14239 (plus:SI (reg:SI SP_REG)
14240 (match_operand:SI 4 "" "")))])]
14243 ix86_expand_call (operands[0], operands[1], operands[2],
14244 operands[3], operands[4], 0);
14248 (define_expand "call_value"
14249 [(set (match_operand 0 "" "")
14250 (call (match_operand:QI 1 "" "")
14251 (match_operand:SI 2 "" "")))
14252 (use (match_operand:SI 3 "" ""))]
14253 ;; Operand 2 not used on the i386.
14256 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14260 (define_expand "sibcall_value"
14261 [(set (match_operand 0 "" "")
14262 (call (match_operand:QI 1 "" "")
14263 (match_operand:SI 2 "" "")))
14264 (use (match_operand:SI 3 "" ""))]
14265 ;; Operand 2 not used on the i386.
14268 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14272 ;; Call subroutine returning any type.
14274 (define_expand "untyped_call"
14275 [(parallel [(call (match_operand 0 "" "")
14277 (match_operand 1 "" "")
14278 (match_operand 2 "" "")])]
14283 /* In order to give reg-stack an easier job in validating two
14284 coprocessor registers as containing a possible return value,
14285 simply pretend the untyped call returns a complex long double
14288 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14289 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14290 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14293 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14295 rtx set = XVECEXP (operands[2], 0, i);
14296 emit_move_insn (SET_DEST (set), SET_SRC (set));
14299 /* The optimizer does not know that the call sets the function value
14300 registers we stored in the result block. We avoid problems by
14301 claiming that all hard registers are used and clobbered at this
14303 emit_insn (gen_blockage (const0_rtx));
14308 ;; Prologue and epilogue instructions
14310 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14311 ;; all of memory. This blocks insns from being moved across this point.
14313 (define_insn "blockage"
14314 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14317 [(set_attr "length" "0")])
14319 ;; Insn emitted into the body of a function to return from a function.
14320 ;; This is only done if the function's epilogue is known to be simple.
14321 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14323 (define_expand "return"
14325 "ix86_can_use_return_insn_p ()"
14327 if (current_function_pops_args)
14329 rtx popc = GEN_INT (current_function_pops_args);
14330 emit_jump_insn (gen_return_pop_internal (popc));
14335 (define_insn "return_internal"
14339 [(set_attr "length" "1")
14340 (set_attr "length_immediate" "0")
14341 (set_attr "modrm" "0")])
14343 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14344 ;; instruction Athlon and K8 have.
14346 (define_insn "return_internal_long"
14348 (unspec [(const_int 0)] UNSPEC_REP)]
14351 [(set_attr "length" "1")
14352 (set_attr "length_immediate" "0")
14353 (set_attr "prefix_rep" "1")
14354 (set_attr "modrm" "0")])
14356 (define_insn "return_pop_internal"
14358 (use (match_operand:SI 0 "const_int_operand" ""))]
14361 [(set_attr "length" "3")
14362 (set_attr "length_immediate" "2")
14363 (set_attr "modrm" "0")])
14365 (define_insn "return_indirect_internal"
14367 (use (match_operand:SI 0 "register_operand" "r"))]
14370 [(set_attr "type" "ibr")
14371 (set_attr "length_immediate" "0")])
14377 [(set_attr "length" "1")
14378 (set_attr "length_immediate" "0")
14379 (set_attr "modrm" "0")])
14381 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14382 ;; branch prediction penalty for the third jump in a 16-byte
14385 (define_insn "align"
14386 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14389 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14390 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14392 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14393 The align insn is used to avoid 3 jump instructions in the row to improve
14394 branch prediction and the benefits hardly outweigh the cost of extra 8
14395 nops on the average inserted by full alignment pseudo operation. */
14399 [(set_attr "length" "16")])
14401 (define_expand "prologue"
14404 "ix86_expand_prologue (); DONE;")
14406 (define_insn "set_got"
14407 [(set (match_operand:SI 0 "register_operand" "=r")
14408 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14409 (clobber (reg:CC FLAGS_REG))]
14411 { return output_set_got (operands[0], NULL_RTX); }
14412 [(set_attr "type" "multi")
14413 (set_attr "length" "12")])
14415 (define_insn "set_got_labelled"
14416 [(set (match_operand:SI 0 "register_operand" "=r")
14417 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14419 (clobber (reg:CC FLAGS_REG))]
14421 { return output_set_got (operands[0], operands[1]); }
14422 [(set_attr "type" "multi")
14423 (set_attr "length" "12")])
14425 (define_insn "set_got_rex64"
14426 [(set (match_operand:DI 0 "register_operand" "=r")
14427 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14429 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14430 [(set_attr "type" "lea")
14431 (set_attr "length" "6")])
14433 (define_expand "epilogue"
14436 "ix86_expand_epilogue (1); DONE;")
14438 (define_expand "sibcall_epilogue"
14441 "ix86_expand_epilogue (0); DONE;")
14443 (define_expand "eh_return"
14444 [(use (match_operand 0 "register_operand" ""))]
14447 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14449 /* Tricky bit: we write the address of the handler to which we will
14450 be returning into someone else's stack frame, one word below the
14451 stack address we wish to restore. */
14452 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14453 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14454 tmp = gen_rtx_MEM (Pmode, tmp);
14455 emit_move_insn (tmp, ra);
14457 if (Pmode == SImode)
14458 emit_jump_insn (gen_eh_return_si (sa));
14460 emit_jump_insn (gen_eh_return_di (sa));
14465 (define_insn_and_split "eh_return_si"
14467 (unspec [(match_operand:SI 0 "register_operand" "c")]
14468 UNSPEC_EH_RETURN))]
14473 "ix86_expand_epilogue (2); DONE;")
14475 (define_insn_and_split "eh_return_di"
14477 (unspec [(match_operand:DI 0 "register_operand" "c")]
14478 UNSPEC_EH_RETURN))]
14483 "ix86_expand_epilogue (2); DONE;")
14485 (define_insn "leave"
14486 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14487 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14488 (clobber (mem:BLK (scratch)))]
14491 [(set_attr "type" "leave")])
14493 (define_insn "leave_rex64"
14494 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14495 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14496 (clobber (mem:BLK (scratch)))]
14499 [(set_attr "type" "leave")])
14501 (define_expand "ffssi2"
14503 [(set (match_operand:SI 0 "register_operand" "")
14504 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14505 (clobber (match_scratch:SI 2 ""))
14506 (clobber (reg:CC FLAGS_REG))])]
14510 (define_insn_and_split "*ffs_cmove"
14511 [(set (match_operand:SI 0 "register_operand" "=r")
14512 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14513 (clobber (match_scratch:SI 2 "=&r"))
14514 (clobber (reg:CC FLAGS_REG))]
14517 "&& reload_completed"
14518 [(set (match_dup 2) (const_int -1))
14519 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14520 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14521 (set (match_dup 0) (if_then_else:SI
14522 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14525 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14526 (clobber (reg:CC FLAGS_REG))])]
14529 (define_insn_and_split "*ffs_no_cmove"
14530 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14531 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14532 (clobber (match_scratch:SI 2 "=&q"))
14533 (clobber (reg:CC FLAGS_REG))]
14537 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14538 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14539 (set (strict_low_part (match_dup 3))
14540 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14541 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14542 (clobber (reg:CC FLAGS_REG))])
14543 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14544 (clobber (reg:CC FLAGS_REG))])
14545 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14546 (clobber (reg:CC FLAGS_REG))])]
14548 operands[3] = gen_lowpart (QImode, operands[2]);
14549 ix86_expand_clear (operands[2]);
14552 (define_insn "*ffssi_1"
14553 [(set (reg:CCZ FLAGS_REG)
14554 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14556 (set (match_operand:SI 0 "register_operand" "=r")
14557 (ctz:SI (match_dup 1)))]
14559 "bsf{l}\t{%1, %0|%0, %1}"
14560 [(set_attr "prefix_0f" "1")])
14562 (define_expand "ffsdi2"
14564 [(set (match_operand:DI 0 "register_operand" "")
14565 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14566 (clobber (match_scratch:DI 2 ""))
14567 (clobber (reg:CC FLAGS_REG))])]
14568 "TARGET_64BIT && TARGET_CMOVE"
14571 (define_insn_and_split "*ffs_rex64"
14572 [(set (match_operand:DI 0 "register_operand" "=r")
14573 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14574 (clobber (match_scratch:DI 2 "=&r"))
14575 (clobber (reg:CC FLAGS_REG))]
14576 "TARGET_64BIT && TARGET_CMOVE"
14578 "&& reload_completed"
14579 [(set (match_dup 2) (const_int -1))
14580 (parallel [(set (reg:CCZ FLAGS_REG)
14581 (compare:CCZ (match_dup 1) (const_int 0)))
14582 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14583 (set (match_dup 0) (if_then_else:DI
14584 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14587 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14588 (clobber (reg:CC FLAGS_REG))])]
14591 (define_insn "*ffsdi_1"
14592 [(set (reg:CCZ FLAGS_REG)
14593 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14595 (set (match_operand:DI 0 "register_operand" "=r")
14596 (ctz:DI (match_dup 1)))]
14598 "bsf{q}\t{%1, %0|%0, %1}"
14599 [(set_attr "prefix_0f" "1")])
14601 (define_insn "ctzsi2"
14602 [(set (match_operand:SI 0 "register_operand" "=r")
14603 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14604 (clobber (reg:CC FLAGS_REG))]
14606 "bsf{l}\t{%1, %0|%0, %1}"
14607 [(set_attr "prefix_0f" "1")])
14609 (define_insn "ctzdi2"
14610 [(set (match_operand:DI 0 "register_operand" "=r")
14611 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14612 (clobber (reg:CC FLAGS_REG))]
14614 "bsf{q}\t{%1, %0|%0, %1}"
14615 [(set_attr "prefix_0f" "1")])
14617 (define_expand "clzsi2"
14619 [(set (match_operand:SI 0 "register_operand" "")
14620 (minus:SI (const_int 31)
14621 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14622 (clobber (reg:CC FLAGS_REG))])
14624 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14625 (clobber (reg:CC FLAGS_REG))])]
14629 (define_insn "*bsr"
14630 [(set (match_operand:SI 0 "register_operand" "=r")
14631 (minus:SI (const_int 31)
14632 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14633 (clobber (reg:CC FLAGS_REG))]
14635 "bsr{l}\t{%1, %0|%0, %1}"
14636 [(set_attr "prefix_0f" "1")])
14638 (define_insn "bswapsi2"
14639 [(set (match_operand:SI 0 "register_operand" "=r")
14640 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14641 (clobber (reg:CC FLAGS_REG))]
14644 [(set_attr "prefix_0f" "1")
14645 (set_attr "length" "2")])
14647 (define_insn "bswapdi2"
14648 [(set (match_operand:DI 0 "register_operand" "=r")
14649 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14650 (clobber (reg:CC FLAGS_REG))]
14651 "TARGET_64BIT && TARGET_BSWAP"
14653 [(set_attr "prefix_0f" "1")
14654 (set_attr "length" "3")])
14656 (define_expand "clzdi2"
14658 [(set (match_operand:DI 0 "register_operand" "")
14659 (minus:DI (const_int 63)
14660 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14661 (clobber (reg:CC FLAGS_REG))])
14663 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14664 (clobber (reg:CC FLAGS_REG))])]
14668 (define_insn "*bsr_rex64"
14669 [(set (match_operand:DI 0 "register_operand" "=r")
14670 (minus:DI (const_int 63)
14671 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14672 (clobber (reg:CC FLAGS_REG))]
14674 "bsr{q}\t{%1, %0|%0, %1}"
14675 [(set_attr "prefix_0f" "1")])
14677 ;; Thread-local storage patterns for ELF.
14679 ;; Note that these code sequences must appear exactly as shown
14680 ;; in order to allow linker relaxation.
14682 (define_insn "*tls_global_dynamic_32_gnu"
14683 [(set (match_operand:SI 0 "register_operand" "=a")
14684 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14685 (match_operand:SI 2 "tls_symbolic_operand" "")
14686 (match_operand:SI 3 "call_insn_operand" "")]
14688 (clobber (match_scratch:SI 4 "=d"))
14689 (clobber (match_scratch:SI 5 "=c"))
14690 (clobber (reg:CC FLAGS_REG))]
14691 "!TARGET_64BIT && TARGET_GNU_TLS"
14692 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14693 [(set_attr "type" "multi")
14694 (set_attr "length" "12")])
14696 (define_insn "*tls_global_dynamic_32_sun"
14697 [(set (match_operand:SI 0 "register_operand" "=a")
14698 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14699 (match_operand:SI 2 "tls_symbolic_operand" "")
14700 (match_operand:SI 3 "call_insn_operand" "")]
14702 (clobber (match_scratch:SI 4 "=d"))
14703 (clobber (match_scratch:SI 5 "=c"))
14704 (clobber (reg:CC FLAGS_REG))]
14705 "!TARGET_64BIT && TARGET_SUN_TLS"
14706 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14707 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14708 [(set_attr "type" "multi")
14709 (set_attr "length" "14")])
14711 (define_expand "tls_global_dynamic_32"
14712 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14715 (match_operand:SI 1 "tls_symbolic_operand" "")
14718 (clobber (match_scratch:SI 4 ""))
14719 (clobber (match_scratch:SI 5 ""))
14720 (clobber (reg:CC FLAGS_REG))])]
14724 operands[2] = pic_offset_table_rtx;
14727 operands[2] = gen_reg_rtx (Pmode);
14728 emit_insn (gen_set_got (operands[2]));
14730 if (TARGET_GNU2_TLS)
14732 emit_insn (gen_tls_dynamic_gnu2_32
14733 (operands[0], operands[1], operands[2]));
14736 operands[3] = ix86_tls_get_addr ();
14739 (define_insn "*tls_global_dynamic_64"
14740 [(set (match_operand:DI 0 "register_operand" "=a")
14741 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14742 (match_operand:DI 3 "" "")))
14743 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14746 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14747 [(set_attr "type" "multi")
14748 (set_attr "length" "16")])
14750 (define_expand "tls_global_dynamic_64"
14751 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14752 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14753 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14757 if (TARGET_GNU2_TLS)
14759 emit_insn (gen_tls_dynamic_gnu2_64
14760 (operands[0], operands[1]));
14763 operands[2] = ix86_tls_get_addr ();
14766 (define_insn "*tls_local_dynamic_base_32_gnu"
14767 [(set (match_operand:SI 0 "register_operand" "=a")
14768 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14769 (match_operand:SI 2 "call_insn_operand" "")]
14770 UNSPEC_TLS_LD_BASE))
14771 (clobber (match_scratch:SI 3 "=d"))
14772 (clobber (match_scratch:SI 4 "=c"))
14773 (clobber (reg:CC FLAGS_REG))]
14774 "!TARGET_64BIT && TARGET_GNU_TLS"
14775 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14776 [(set_attr "type" "multi")
14777 (set_attr "length" "11")])
14779 (define_insn "*tls_local_dynamic_base_32_sun"
14780 [(set (match_operand:SI 0 "register_operand" "=a")
14781 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14782 (match_operand:SI 2 "call_insn_operand" "")]
14783 UNSPEC_TLS_LD_BASE))
14784 (clobber (match_scratch:SI 3 "=d"))
14785 (clobber (match_scratch:SI 4 "=c"))
14786 (clobber (reg:CC FLAGS_REG))]
14787 "!TARGET_64BIT && TARGET_SUN_TLS"
14788 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14789 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14790 [(set_attr "type" "multi")
14791 (set_attr "length" "13")])
14793 (define_expand "tls_local_dynamic_base_32"
14794 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14795 (unspec:SI [(match_dup 1) (match_dup 2)]
14796 UNSPEC_TLS_LD_BASE))
14797 (clobber (match_scratch:SI 3 ""))
14798 (clobber (match_scratch:SI 4 ""))
14799 (clobber (reg:CC FLAGS_REG))])]
14803 operands[1] = pic_offset_table_rtx;
14806 operands[1] = gen_reg_rtx (Pmode);
14807 emit_insn (gen_set_got (operands[1]));
14809 if (TARGET_GNU2_TLS)
14811 emit_insn (gen_tls_dynamic_gnu2_32
14812 (operands[0], ix86_tls_module_base (), operands[1]));
14815 operands[2] = ix86_tls_get_addr ();
14818 (define_insn "*tls_local_dynamic_base_64"
14819 [(set (match_operand:DI 0 "register_operand" "=a")
14820 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14821 (match_operand:DI 2 "" "")))
14822 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14824 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14825 [(set_attr "type" "multi")
14826 (set_attr "length" "12")])
14828 (define_expand "tls_local_dynamic_base_64"
14829 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14830 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14831 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14834 if (TARGET_GNU2_TLS)
14836 emit_insn (gen_tls_dynamic_gnu2_64
14837 (operands[0], ix86_tls_module_base ()));
14840 operands[1] = ix86_tls_get_addr ();
14843 ;; Local dynamic of a single variable is a lose. Show combine how
14844 ;; to convert that back to global dynamic.
14846 (define_insn_and_split "*tls_local_dynamic_32_once"
14847 [(set (match_operand:SI 0 "register_operand" "=a")
14848 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14849 (match_operand:SI 2 "call_insn_operand" "")]
14850 UNSPEC_TLS_LD_BASE)
14851 (const:SI (unspec:SI
14852 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14854 (clobber (match_scratch:SI 4 "=d"))
14855 (clobber (match_scratch:SI 5 "=c"))
14856 (clobber (reg:CC FLAGS_REG))]
14860 [(parallel [(set (match_dup 0)
14861 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14863 (clobber (match_dup 4))
14864 (clobber (match_dup 5))
14865 (clobber (reg:CC FLAGS_REG))])]
14868 ;; Load and add the thread base pointer from %gs:0.
14870 (define_insn "*load_tp_si"
14871 [(set (match_operand:SI 0 "register_operand" "=r")
14872 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14874 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14875 [(set_attr "type" "imov")
14876 (set_attr "modrm" "0")
14877 (set_attr "length" "7")
14878 (set_attr "memory" "load")
14879 (set_attr "imm_disp" "false")])
14881 (define_insn "*add_tp_si"
14882 [(set (match_operand:SI 0 "register_operand" "=r")
14883 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14884 (match_operand:SI 1 "register_operand" "0")))
14885 (clobber (reg:CC FLAGS_REG))]
14887 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14888 [(set_attr "type" "alu")
14889 (set_attr "modrm" "0")
14890 (set_attr "length" "7")
14891 (set_attr "memory" "load")
14892 (set_attr "imm_disp" "false")])
14894 (define_insn "*load_tp_di"
14895 [(set (match_operand:DI 0 "register_operand" "=r")
14896 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14898 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14899 [(set_attr "type" "imov")
14900 (set_attr "modrm" "0")
14901 (set_attr "length" "7")
14902 (set_attr "memory" "load")
14903 (set_attr "imm_disp" "false")])
14905 (define_insn "*add_tp_di"
14906 [(set (match_operand:DI 0 "register_operand" "=r")
14907 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14908 (match_operand:DI 1 "register_operand" "0")))
14909 (clobber (reg:CC FLAGS_REG))]
14911 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14912 [(set_attr "type" "alu")
14913 (set_attr "modrm" "0")
14914 (set_attr "length" "7")
14915 (set_attr "memory" "load")
14916 (set_attr "imm_disp" "false")])
14918 ;; GNU2 TLS patterns can be split.
14920 (define_expand "tls_dynamic_gnu2_32"
14921 [(set (match_dup 3)
14922 (plus:SI (match_operand:SI 2 "register_operand" "")
14924 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14927 [(set (match_operand:SI 0 "register_operand" "")
14928 (unspec:SI [(match_dup 1) (match_dup 3)
14929 (match_dup 2) (reg:SI SP_REG)]
14931 (clobber (reg:CC FLAGS_REG))])]
14932 "!TARGET_64BIT && TARGET_GNU2_TLS"
14934 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14935 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14938 (define_insn "*tls_dynamic_lea_32"
14939 [(set (match_operand:SI 0 "register_operand" "=r")
14940 (plus:SI (match_operand:SI 1 "register_operand" "b")
14942 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14943 UNSPEC_TLSDESC))))]
14944 "!TARGET_64BIT && TARGET_GNU2_TLS"
14945 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14946 [(set_attr "type" "lea")
14947 (set_attr "mode" "SI")
14948 (set_attr "length" "6")
14949 (set_attr "length_address" "4")])
14951 (define_insn "*tls_dynamic_call_32"
14952 [(set (match_operand:SI 0 "register_operand" "=a")
14953 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14954 (match_operand:SI 2 "register_operand" "0")
14955 ;; we have to make sure %ebx still points to the GOT
14956 (match_operand:SI 3 "register_operand" "b")
14959 (clobber (reg:CC FLAGS_REG))]
14960 "!TARGET_64BIT && TARGET_GNU2_TLS"
14961 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14962 [(set_attr "type" "call")
14963 (set_attr "length" "2")
14964 (set_attr "length_address" "0")])
14966 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14967 [(set (match_operand:SI 0 "register_operand" "=&a")
14969 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14970 (match_operand:SI 4 "" "")
14971 (match_operand:SI 2 "register_operand" "b")
14974 (const:SI (unspec:SI
14975 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14977 (clobber (reg:CC FLAGS_REG))]
14978 "!TARGET_64BIT && TARGET_GNU2_TLS"
14981 [(set (match_dup 0) (match_dup 5))]
14983 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14984 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14987 (define_expand "tls_dynamic_gnu2_64"
14988 [(set (match_dup 2)
14989 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14992 [(set (match_operand:DI 0 "register_operand" "")
14993 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14995 (clobber (reg:CC FLAGS_REG))])]
14996 "TARGET_64BIT && TARGET_GNU2_TLS"
14998 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14999 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15002 (define_insn "*tls_dynamic_lea_64"
15003 [(set (match_operand:DI 0 "register_operand" "=r")
15004 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15006 "TARGET_64BIT && TARGET_GNU2_TLS"
15007 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15008 [(set_attr "type" "lea")
15009 (set_attr "mode" "DI")
15010 (set_attr "length" "7")
15011 (set_attr "length_address" "4")])
15013 (define_insn "*tls_dynamic_call_64"
15014 [(set (match_operand:DI 0 "register_operand" "=a")
15015 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15016 (match_operand:DI 2 "register_operand" "0")
15019 (clobber (reg:CC FLAGS_REG))]
15020 "TARGET_64BIT && TARGET_GNU2_TLS"
15021 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15022 [(set_attr "type" "call")
15023 (set_attr "length" "2")
15024 (set_attr "length_address" "0")])
15026 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15027 [(set (match_operand:DI 0 "register_operand" "=&a")
15029 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15030 (match_operand:DI 3 "" "")
15033 (const:DI (unspec:DI
15034 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15036 (clobber (reg:CC FLAGS_REG))]
15037 "TARGET_64BIT && TARGET_GNU2_TLS"
15040 [(set (match_dup 0) (match_dup 4))]
15042 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15043 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15048 ;; These patterns match the binary 387 instructions for addM3, subM3,
15049 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15050 ;; SFmode. The first is the normal insn, the second the same insn but
15051 ;; with one operand a conversion, and the third the same insn but with
15052 ;; the other operand a conversion. The conversion may be SFmode or
15053 ;; SImode if the target mode DFmode, but only SImode if the target mode
15056 ;; Gcc is slightly more smart about handling normal two address instructions
15057 ;; so use special patterns for add and mull.
15059 (define_insn "*fop_sf_comm_mixed"
15060 [(set (match_operand:SF 0 "register_operand" "=f,x")
15061 (match_operator:SF 3 "binary_fp_operator"
15062 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15063 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15064 "TARGET_MIX_SSE_I387
15065 && COMMUTATIVE_ARITH_P (operands[3])
15066 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15067 "* return output_387_binary_op (insn, operands);"
15068 [(set (attr "type")
15069 (if_then_else (eq_attr "alternative" "1")
15070 (if_then_else (match_operand:SF 3 "mult_operator" "")
15071 (const_string "ssemul")
15072 (const_string "sseadd"))
15073 (if_then_else (match_operand:SF 3 "mult_operator" "")
15074 (const_string "fmul")
15075 (const_string "fop"))))
15076 (set_attr "mode" "SF")])
15078 (define_insn "*fop_sf_comm_sse"
15079 [(set (match_operand:SF 0 "register_operand" "=x")
15080 (match_operator:SF 3 "binary_fp_operator"
15081 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15082 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15084 && COMMUTATIVE_ARITH_P (operands[3])
15085 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15086 "* return output_387_binary_op (insn, operands);"
15087 [(set (attr "type")
15088 (if_then_else (match_operand:SF 3 "mult_operator" "")
15089 (const_string "ssemul")
15090 (const_string "sseadd")))
15091 (set_attr "mode" "SF")])
15093 (define_insn "*fop_sf_comm_i387"
15094 [(set (match_operand:SF 0 "register_operand" "=f")
15095 (match_operator:SF 3 "binary_fp_operator"
15096 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15097 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15099 && COMMUTATIVE_ARITH_P (operands[3])
15100 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15101 "* return output_387_binary_op (insn, operands);"
15102 [(set (attr "type")
15103 (if_then_else (match_operand:SF 3 "mult_operator" "")
15104 (const_string "fmul")
15105 (const_string "fop")))
15106 (set_attr "mode" "SF")])
15108 (define_insn "*fop_sf_1_mixed"
15109 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15110 (match_operator:SF 3 "binary_fp_operator"
15111 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15112 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15113 "TARGET_MIX_SSE_I387
15114 && !COMMUTATIVE_ARITH_P (operands[3])
15115 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15116 "* return output_387_binary_op (insn, operands);"
15117 [(set (attr "type")
15118 (cond [(and (eq_attr "alternative" "2")
15119 (match_operand:SF 3 "mult_operator" ""))
15120 (const_string "ssemul")
15121 (and (eq_attr "alternative" "2")
15122 (match_operand:SF 3 "div_operator" ""))
15123 (const_string "ssediv")
15124 (eq_attr "alternative" "2")
15125 (const_string "sseadd")
15126 (match_operand:SF 3 "mult_operator" "")
15127 (const_string "fmul")
15128 (match_operand:SF 3 "div_operator" "")
15129 (const_string "fdiv")
15131 (const_string "fop")))
15132 (set_attr "mode" "SF")])
15134 (define_insn "*fop_sf_1_sse"
15135 [(set (match_operand:SF 0 "register_operand" "=x")
15136 (match_operator:SF 3 "binary_fp_operator"
15137 [(match_operand:SF 1 "register_operand" "0")
15138 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15140 && !COMMUTATIVE_ARITH_P (operands[3])"
15141 "* return output_387_binary_op (insn, operands);"
15142 [(set (attr "type")
15143 (cond [(match_operand:SF 3 "mult_operator" "")
15144 (const_string "ssemul")
15145 (match_operand:SF 3 "div_operator" "")
15146 (const_string "ssediv")
15148 (const_string "sseadd")))
15149 (set_attr "mode" "SF")])
15151 ;; This pattern is not fully shadowed by the pattern above.
15152 (define_insn "*fop_sf_1_i387"
15153 [(set (match_operand:SF 0 "register_operand" "=f,f")
15154 (match_operator:SF 3 "binary_fp_operator"
15155 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15156 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15157 "TARGET_80387 && !TARGET_SSE_MATH
15158 && !COMMUTATIVE_ARITH_P (operands[3])
15159 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15160 "* return output_387_binary_op (insn, operands);"
15161 [(set (attr "type")
15162 (cond [(match_operand:SF 3 "mult_operator" "")
15163 (const_string "fmul")
15164 (match_operand:SF 3 "div_operator" "")
15165 (const_string "fdiv")
15167 (const_string "fop")))
15168 (set_attr "mode" "SF")])
15170 ;; ??? Add SSE splitters for these!
15171 (define_insn "*fop_sf_2<mode>_i387"
15172 [(set (match_operand:SF 0 "register_operand" "=f,f")
15173 (match_operator:SF 3 "binary_fp_operator"
15174 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15175 (match_operand:SF 2 "register_operand" "0,0")]))]
15176 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15177 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15178 [(set (attr "type")
15179 (cond [(match_operand:SF 3 "mult_operator" "")
15180 (const_string "fmul")
15181 (match_operand:SF 3 "div_operator" "")
15182 (const_string "fdiv")
15184 (const_string "fop")))
15185 (set_attr "fp_int_src" "true")
15186 (set_attr "mode" "<MODE>")])
15188 (define_insn "*fop_sf_3<mode>_i387"
15189 [(set (match_operand:SF 0 "register_operand" "=f,f")
15190 (match_operator:SF 3 "binary_fp_operator"
15191 [(match_operand:SF 1 "register_operand" "0,0")
15192 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15193 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15194 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15195 [(set (attr "type")
15196 (cond [(match_operand:SF 3 "mult_operator" "")
15197 (const_string "fmul")
15198 (match_operand:SF 3 "div_operator" "")
15199 (const_string "fdiv")
15201 (const_string "fop")))
15202 (set_attr "fp_int_src" "true")
15203 (set_attr "mode" "<MODE>")])
15205 (define_insn "*fop_df_comm_mixed"
15206 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15207 (match_operator:DF 3 "binary_fp_operator"
15208 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15209 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15210 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15211 && COMMUTATIVE_ARITH_P (operands[3])
15212 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15213 "* return output_387_binary_op (insn, operands);"
15214 [(set (attr "type")
15215 (if_then_else (eq_attr "alternative" "1")
15216 (if_then_else (match_operand:DF 3 "mult_operator" "")
15217 (const_string "ssemul")
15218 (const_string "sseadd"))
15219 (if_then_else (match_operand:DF 3 "mult_operator" "")
15220 (const_string "fmul")
15221 (const_string "fop"))))
15222 (set_attr "mode" "DF")])
15224 (define_insn "*fop_df_comm_sse"
15225 [(set (match_operand:DF 0 "register_operand" "=Y")
15226 (match_operator:DF 3 "binary_fp_operator"
15227 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15228 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15229 "TARGET_SSE2 && TARGET_SSE_MATH
15230 && COMMUTATIVE_ARITH_P (operands[3])
15231 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15232 "* return output_387_binary_op (insn, operands);"
15233 [(set (attr "type")
15234 (if_then_else (match_operand:DF 3 "mult_operator" "")
15235 (const_string "ssemul")
15236 (const_string "sseadd")))
15237 (set_attr "mode" "DF")])
15239 (define_insn "*fop_df_comm_i387"
15240 [(set (match_operand:DF 0 "register_operand" "=f")
15241 (match_operator:DF 3 "binary_fp_operator"
15242 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15243 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15245 && COMMUTATIVE_ARITH_P (operands[3])
15246 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15247 "* return output_387_binary_op (insn, operands);"
15248 [(set (attr "type")
15249 (if_then_else (match_operand:DF 3 "mult_operator" "")
15250 (const_string "fmul")
15251 (const_string "fop")))
15252 (set_attr "mode" "DF")])
15254 (define_insn "*fop_df_1_mixed"
15255 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15256 (match_operator:DF 3 "binary_fp_operator"
15257 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15258 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15259 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15260 && !COMMUTATIVE_ARITH_P (operands[3])
15261 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15262 "* return output_387_binary_op (insn, operands);"
15263 [(set (attr "type")
15264 (cond [(and (eq_attr "alternative" "2")
15265 (match_operand:DF 3 "mult_operator" ""))
15266 (const_string "ssemul")
15267 (and (eq_attr "alternative" "2")
15268 (match_operand:DF 3 "div_operator" ""))
15269 (const_string "ssediv")
15270 (eq_attr "alternative" "2")
15271 (const_string "sseadd")
15272 (match_operand:DF 3 "mult_operator" "")
15273 (const_string "fmul")
15274 (match_operand:DF 3 "div_operator" "")
15275 (const_string "fdiv")
15277 (const_string "fop")))
15278 (set_attr "mode" "DF")])
15280 (define_insn "*fop_df_1_sse"
15281 [(set (match_operand:DF 0 "register_operand" "=Y")
15282 (match_operator:DF 3 "binary_fp_operator"
15283 [(match_operand:DF 1 "register_operand" "0")
15284 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15285 "TARGET_SSE2 && TARGET_SSE_MATH
15286 && !COMMUTATIVE_ARITH_P (operands[3])"
15287 "* return output_387_binary_op (insn, operands);"
15288 [(set_attr "mode" "DF")
15290 (cond [(match_operand:DF 3 "mult_operator" "")
15291 (const_string "ssemul")
15292 (match_operand:DF 3 "div_operator" "")
15293 (const_string "ssediv")
15295 (const_string "sseadd")))])
15297 ;; This pattern is not fully shadowed by the pattern above.
15298 (define_insn "*fop_df_1_i387"
15299 [(set (match_operand:DF 0 "register_operand" "=f,f")
15300 (match_operator:DF 3 "binary_fp_operator"
15301 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15302 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15303 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15304 && !COMMUTATIVE_ARITH_P (operands[3])
15305 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15306 "* return output_387_binary_op (insn, operands);"
15307 [(set (attr "type")
15308 (cond [(match_operand:DF 3 "mult_operator" "")
15309 (const_string "fmul")
15310 (match_operand:DF 3 "div_operator" "")
15311 (const_string "fdiv")
15313 (const_string "fop")))
15314 (set_attr "mode" "DF")])
15316 ;; ??? Add SSE splitters for these!
15317 (define_insn "*fop_df_2<mode>_i387"
15318 [(set (match_operand:DF 0 "register_operand" "=f,f")
15319 (match_operator:DF 3 "binary_fp_operator"
15320 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15321 (match_operand:DF 2 "register_operand" "0,0")]))]
15322 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15323 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15324 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15325 [(set (attr "type")
15326 (cond [(match_operand:DF 3 "mult_operator" "")
15327 (const_string "fmul")
15328 (match_operand:DF 3 "div_operator" "")
15329 (const_string "fdiv")
15331 (const_string "fop")))
15332 (set_attr "fp_int_src" "true")
15333 (set_attr "mode" "<MODE>")])
15335 (define_insn "*fop_df_3<mode>_i387"
15336 [(set (match_operand:DF 0 "register_operand" "=f,f")
15337 (match_operator:DF 3 "binary_fp_operator"
15338 [(match_operand:DF 1 "register_operand" "0,0")
15339 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15340 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15341 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15342 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15343 [(set (attr "type")
15344 (cond [(match_operand:DF 3 "mult_operator" "")
15345 (const_string "fmul")
15346 (match_operand:DF 3 "div_operator" "")
15347 (const_string "fdiv")
15349 (const_string "fop")))
15350 (set_attr "fp_int_src" "true")
15351 (set_attr "mode" "<MODE>")])
15353 (define_insn "*fop_df_4_i387"
15354 [(set (match_operand:DF 0 "register_operand" "=f,f")
15355 (match_operator:DF 3 "binary_fp_operator"
15356 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15357 (match_operand:DF 2 "register_operand" "0,f")]))]
15358 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15359 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15360 "* return output_387_binary_op (insn, operands);"
15361 [(set (attr "type")
15362 (cond [(match_operand:DF 3 "mult_operator" "")
15363 (const_string "fmul")
15364 (match_operand:DF 3 "div_operator" "")
15365 (const_string "fdiv")
15367 (const_string "fop")))
15368 (set_attr "mode" "SF")])
15370 (define_insn "*fop_df_5_i387"
15371 [(set (match_operand:DF 0 "register_operand" "=f,f")
15372 (match_operator:DF 3 "binary_fp_operator"
15373 [(match_operand:DF 1 "register_operand" "0,f")
15375 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15376 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15377 "* return output_387_binary_op (insn, operands);"
15378 [(set (attr "type")
15379 (cond [(match_operand:DF 3 "mult_operator" "")
15380 (const_string "fmul")
15381 (match_operand:DF 3 "div_operator" "")
15382 (const_string "fdiv")
15384 (const_string "fop")))
15385 (set_attr "mode" "SF")])
15387 (define_insn "*fop_df_6_i387"
15388 [(set (match_operand:DF 0 "register_operand" "=f,f")
15389 (match_operator:DF 3 "binary_fp_operator"
15391 (match_operand:SF 1 "register_operand" "0,f"))
15393 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15394 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15395 "* return output_387_binary_op (insn, operands);"
15396 [(set (attr "type")
15397 (cond [(match_operand:DF 3 "mult_operator" "")
15398 (const_string "fmul")
15399 (match_operand:DF 3 "div_operator" "")
15400 (const_string "fdiv")
15402 (const_string "fop")))
15403 (set_attr "mode" "SF")])
15405 (define_insn "*fop_xf_comm_i387"
15406 [(set (match_operand:XF 0 "register_operand" "=f")
15407 (match_operator:XF 3 "binary_fp_operator"
15408 [(match_operand:XF 1 "register_operand" "%0")
15409 (match_operand:XF 2 "register_operand" "f")]))]
15411 && COMMUTATIVE_ARITH_P (operands[3])"
15412 "* return output_387_binary_op (insn, operands);"
15413 [(set (attr "type")
15414 (if_then_else (match_operand:XF 3 "mult_operator" "")
15415 (const_string "fmul")
15416 (const_string "fop")))
15417 (set_attr "mode" "XF")])
15419 (define_insn "*fop_xf_1_i387"
15420 [(set (match_operand:XF 0 "register_operand" "=f,f")
15421 (match_operator:XF 3 "binary_fp_operator"
15422 [(match_operand:XF 1 "register_operand" "0,f")
15423 (match_operand:XF 2 "register_operand" "f,0")]))]
15425 && !COMMUTATIVE_ARITH_P (operands[3])"
15426 "* return output_387_binary_op (insn, operands);"
15427 [(set (attr "type")
15428 (cond [(match_operand:XF 3 "mult_operator" "")
15429 (const_string "fmul")
15430 (match_operand:XF 3 "div_operator" "")
15431 (const_string "fdiv")
15433 (const_string "fop")))
15434 (set_attr "mode" "XF")])
15436 (define_insn "*fop_xf_2<mode>_i387"
15437 [(set (match_operand:XF 0 "register_operand" "=f,f")
15438 (match_operator:XF 3 "binary_fp_operator"
15439 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15440 (match_operand:XF 2 "register_operand" "0,0")]))]
15441 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15442 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15443 [(set (attr "type")
15444 (cond [(match_operand:XF 3 "mult_operator" "")
15445 (const_string "fmul")
15446 (match_operand:XF 3 "div_operator" "")
15447 (const_string "fdiv")
15449 (const_string "fop")))
15450 (set_attr "fp_int_src" "true")
15451 (set_attr "mode" "<MODE>")])
15453 (define_insn "*fop_xf_3<mode>_i387"
15454 [(set (match_operand:XF 0 "register_operand" "=f,f")
15455 (match_operator:XF 3 "binary_fp_operator"
15456 [(match_operand:XF 1 "register_operand" "0,0")
15457 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15458 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15459 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15460 [(set (attr "type")
15461 (cond [(match_operand:XF 3 "mult_operator" "")
15462 (const_string "fmul")
15463 (match_operand:XF 3 "div_operator" "")
15464 (const_string "fdiv")
15466 (const_string "fop")))
15467 (set_attr "fp_int_src" "true")
15468 (set_attr "mode" "<MODE>")])
15470 (define_insn "*fop_xf_4_i387"
15471 [(set (match_operand:XF 0 "register_operand" "=f,f")
15472 (match_operator:XF 3 "binary_fp_operator"
15473 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15474 (match_operand:XF 2 "register_operand" "0,f")]))]
15476 "* return output_387_binary_op (insn, operands);"
15477 [(set (attr "type")
15478 (cond [(match_operand:XF 3 "mult_operator" "")
15479 (const_string "fmul")
15480 (match_operand:XF 3 "div_operator" "")
15481 (const_string "fdiv")
15483 (const_string "fop")))
15484 (set_attr "mode" "SF")])
15486 (define_insn "*fop_xf_5_i387"
15487 [(set (match_operand:XF 0 "register_operand" "=f,f")
15488 (match_operator:XF 3 "binary_fp_operator"
15489 [(match_operand:XF 1 "register_operand" "0,f")
15491 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15493 "* return output_387_binary_op (insn, operands);"
15494 [(set (attr "type")
15495 (cond [(match_operand:XF 3 "mult_operator" "")
15496 (const_string "fmul")
15497 (match_operand:XF 3 "div_operator" "")
15498 (const_string "fdiv")
15500 (const_string "fop")))
15501 (set_attr "mode" "SF")])
15503 (define_insn "*fop_xf_6_i387"
15504 [(set (match_operand:XF 0 "register_operand" "=f,f")
15505 (match_operator:XF 3 "binary_fp_operator"
15507 (match_operand 1 "register_operand" "0,f"))
15509 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15511 "* return output_387_binary_op (insn, operands);"
15512 [(set (attr "type")
15513 (cond [(match_operand:XF 3 "mult_operator" "")
15514 (const_string "fmul")
15515 (match_operand:XF 3 "div_operator" "")
15516 (const_string "fdiv")
15518 (const_string "fop")))
15519 (set_attr "mode" "SF")])
15522 [(set (match_operand 0 "register_operand" "")
15523 (match_operator 3 "binary_fp_operator"
15524 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15525 (match_operand 2 "register_operand" "")]))]
15526 "TARGET_80387 && reload_completed
15527 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15530 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15531 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15532 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15533 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15534 GET_MODE (operands[3]),
15537 ix86_free_from_memory (GET_MODE (operands[1]));
15542 [(set (match_operand 0 "register_operand" "")
15543 (match_operator 3 "binary_fp_operator"
15544 [(match_operand 1 "register_operand" "")
15545 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15546 "TARGET_80387 && reload_completed
15547 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15550 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15551 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15552 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15553 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15554 GET_MODE (operands[3]),
15557 ix86_free_from_memory (GET_MODE (operands[2]));
15561 ;; FPU special functions.
15563 ;; This pattern implements a no-op XFmode truncation for
15564 ;; all fancy i386 XFmode math functions.
15566 (define_insn "truncxf<mode>2_i387_noop_unspec"
15567 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15568 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15569 UNSPEC_TRUNC_NOOP))]
15570 "TARGET_USE_FANCY_MATH_387"
15571 "* return output_387_reg_move (insn, operands);"
15572 [(set_attr "type" "fmov")
15573 (set_attr "mode" "<MODE>")])
15575 (define_insn "sqrtxf2"
15576 [(set (match_operand:XF 0 "register_operand" "=f")
15577 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15578 "TARGET_USE_FANCY_MATH_387"
15580 [(set_attr "type" "fpspc")
15581 (set_attr "mode" "XF")
15582 (set_attr "athlon_decode" "direct")])
15584 (define_insn "sqrt_extend<mode>xf2_i387"
15585 [(set (match_operand:XF 0 "register_operand" "=f")
15588 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15589 "TARGET_USE_FANCY_MATH_387"
15591 [(set_attr "type" "fpspc")
15592 (set_attr "mode" "XF")
15593 (set_attr "athlon_decode" "direct")])
15595 (define_insn "*sqrt<mode>2_sse"
15596 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15598 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15599 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15600 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15601 [(set_attr "type" "sse")
15602 (set_attr "mode" "<MODE>")
15603 (set_attr "athlon_decode" "*")])
15605 (define_expand "sqrt<mode>2"
15606 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15608 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15609 "TARGET_USE_FANCY_MATH_387
15610 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15612 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15614 rtx op0 = gen_reg_rtx (XFmode);
15615 rtx op1 = force_reg (<MODE>mode, operands[1]);
15617 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15618 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15623 (define_insn "fpremxf4_i387"
15624 [(set (match_operand:XF 0 "register_operand" "=f")
15625 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15626 (match_operand:XF 3 "register_operand" "1")]
15628 (set (match_operand:XF 1 "register_operand" "=u")
15629 (unspec:XF [(match_dup 2) (match_dup 3)]
15631 (set (reg:CCFP FPSR_REG)
15632 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15633 "TARGET_USE_FANCY_MATH_387"
15635 [(set_attr "type" "fpspc")
15636 (set_attr "mode" "XF")])
15638 (define_expand "fmodxf3"
15639 [(use (match_operand:XF 0 "register_operand" ""))
15640 (use (match_operand:XF 1 "register_operand" ""))
15641 (use (match_operand:XF 2 "register_operand" ""))]
15642 "TARGET_USE_FANCY_MATH_387"
15644 rtx label = gen_label_rtx ();
15646 emit_label (label);
15648 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15649 operands[1], operands[2]));
15650 ix86_emit_fp_unordered_jump (label);
15652 emit_move_insn (operands[0], operands[1]);
15656 (define_expand "fmod<mode>3"
15657 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15658 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15659 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15660 "TARGET_USE_FANCY_MATH_387
15661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15662 || TARGET_MIX_SSE_I387)"
15664 rtx label = gen_label_rtx ();
15666 rtx op1 = gen_reg_rtx (XFmode);
15667 rtx op2 = gen_reg_rtx (XFmode);
15669 emit_insn(gen_extend<mode>xf2 (op1, operands[1]));
15670 emit_insn(gen_extend<mode>xf2 (op2, operands[2]));
15672 emit_label (label);
15673 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15674 ix86_emit_fp_unordered_jump (label);
15676 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15680 (define_insn "fprem1xf4_i387"
15681 [(set (match_operand:XF 0 "register_operand" "=f")
15682 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15683 (match_operand:XF 3 "register_operand" "1")]
15685 (set (match_operand:XF 1 "register_operand" "=u")
15686 (unspec:XF [(match_dup 2) (match_dup 3)]
15688 (set (reg:CCFP FPSR_REG)
15689 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15690 "TARGET_USE_FANCY_MATH_387"
15692 [(set_attr "type" "fpspc")
15693 (set_attr "mode" "XF")])
15695 (define_expand "remainderxf3"
15696 [(use (match_operand:XF 0 "register_operand" ""))
15697 (use (match_operand:XF 1 "register_operand" ""))
15698 (use (match_operand:XF 2 "register_operand" ""))]
15699 "TARGET_USE_FANCY_MATH_387"
15701 rtx label = gen_label_rtx ();
15703 emit_label (label);
15705 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15706 operands[1], operands[2]));
15707 ix86_emit_fp_unordered_jump (label);
15709 emit_move_insn (operands[0], operands[1]);
15713 (define_expand "remainder<mode>3"
15714 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15715 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15716 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15717 "TARGET_USE_FANCY_MATH_387
15718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15719 || TARGET_MIX_SSE_I387)"
15721 rtx label = gen_label_rtx ();
15723 rtx op1 = gen_reg_rtx (XFmode);
15724 rtx op2 = gen_reg_rtx (XFmode);
15726 emit_insn(gen_extend<mode>xf2 (op1, operands[1]));
15727 emit_insn(gen_extend<mode>xf2 (op2, operands[2]));
15729 emit_label (label);
15731 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15732 ix86_emit_fp_unordered_jump (label);
15734 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15738 (define_insn "*sindf2"
15739 [(set (match_operand:DF 0 "register_operand" "=f")
15740 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15741 "TARGET_USE_FANCY_MATH_387
15742 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15743 && flag_unsafe_math_optimizations"
15745 [(set_attr "type" "fpspc")
15746 (set_attr "mode" "DF")])
15748 (define_insn "*sinsf2"
15749 [(set (match_operand:SF 0 "register_operand" "=f")
15750 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15751 "TARGET_USE_FANCY_MATH_387
15752 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15753 && flag_unsafe_math_optimizations"
15755 [(set_attr "type" "fpspc")
15756 (set_attr "mode" "SF")])
15758 (define_insn "*sinextendsfdf2"
15759 [(set (match_operand:DF 0 "register_operand" "=f")
15760 (unspec:DF [(float_extend:DF
15761 (match_operand:SF 1 "register_operand" "0"))]
15763 "TARGET_USE_FANCY_MATH_387
15764 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15765 && flag_unsafe_math_optimizations"
15767 [(set_attr "type" "fpspc")
15768 (set_attr "mode" "DF")])
15770 (define_insn "*sinxf2"
15771 [(set (match_operand:XF 0 "register_operand" "=f")
15772 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15773 "TARGET_USE_FANCY_MATH_387
15774 && flag_unsafe_math_optimizations"
15776 [(set_attr "type" "fpspc")
15777 (set_attr "mode" "XF")])
15779 (define_insn "*cosdf2"
15780 [(set (match_operand:DF 0 "register_operand" "=f")
15781 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15782 "TARGET_USE_FANCY_MATH_387
15783 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15784 && flag_unsafe_math_optimizations"
15786 [(set_attr "type" "fpspc")
15787 (set_attr "mode" "DF")])
15789 (define_insn "*cossf2"
15790 [(set (match_operand:SF 0 "register_operand" "=f")
15791 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15792 "TARGET_USE_FANCY_MATH_387
15793 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15794 && flag_unsafe_math_optimizations"
15796 [(set_attr "type" "fpspc")
15797 (set_attr "mode" "SF")])
15799 (define_insn "*cosextendsfdf2"
15800 [(set (match_operand:DF 0 "register_operand" "=f")
15801 (unspec:DF [(float_extend:DF
15802 (match_operand:SF 1 "register_operand" "0"))]
15804 "TARGET_USE_FANCY_MATH_387
15805 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15806 && flag_unsafe_math_optimizations"
15808 [(set_attr "type" "fpspc")
15809 (set_attr "mode" "DF")])
15811 (define_insn "*cosxf2"
15812 [(set (match_operand:XF 0 "register_operand" "=f")
15813 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15814 "TARGET_USE_FANCY_MATH_387
15815 && flag_unsafe_math_optimizations"
15817 [(set_attr "type" "fpspc")
15818 (set_attr "mode" "XF")])
15820 ;; With sincos pattern defined, sin and cos builtin function will be
15821 ;; expanded to sincos pattern with one of its outputs left unused.
15822 ;; Cse pass will detected, if two sincos patterns can be combined,
15823 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15824 ;; depending on the unused output.
15826 (define_insn "sincosdf3"
15827 [(set (match_operand:DF 0 "register_operand" "=f")
15828 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15829 UNSPEC_SINCOS_COS))
15830 (set (match_operand:DF 1 "register_operand" "=u")
15831 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15832 "TARGET_USE_FANCY_MATH_387
15833 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15834 && flag_unsafe_math_optimizations"
15836 [(set_attr "type" "fpspc")
15837 (set_attr "mode" "DF")])
15840 [(set (match_operand:DF 0 "register_operand" "")
15841 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15842 UNSPEC_SINCOS_COS))
15843 (set (match_operand:DF 1 "register_operand" "")
15844 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15845 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15846 && !reload_completed && !reload_in_progress"
15847 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15851 [(set (match_operand:DF 0 "register_operand" "")
15852 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15853 UNSPEC_SINCOS_COS))
15854 (set (match_operand:DF 1 "register_operand" "")
15855 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15856 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15857 && !reload_completed && !reload_in_progress"
15858 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15861 (define_insn "sincossf3"
15862 [(set (match_operand:SF 0 "register_operand" "=f")
15863 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15864 UNSPEC_SINCOS_COS))
15865 (set (match_operand:SF 1 "register_operand" "=u")
15866 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15867 "TARGET_USE_FANCY_MATH_387
15868 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15869 && flag_unsafe_math_optimizations"
15871 [(set_attr "type" "fpspc")
15872 (set_attr "mode" "SF")])
15875 [(set (match_operand:SF 0 "register_operand" "")
15876 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15877 UNSPEC_SINCOS_COS))
15878 (set (match_operand:SF 1 "register_operand" "")
15879 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15880 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15881 && !reload_completed && !reload_in_progress"
15882 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15886 [(set (match_operand:SF 0 "register_operand" "")
15887 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15888 UNSPEC_SINCOS_COS))
15889 (set (match_operand:SF 1 "register_operand" "")
15890 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15891 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15892 && !reload_completed && !reload_in_progress"
15893 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15896 (define_insn "*sincosextendsfdf3"
15897 [(set (match_operand:DF 0 "register_operand" "=f")
15898 (unspec:DF [(float_extend:DF
15899 (match_operand:SF 2 "register_operand" "0"))]
15900 UNSPEC_SINCOS_COS))
15901 (set (match_operand:DF 1 "register_operand" "=u")
15902 (unspec:DF [(float_extend:DF
15903 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15904 "TARGET_USE_FANCY_MATH_387
15905 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15906 && flag_unsafe_math_optimizations"
15908 [(set_attr "type" "fpspc")
15909 (set_attr "mode" "DF")])
15912 [(set (match_operand:DF 0 "register_operand" "")
15913 (unspec:DF [(float_extend:DF
15914 (match_operand:SF 2 "register_operand" ""))]
15915 UNSPEC_SINCOS_COS))
15916 (set (match_operand:DF 1 "register_operand" "")
15917 (unspec:DF [(float_extend:DF
15918 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15919 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15920 && !reload_completed && !reload_in_progress"
15921 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15922 (match_dup 2))] UNSPEC_SIN))]
15926 [(set (match_operand:DF 0 "register_operand" "")
15927 (unspec:DF [(float_extend:DF
15928 (match_operand:SF 2 "register_operand" ""))]
15929 UNSPEC_SINCOS_COS))
15930 (set (match_operand:DF 1 "register_operand" "")
15931 (unspec:DF [(float_extend:DF
15932 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15933 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15934 && !reload_completed && !reload_in_progress"
15935 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15936 (match_dup 2))] UNSPEC_COS))]
15939 (define_insn "sincosxf3"
15940 [(set (match_operand:XF 0 "register_operand" "=f")
15941 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15942 UNSPEC_SINCOS_COS))
15943 (set (match_operand:XF 1 "register_operand" "=u")
15944 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15945 "TARGET_USE_FANCY_MATH_387
15946 && flag_unsafe_math_optimizations"
15948 [(set_attr "type" "fpspc")
15949 (set_attr "mode" "XF")])
15952 [(set (match_operand:XF 0 "register_operand" "")
15953 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15954 UNSPEC_SINCOS_COS))
15955 (set (match_operand:XF 1 "register_operand" "")
15956 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15957 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15958 && !reload_completed && !reload_in_progress"
15959 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15963 [(set (match_operand:XF 0 "register_operand" "")
15964 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15965 UNSPEC_SINCOS_COS))
15966 (set (match_operand:XF 1 "register_operand" "")
15967 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15968 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15969 && !reload_completed && !reload_in_progress"
15970 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15973 (define_insn "*tandf3_1"
15974 [(set (match_operand:DF 0 "register_operand" "=f")
15975 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15977 (set (match_operand:DF 1 "register_operand" "=u")
15978 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15979 "TARGET_USE_FANCY_MATH_387
15980 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15981 && flag_unsafe_math_optimizations"
15983 [(set_attr "type" "fpspc")
15984 (set_attr "mode" "DF")])
15986 ;; optimize sequence: fptan
15989 ;; into fptan insn.
15992 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15993 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15995 (set (match_operand:DF 1 "register_operand" "")
15996 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15998 (match_operand:DF 3 "immediate_operand" ""))]
15999 "standard_80387_constant_p (operands[3]) == 2"
16000 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16001 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16004 (define_expand "tandf2"
16005 [(parallel [(set (match_dup 2)
16006 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16008 (set (match_operand:DF 0 "register_operand" "")
16009 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16010 "TARGET_USE_FANCY_MATH_387
16011 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16012 && flag_unsafe_math_optimizations"
16014 operands[2] = gen_reg_rtx (DFmode);
16017 (define_insn "*tansf3_1"
16018 [(set (match_operand:SF 0 "register_operand" "=f")
16019 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16021 (set (match_operand:SF 1 "register_operand" "=u")
16022 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16023 "TARGET_USE_FANCY_MATH_387
16024 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16025 && flag_unsafe_math_optimizations"
16027 [(set_attr "type" "fpspc")
16028 (set_attr "mode" "SF")])
16030 ;; optimize sequence: fptan
16033 ;; into fptan insn.
16036 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16037 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16039 (set (match_operand:SF 1 "register_operand" "")
16040 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16042 (match_operand:SF 3 "immediate_operand" ""))]
16043 "standard_80387_constant_p (operands[3]) == 2"
16044 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16045 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16048 (define_expand "tansf2"
16049 [(parallel [(set (match_dup 2)
16050 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16052 (set (match_operand:SF 0 "register_operand" "")
16053 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16054 "TARGET_USE_FANCY_MATH_387
16055 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16056 && flag_unsafe_math_optimizations"
16058 operands[2] = gen_reg_rtx (SFmode);
16061 (define_insn "*tanxf3_1"
16062 [(set (match_operand:XF 0 "register_operand" "=f")
16063 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16065 (set (match_operand:XF 1 "register_operand" "=u")
16066 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16067 "TARGET_USE_FANCY_MATH_387
16068 && flag_unsafe_math_optimizations"
16070 [(set_attr "type" "fpspc")
16071 (set_attr "mode" "XF")])
16073 ;; optimize sequence: fptan
16076 ;; into fptan insn.
16079 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16080 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16082 (set (match_operand:XF 1 "register_operand" "")
16083 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16085 (match_operand:XF 3 "immediate_operand" ""))]
16086 "standard_80387_constant_p (operands[3]) == 2"
16087 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16088 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16091 (define_expand "tanxf2"
16092 [(parallel [(set (match_dup 2)
16093 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16095 (set (match_operand:XF 0 "register_operand" "")
16096 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16097 "TARGET_USE_FANCY_MATH_387
16098 && flag_unsafe_math_optimizations"
16100 operands[2] = gen_reg_rtx (XFmode);
16103 (define_insn "atan2df3_1"
16104 [(set (match_operand:DF 0 "register_operand" "=f")
16105 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16106 (match_operand:DF 1 "register_operand" "u")]
16108 (clobber (match_scratch:DF 3 "=1"))]
16109 "TARGET_USE_FANCY_MATH_387
16110 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16111 && flag_unsafe_math_optimizations"
16113 [(set_attr "type" "fpspc")
16114 (set_attr "mode" "DF")])
16116 (define_expand "atan2df3"
16117 [(use (match_operand:DF 0 "register_operand" ""))
16118 (use (match_operand:DF 2 "register_operand" ""))
16119 (use (match_operand:DF 1 "register_operand" ""))]
16120 "TARGET_USE_FANCY_MATH_387
16121 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16122 && flag_unsafe_math_optimizations"
16124 rtx copy = gen_reg_rtx (DFmode);
16125 emit_move_insn (copy, operands[1]);
16126 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16130 (define_expand "atandf2"
16131 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16132 (unspec:DF [(match_dup 2)
16133 (match_operand:DF 1 "register_operand" "")]
16135 (clobber (match_scratch:DF 3 ""))])]
16136 "TARGET_USE_FANCY_MATH_387
16137 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16138 && flag_unsafe_math_optimizations"
16140 operands[2] = gen_reg_rtx (DFmode);
16141 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16144 (define_insn "atan2sf3_1"
16145 [(set (match_operand:SF 0 "register_operand" "=f")
16146 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16147 (match_operand:SF 1 "register_operand" "u")]
16149 (clobber (match_scratch:SF 3 "=1"))]
16150 "TARGET_USE_FANCY_MATH_387
16151 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16152 && flag_unsafe_math_optimizations"
16154 [(set_attr "type" "fpspc")
16155 (set_attr "mode" "SF")])
16157 (define_expand "atan2sf3"
16158 [(use (match_operand:SF 0 "register_operand" ""))
16159 (use (match_operand:SF 2 "register_operand" ""))
16160 (use (match_operand:SF 1 "register_operand" ""))]
16161 "TARGET_USE_FANCY_MATH_387
16162 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16163 && flag_unsafe_math_optimizations"
16165 rtx copy = gen_reg_rtx (SFmode);
16166 emit_move_insn (copy, operands[1]);
16167 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16171 (define_expand "atansf2"
16172 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16173 (unspec:SF [(match_dup 2)
16174 (match_operand:SF 1 "register_operand" "")]
16176 (clobber (match_scratch:SF 3 ""))])]
16177 "TARGET_USE_FANCY_MATH_387
16178 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16179 && flag_unsafe_math_optimizations"
16181 operands[2] = gen_reg_rtx (SFmode);
16182 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16185 (define_insn "atan2xf3_1"
16186 [(set (match_operand:XF 0 "register_operand" "=f")
16187 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16188 (match_operand:XF 1 "register_operand" "u")]
16190 (clobber (match_scratch:XF 3 "=1"))]
16191 "TARGET_USE_FANCY_MATH_387
16192 && flag_unsafe_math_optimizations"
16194 [(set_attr "type" "fpspc")
16195 (set_attr "mode" "XF")])
16197 (define_expand "atan2xf3"
16198 [(use (match_operand:XF 0 "register_operand" ""))
16199 (use (match_operand:XF 2 "register_operand" ""))
16200 (use (match_operand:XF 1 "register_operand" ""))]
16201 "TARGET_USE_FANCY_MATH_387
16202 && flag_unsafe_math_optimizations"
16204 rtx copy = gen_reg_rtx (XFmode);
16205 emit_move_insn (copy, operands[1]);
16206 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16210 (define_expand "atanxf2"
16211 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16212 (unspec:XF [(match_dup 2)
16213 (match_operand:XF 1 "register_operand" "")]
16215 (clobber (match_scratch:XF 3 ""))])]
16216 "TARGET_USE_FANCY_MATH_387
16217 && flag_unsafe_math_optimizations"
16219 operands[2] = gen_reg_rtx (XFmode);
16220 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16223 (define_expand "asindf2"
16224 [(set (match_dup 2)
16225 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16226 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16227 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16228 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16229 (parallel [(set (match_dup 7)
16230 (unspec:XF [(match_dup 6) (match_dup 2)]
16232 (clobber (match_scratch:XF 8 ""))])
16233 (set (match_operand:DF 0 "register_operand" "")
16234 (float_truncate:DF (match_dup 7)))]
16235 "TARGET_USE_FANCY_MATH_387
16236 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16237 && flag_unsafe_math_optimizations && !optimize_size"
16241 for (i=2; i<8; i++)
16242 operands[i] = gen_reg_rtx (XFmode);
16244 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16247 (define_expand "asinsf2"
16248 [(set (match_dup 2)
16249 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16250 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16251 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16252 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16253 (parallel [(set (match_dup 7)
16254 (unspec:XF [(match_dup 6) (match_dup 2)]
16256 (clobber (match_scratch:XF 8 ""))])
16257 (set (match_operand:SF 0 "register_operand" "")
16258 (float_truncate:SF (match_dup 7)))]
16259 "TARGET_USE_FANCY_MATH_387
16260 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16261 && flag_unsafe_math_optimizations && !optimize_size"
16265 for (i=2; i<8; i++)
16266 operands[i] = gen_reg_rtx (XFmode);
16268 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16271 (define_expand "asinxf2"
16272 [(set (match_dup 2)
16273 (mult:XF (match_operand:XF 1 "register_operand" "")
16275 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16276 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16277 (parallel [(set (match_operand:XF 0 "register_operand" "")
16278 (unspec:XF [(match_dup 5) (match_dup 1)]
16280 (clobber (match_scratch:XF 6 ""))])]
16281 "TARGET_USE_FANCY_MATH_387
16282 && flag_unsafe_math_optimizations && !optimize_size"
16286 for (i=2; i<6; i++)
16287 operands[i] = gen_reg_rtx (XFmode);
16289 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16292 (define_expand "acosdf2"
16293 [(set (match_dup 2)
16294 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16295 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16296 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16297 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16298 (parallel [(set (match_dup 7)
16299 (unspec:XF [(match_dup 2) (match_dup 6)]
16301 (clobber (match_scratch:XF 8 ""))])
16302 (set (match_operand:DF 0 "register_operand" "")
16303 (float_truncate:DF (match_dup 7)))]
16304 "TARGET_USE_FANCY_MATH_387
16305 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16306 && flag_unsafe_math_optimizations && !optimize_size"
16310 for (i=2; i<8; i++)
16311 operands[i] = gen_reg_rtx (XFmode);
16313 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16316 (define_expand "acossf2"
16317 [(set (match_dup 2)
16318 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16319 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16320 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16321 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16322 (parallel [(set (match_dup 7)
16323 (unspec:XF [(match_dup 2) (match_dup 6)]
16325 (clobber (match_scratch:XF 8 ""))])
16326 (set (match_operand:SF 0 "register_operand" "")
16327 (float_truncate:SF (match_dup 7)))]
16328 "TARGET_USE_FANCY_MATH_387
16329 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16330 && flag_unsafe_math_optimizations && !optimize_size"
16334 for (i=2; i<8; i++)
16335 operands[i] = gen_reg_rtx (XFmode);
16337 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16340 (define_expand "acosxf2"
16341 [(set (match_dup 2)
16342 (mult:XF (match_operand:XF 1 "register_operand" "")
16344 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16345 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16346 (parallel [(set (match_operand:XF 0 "register_operand" "")
16347 (unspec:XF [(match_dup 1) (match_dup 5)]
16349 (clobber (match_scratch:XF 6 ""))])]
16350 "TARGET_USE_FANCY_MATH_387
16351 && flag_unsafe_math_optimizations && !optimize_size"
16355 for (i=2; i<6; i++)
16356 operands[i] = gen_reg_rtx (XFmode);
16358 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16361 (define_insn "fyl2x_xf3"
16362 [(set (match_operand:XF 0 "register_operand" "=f")
16363 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16364 (match_operand:XF 1 "register_operand" "u")]
16366 (clobber (match_scratch:XF 3 "=1"))]
16367 "TARGET_USE_FANCY_MATH_387
16368 && flag_unsafe_math_optimizations"
16370 [(set_attr "type" "fpspc")
16371 (set_attr "mode" "XF")])
16373 (define_expand "logsf2"
16374 [(set (match_dup 2)
16375 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16376 (parallel [(set (match_dup 4)
16377 (unspec:XF [(match_dup 2)
16378 (match_dup 3)] UNSPEC_FYL2X))
16379 (clobber (match_scratch:XF 5 ""))])
16380 (set (match_operand:SF 0 "register_operand" "")
16381 (float_truncate:SF (match_dup 4)))]
16382 "TARGET_USE_FANCY_MATH_387
16383 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16384 && flag_unsafe_math_optimizations"
16388 operands[2] = gen_reg_rtx (XFmode);
16389 operands[3] = gen_reg_rtx (XFmode);
16390 operands[4] = gen_reg_rtx (XFmode);
16392 temp = standard_80387_constant_rtx (4); /* fldln2 */
16393 emit_move_insn (operands[3], temp);
16396 (define_expand "logdf2"
16397 [(set (match_dup 2)
16398 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16399 (parallel [(set (match_dup 4)
16400 (unspec:XF [(match_dup 2)
16401 (match_dup 3)] UNSPEC_FYL2X))
16402 (clobber (match_scratch:XF 5 ""))])
16403 (set (match_operand:DF 0 "register_operand" "")
16404 (float_truncate:DF (match_dup 4)))]
16405 "TARGET_USE_FANCY_MATH_387
16406 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16407 && flag_unsafe_math_optimizations"
16411 operands[2] = gen_reg_rtx (XFmode);
16412 operands[3] = gen_reg_rtx (XFmode);
16413 operands[4] = gen_reg_rtx (XFmode);
16415 temp = standard_80387_constant_rtx (4); /* fldln2 */
16416 emit_move_insn (operands[3], temp);
16419 (define_expand "logxf2"
16420 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16421 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16422 (match_dup 2)] UNSPEC_FYL2X))
16423 (clobber (match_scratch:XF 3 ""))])]
16424 "TARGET_USE_FANCY_MATH_387
16425 && flag_unsafe_math_optimizations"
16429 operands[2] = gen_reg_rtx (XFmode);
16430 temp = standard_80387_constant_rtx (4); /* fldln2 */
16431 emit_move_insn (operands[2], temp);
16434 (define_expand "log10sf2"
16435 [(set (match_dup 2)
16436 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16437 (parallel [(set (match_dup 4)
16438 (unspec:XF [(match_dup 2)
16439 (match_dup 3)] UNSPEC_FYL2X))
16440 (clobber (match_scratch:XF 5 ""))])
16441 (set (match_operand:SF 0 "register_operand" "")
16442 (float_truncate:SF (match_dup 4)))]
16443 "TARGET_USE_FANCY_MATH_387
16444 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16445 && flag_unsafe_math_optimizations"
16449 operands[2] = gen_reg_rtx (XFmode);
16450 operands[3] = gen_reg_rtx (XFmode);
16451 operands[4] = gen_reg_rtx (XFmode);
16453 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16454 emit_move_insn (operands[3], temp);
16457 (define_expand "log10df2"
16458 [(set (match_dup 2)
16459 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16460 (parallel [(set (match_dup 4)
16461 (unspec:XF [(match_dup 2)
16462 (match_dup 3)] UNSPEC_FYL2X))
16463 (clobber (match_scratch:XF 5 ""))])
16464 (set (match_operand:DF 0 "register_operand" "")
16465 (float_truncate:DF (match_dup 4)))]
16466 "TARGET_USE_FANCY_MATH_387
16467 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16468 && flag_unsafe_math_optimizations"
16472 operands[2] = gen_reg_rtx (XFmode);
16473 operands[3] = gen_reg_rtx (XFmode);
16474 operands[4] = gen_reg_rtx (XFmode);
16476 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16477 emit_move_insn (operands[3], temp);
16480 (define_expand "log10xf2"
16481 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16482 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16483 (match_dup 2)] UNSPEC_FYL2X))
16484 (clobber (match_scratch:XF 3 ""))])]
16485 "TARGET_USE_FANCY_MATH_387
16486 && flag_unsafe_math_optimizations"
16490 operands[2] = gen_reg_rtx (XFmode);
16491 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16492 emit_move_insn (operands[2], temp);
16495 (define_expand "log2sf2"
16496 [(set (match_dup 2)
16497 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16498 (parallel [(set (match_dup 4)
16499 (unspec:XF [(match_dup 2)
16500 (match_dup 3)] UNSPEC_FYL2X))
16501 (clobber (match_scratch:XF 5 ""))])
16502 (set (match_operand:SF 0 "register_operand" "")
16503 (float_truncate:SF (match_dup 4)))]
16504 "TARGET_USE_FANCY_MATH_387
16505 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16506 && flag_unsafe_math_optimizations"
16508 operands[2] = gen_reg_rtx (XFmode);
16509 operands[3] = gen_reg_rtx (XFmode);
16510 operands[4] = gen_reg_rtx (XFmode);
16512 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16515 (define_expand "log2df2"
16516 [(set (match_dup 2)
16517 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16518 (parallel [(set (match_dup 4)
16519 (unspec:XF [(match_dup 2)
16520 (match_dup 3)] UNSPEC_FYL2X))
16521 (clobber (match_scratch:XF 5 ""))])
16522 (set (match_operand:DF 0 "register_operand" "")
16523 (float_truncate:DF (match_dup 4)))]
16524 "TARGET_USE_FANCY_MATH_387
16525 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16526 && flag_unsafe_math_optimizations"
16528 operands[2] = gen_reg_rtx (XFmode);
16529 operands[3] = gen_reg_rtx (XFmode);
16530 operands[4] = gen_reg_rtx (XFmode);
16532 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16535 (define_expand "log2xf2"
16536 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16537 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16538 (match_dup 2)] UNSPEC_FYL2X))
16539 (clobber (match_scratch:XF 3 ""))])]
16540 "TARGET_USE_FANCY_MATH_387
16541 && flag_unsafe_math_optimizations"
16543 operands[2] = gen_reg_rtx (XFmode);
16544 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16547 (define_insn "fyl2xp1_xf3"
16548 [(set (match_operand:XF 0 "register_operand" "=f")
16549 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16550 (match_operand:XF 1 "register_operand" "u")]
16552 (clobber (match_scratch:XF 3 "=1"))]
16553 "TARGET_USE_FANCY_MATH_387
16554 && flag_unsafe_math_optimizations"
16556 [(set_attr "type" "fpspc")
16557 (set_attr "mode" "XF")])
16559 (define_expand "log1psf2"
16560 [(use (match_operand:SF 0 "register_operand" ""))
16561 (use (match_operand:SF 1 "register_operand" ""))]
16562 "TARGET_USE_FANCY_MATH_387
16563 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16564 && flag_unsafe_math_optimizations && !optimize_size"
16566 rtx op0 = gen_reg_rtx (XFmode);
16567 rtx op1 = gen_reg_rtx (XFmode);
16569 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16570 ix86_emit_i387_log1p (op0, op1);
16571 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16575 (define_expand "log1pdf2"
16576 [(use (match_operand:DF 0 "register_operand" ""))
16577 (use (match_operand:DF 1 "register_operand" ""))]
16578 "TARGET_USE_FANCY_MATH_387
16579 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16580 && flag_unsafe_math_optimizations && !optimize_size"
16582 rtx op0 = gen_reg_rtx (XFmode);
16583 rtx op1 = gen_reg_rtx (XFmode);
16585 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16586 ix86_emit_i387_log1p (op0, op1);
16587 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16591 (define_expand "log1pxf2"
16592 [(use (match_operand:XF 0 "register_operand" ""))
16593 (use (match_operand:XF 1 "register_operand" ""))]
16594 "TARGET_USE_FANCY_MATH_387
16595 && flag_unsafe_math_optimizations && !optimize_size"
16597 ix86_emit_i387_log1p (operands[0], operands[1]);
16601 (define_insn "*fxtractxf3"
16602 [(set (match_operand:XF 0 "register_operand" "=f")
16603 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16604 UNSPEC_XTRACT_FRACT))
16605 (set (match_operand:XF 1 "register_operand" "=u")
16606 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16607 "TARGET_USE_FANCY_MATH_387
16608 && flag_unsafe_math_optimizations"
16610 [(set_attr "type" "fpspc")
16611 (set_attr "mode" "XF")])
16613 (define_expand "logbsf2"
16614 [(set (match_dup 2)
16615 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16616 (parallel [(set (match_dup 3)
16617 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16619 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16620 (set (match_operand:SF 0 "register_operand" "")
16621 (float_truncate:SF (match_dup 4)))]
16622 "TARGET_USE_FANCY_MATH_387
16623 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16624 && flag_unsafe_math_optimizations"
16626 operands[2] = gen_reg_rtx (XFmode);
16627 operands[3] = gen_reg_rtx (XFmode);
16628 operands[4] = gen_reg_rtx (XFmode);
16631 (define_expand "logbdf2"
16632 [(set (match_dup 2)
16633 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16634 (parallel [(set (match_dup 3)
16635 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16637 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16638 (set (match_operand:DF 0 "register_operand" "")
16639 (float_truncate:DF (match_dup 4)))]
16640 "TARGET_USE_FANCY_MATH_387
16641 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16642 && flag_unsafe_math_optimizations"
16644 operands[2] = gen_reg_rtx (XFmode);
16645 operands[3] = gen_reg_rtx (XFmode);
16646 operands[4] = gen_reg_rtx (XFmode);
16649 (define_expand "logbxf2"
16650 [(parallel [(set (match_dup 2)
16651 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16652 UNSPEC_XTRACT_FRACT))
16653 (set (match_operand:XF 0 "register_operand" "")
16654 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16655 "TARGET_USE_FANCY_MATH_387
16656 && flag_unsafe_math_optimizations"
16658 operands[2] = gen_reg_rtx (XFmode);
16661 (define_expand "ilogbsi2"
16662 [(parallel [(set (match_dup 2)
16663 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16664 UNSPEC_XTRACT_FRACT))
16665 (set (match_operand:XF 3 "register_operand" "")
16666 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16667 (parallel [(set (match_operand:SI 0 "register_operand" "")
16668 (fix:SI (match_dup 3)))
16669 (clobber (reg:CC FLAGS_REG))])]
16670 "TARGET_USE_FANCY_MATH_387
16671 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16672 && flag_unsafe_math_optimizations && !optimize_size"
16674 operands[2] = gen_reg_rtx (XFmode);
16675 operands[3] = gen_reg_rtx (XFmode);
16678 (define_insn "*f2xm1xf2"
16679 [(set (match_operand:XF 0 "register_operand" "=f")
16680 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16682 "TARGET_USE_FANCY_MATH_387
16683 && flag_unsafe_math_optimizations"
16685 [(set_attr "type" "fpspc")
16686 (set_attr "mode" "XF")])
16688 (define_insn "*fscalexf4"
16689 [(set (match_operand:XF 0 "register_operand" "=f")
16690 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16691 (match_operand:XF 3 "register_operand" "1")]
16692 UNSPEC_FSCALE_FRACT))
16693 (set (match_operand:XF 1 "register_operand" "=u")
16694 (unspec:XF [(match_dup 2) (match_dup 3)]
16695 UNSPEC_FSCALE_EXP))]
16696 "TARGET_USE_FANCY_MATH_387
16697 && flag_unsafe_math_optimizations"
16699 [(set_attr "type" "fpspc")
16700 (set_attr "mode" "XF")])
16702 (define_expand "expsf2"
16703 [(set (match_dup 2)
16704 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16705 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16706 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16707 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16708 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16709 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16710 (parallel [(set (match_dup 10)
16711 (unspec:XF [(match_dup 9) (match_dup 5)]
16712 UNSPEC_FSCALE_FRACT))
16713 (set (match_dup 11)
16714 (unspec:XF [(match_dup 9) (match_dup 5)]
16715 UNSPEC_FSCALE_EXP))])
16716 (set (match_operand:SF 0 "register_operand" "")
16717 (float_truncate:SF (match_dup 10)))]
16718 "TARGET_USE_FANCY_MATH_387
16719 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16720 && flag_unsafe_math_optimizations && !optimize_size"
16725 for (i=2; i<12; i++)
16726 operands[i] = gen_reg_rtx (XFmode);
16727 temp = standard_80387_constant_rtx (5); /* fldl2e */
16728 emit_move_insn (operands[3], temp);
16729 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16732 (define_expand "expdf2"
16733 [(set (match_dup 2)
16734 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16735 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16736 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16737 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16738 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16739 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16740 (parallel [(set (match_dup 10)
16741 (unspec:XF [(match_dup 9) (match_dup 5)]
16742 UNSPEC_FSCALE_FRACT))
16743 (set (match_dup 11)
16744 (unspec:XF [(match_dup 9) (match_dup 5)]
16745 UNSPEC_FSCALE_EXP))])
16746 (set (match_operand:DF 0 "register_operand" "")
16747 (float_truncate:DF (match_dup 10)))]
16748 "TARGET_USE_FANCY_MATH_387
16749 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16750 && flag_unsafe_math_optimizations && !optimize_size"
16755 for (i=2; i<12; i++)
16756 operands[i] = gen_reg_rtx (XFmode);
16757 temp = standard_80387_constant_rtx (5); /* fldl2e */
16758 emit_move_insn (operands[3], temp);
16759 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16762 (define_expand "expxf2"
16763 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16765 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16766 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16767 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16768 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16769 (parallel [(set (match_operand:XF 0 "register_operand" "")
16770 (unspec:XF [(match_dup 8) (match_dup 4)]
16771 UNSPEC_FSCALE_FRACT))
16773 (unspec:XF [(match_dup 8) (match_dup 4)]
16774 UNSPEC_FSCALE_EXP))])]
16775 "TARGET_USE_FANCY_MATH_387
16776 && flag_unsafe_math_optimizations && !optimize_size"
16781 for (i=2; i<10; i++)
16782 operands[i] = gen_reg_rtx (XFmode);
16783 temp = standard_80387_constant_rtx (5); /* fldl2e */
16784 emit_move_insn (operands[2], temp);
16785 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16788 (define_expand "exp10sf2"
16789 [(set (match_dup 2)
16790 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16791 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16792 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16793 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16794 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16795 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16796 (parallel [(set (match_dup 10)
16797 (unspec:XF [(match_dup 9) (match_dup 5)]
16798 UNSPEC_FSCALE_FRACT))
16799 (set (match_dup 11)
16800 (unspec:XF [(match_dup 9) (match_dup 5)]
16801 UNSPEC_FSCALE_EXP))])
16802 (set (match_operand:SF 0 "register_operand" "")
16803 (float_truncate:SF (match_dup 10)))]
16804 "TARGET_USE_FANCY_MATH_387
16805 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16806 && flag_unsafe_math_optimizations && !optimize_size"
16811 for (i=2; i<12; i++)
16812 operands[i] = gen_reg_rtx (XFmode);
16813 temp = standard_80387_constant_rtx (6); /* fldl2t */
16814 emit_move_insn (operands[3], temp);
16815 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16818 (define_expand "exp10df2"
16819 [(set (match_dup 2)
16820 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16821 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16822 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16823 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16824 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16825 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16826 (parallel [(set (match_dup 10)
16827 (unspec:XF [(match_dup 9) (match_dup 5)]
16828 UNSPEC_FSCALE_FRACT))
16829 (set (match_dup 11)
16830 (unspec:XF [(match_dup 9) (match_dup 5)]
16831 UNSPEC_FSCALE_EXP))])
16832 (set (match_operand:DF 0 "register_operand" "")
16833 (float_truncate:DF (match_dup 10)))]
16834 "TARGET_USE_FANCY_MATH_387
16835 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16836 && flag_unsafe_math_optimizations && !optimize_size"
16841 for (i=2; i<12; i++)
16842 operands[i] = gen_reg_rtx (XFmode);
16843 temp = standard_80387_constant_rtx (6); /* fldl2t */
16844 emit_move_insn (operands[3], temp);
16845 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16848 (define_expand "exp10xf2"
16849 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16851 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16852 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16853 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16854 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16855 (parallel [(set (match_operand:XF 0 "register_operand" "")
16856 (unspec:XF [(match_dup 8) (match_dup 4)]
16857 UNSPEC_FSCALE_FRACT))
16859 (unspec:XF [(match_dup 8) (match_dup 4)]
16860 UNSPEC_FSCALE_EXP))])]
16861 "TARGET_USE_FANCY_MATH_387
16862 && flag_unsafe_math_optimizations && !optimize_size"
16867 for (i=2; i<10; i++)
16868 operands[i] = gen_reg_rtx (XFmode);
16869 temp = standard_80387_constant_rtx (6); /* fldl2t */
16870 emit_move_insn (operands[2], temp);
16871 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16874 (define_expand "exp2sf2"
16875 [(set (match_dup 2)
16876 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16877 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16878 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16879 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16880 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16881 (parallel [(set (match_dup 8)
16882 (unspec:XF [(match_dup 7) (match_dup 3)]
16883 UNSPEC_FSCALE_FRACT))
16885 (unspec:XF [(match_dup 7) (match_dup 3)]
16886 UNSPEC_FSCALE_EXP))])
16887 (set (match_operand:SF 0 "register_operand" "")
16888 (float_truncate:SF (match_dup 8)))]
16889 "TARGET_USE_FANCY_MATH_387
16890 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16891 && flag_unsafe_math_optimizations && !optimize_size"
16895 for (i=2; i<10; i++)
16896 operands[i] = gen_reg_rtx (XFmode);
16897 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16900 (define_expand "exp2df2"
16901 [(set (match_dup 2)
16902 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16903 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16904 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16905 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16906 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16907 (parallel [(set (match_dup 8)
16908 (unspec:XF [(match_dup 7) (match_dup 3)]
16909 UNSPEC_FSCALE_FRACT))
16911 (unspec:XF [(match_dup 7) (match_dup 3)]
16912 UNSPEC_FSCALE_EXP))])
16913 (set (match_operand:DF 0 "register_operand" "")
16914 (float_truncate:DF (match_dup 8)))]
16915 "TARGET_USE_FANCY_MATH_387
16916 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16917 && flag_unsafe_math_optimizations && !optimize_size"
16921 for (i=2; i<10; i++)
16922 operands[i] = gen_reg_rtx (XFmode);
16923 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16926 (define_expand "exp2xf2"
16927 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16928 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16929 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16930 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16931 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16932 (parallel [(set (match_operand:XF 0 "register_operand" "")
16933 (unspec:XF [(match_dup 7) (match_dup 3)]
16934 UNSPEC_FSCALE_FRACT))
16936 (unspec:XF [(match_dup 7) (match_dup 3)]
16937 UNSPEC_FSCALE_EXP))])]
16938 "TARGET_USE_FANCY_MATH_387
16939 && flag_unsafe_math_optimizations && !optimize_size"
16943 for (i=2; i<9; i++)
16944 operands[i] = gen_reg_rtx (XFmode);
16945 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16948 (define_expand "expm1df2"
16949 [(set (match_dup 2)
16950 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16951 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16952 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16953 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16954 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16955 (parallel [(set (match_dup 8)
16956 (unspec:XF [(match_dup 7) (match_dup 5)]
16957 UNSPEC_FSCALE_FRACT))
16959 (unspec:XF [(match_dup 7) (match_dup 5)]
16960 UNSPEC_FSCALE_EXP))])
16961 (parallel [(set (match_dup 11)
16962 (unspec:XF [(match_dup 10) (match_dup 9)]
16963 UNSPEC_FSCALE_FRACT))
16964 (set (match_dup 12)
16965 (unspec:XF [(match_dup 10) (match_dup 9)]
16966 UNSPEC_FSCALE_EXP))])
16967 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16968 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16969 (set (match_operand:DF 0 "register_operand" "")
16970 (float_truncate:DF (match_dup 14)))]
16971 "TARGET_USE_FANCY_MATH_387
16972 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16973 && flag_unsafe_math_optimizations && !optimize_size"
16978 for (i=2; i<15; i++)
16979 operands[i] = gen_reg_rtx (XFmode);
16980 temp = standard_80387_constant_rtx (5); /* fldl2e */
16981 emit_move_insn (operands[3], temp);
16982 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16985 (define_expand "expm1sf2"
16986 [(set (match_dup 2)
16987 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16988 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16989 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16990 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16991 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16992 (parallel [(set (match_dup 8)
16993 (unspec:XF [(match_dup 7) (match_dup 5)]
16994 UNSPEC_FSCALE_FRACT))
16996 (unspec:XF [(match_dup 7) (match_dup 5)]
16997 UNSPEC_FSCALE_EXP))])
16998 (parallel [(set (match_dup 11)
16999 (unspec:XF [(match_dup 10) (match_dup 9)]
17000 UNSPEC_FSCALE_FRACT))
17001 (set (match_dup 12)
17002 (unspec:XF [(match_dup 10) (match_dup 9)]
17003 UNSPEC_FSCALE_EXP))])
17004 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17005 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17006 (set (match_operand:SF 0 "register_operand" "")
17007 (float_truncate:SF (match_dup 14)))]
17008 "TARGET_USE_FANCY_MATH_387
17009 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17010 && flag_unsafe_math_optimizations && !optimize_size"
17015 for (i=2; i<15; i++)
17016 operands[i] = gen_reg_rtx (XFmode);
17017 temp = standard_80387_constant_rtx (5); /* fldl2e */
17018 emit_move_insn (operands[3], temp);
17019 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17022 (define_expand "expm1xf2"
17023 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17025 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17026 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17027 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17028 (parallel [(set (match_dup 7)
17029 (unspec:XF [(match_dup 6) (match_dup 4)]
17030 UNSPEC_FSCALE_FRACT))
17032 (unspec:XF [(match_dup 6) (match_dup 4)]
17033 UNSPEC_FSCALE_EXP))])
17034 (parallel [(set (match_dup 10)
17035 (unspec:XF [(match_dup 9) (match_dup 8)]
17036 UNSPEC_FSCALE_FRACT))
17037 (set (match_dup 11)
17038 (unspec:XF [(match_dup 9) (match_dup 8)]
17039 UNSPEC_FSCALE_EXP))])
17040 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17041 (set (match_operand:XF 0 "register_operand" "")
17042 (plus:XF (match_dup 12) (match_dup 7)))]
17043 "TARGET_USE_FANCY_MATH_387
17044 && flag_unsafe_math_optimizations && !optimize_size"
17049 for (i=2; i<13; i++)
17050 operands[i] = gen_reg_rtx (XFmode);
17051 temp = standard_80387_constant_rtx (5); /* fldl2e */
17052 emit_move_insn (operands[2], temp);
17053 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17056 (define_expand "ldexpdf3"
17057 [(set (match_dup 3)
17058 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17060 (float:XF (match_operand:SI 2 "register_operand" "")))
17061 (parallel [(set (match_dup 5)
17062 (unspec:XF [(match_dup 3) (match_dup 4)]
17063 UNSPEC_FSCALE_FRACT))
17065 (unspec:XF [(match_dup 3) (match_dup 4)]
17066 UNSPEC_FSCALE_EXP))])
17067 (set (match_operand:DF 0 "register_operand" "")
17068 (float_truncate:DF (match_dup 5)))]
17069 "TARGET_USE_FANCY_MATH_387
17070 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17071 && flag_unsafe_math_optimizations && !optimize_size"
17075 for (i=3; i<7; i++)
17076 operands[i] = gen_reg_rtx (XFmode);
17079 (define_expand "ldexpsf3"
17080 [(set (match_dup 3)
17081 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17083 (float:XF (match_operand:SI 2 "register_operand" "")))
17084 (parallel [(set (match_dup 5)
17085 (unspec:XF [(match_dup 3) (match_dup 4)]
17086 UNSPEC_FSCALE_FRACT))
17088 (unspec:XF [(match_dup 3) (match_dup 4)]
17089 UNSPEC_FSCALE_EXP))])
17090 (set (match_operand:SF 0 "register_operand" "")
17091 (float_truncate:SF (match_dup 5)))]
17092 "TARGET_USE_FANCY_MATH_387
17093 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17094 && flag_unsafe_math_optimizations && !optimize_size"
17098 for (i=3; i<7; i++)
17099 operands[i] = gen_reg_rtx (XFmode);
17102 (define_expand "ldexpxf3"
17103 [(set (match_dup 3)
17104 (float:XF (match_operand:SI 2 "register_operand" "")))
17105 (parallel [(set (match_operand:XF 0 " register_operand" "")
17106 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17108 UNSPEC_FSCALE_FRACT))
17110 (unspec:XF [(match_dup 1) (match_dup 3)]
17111 UNSPEC_FSCALE_EXP))])]
17112 "TARGET_USE_FANCY_MATH_387
17113 && flag_unsafe_math_optimizations && !optimize_size"
17117 for (i=3; i<5; i++)
17118 operands[i] = gen_reg_rtx (XFmode);
17122 (define_insn "frndintxf2"
17123 [(set (match_operand:XF 0 "register_operand" "=f")
17124 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17126 "TARGET_USE_FANCY_MATH_387
17127 && flag_unsafe_math_optimizations"
17129 [(set_attr "type" "fpspc")
17130 (set_attr "mode" "XF")])
17132 (define_expand "rintdf2"
17133 [(use (match_operand:DF 0 "register_operand" ""))
17134 (use (match_operand:DF 1 "register_operand" ""))]
17135 "(TARGET_USE_FANCY_MATH_387
17136 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17137 && flag_unsafe_math_optimizations)
17138 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17139 && !flag_trapping_math
17140 && !optimize_size)"
17142 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17143 && !flag_trapping_math
17145 ix86_expand_rint (operand0, operand1);
17148 rtx op0 = gen_reg_rtx (XFmode);
17149 rtx op1 = gen_reg_rtx (XFmode);
17151 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17152 emit_insn (gen_frndintxf2 (op0, op1));
17154 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17159 (define_expand "rintsf2"
17160 [(use (match_operand:SF 0 "register_operand" ""))
17161 (use (match_operand:SF 1 "register_operand" ""))]
17162 "(TARGET_USE_FANCY_MATH_387
17163 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17164 && flag_unsafe_math_optimizations)
17165 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17166 && !flag_trapping_math
17167 && !optimize_size)"
17169 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17170 && !flag_trapping_math
17172 ix86_expand_rint (operand0, operand1);
17175 rtx op0 = gen_reg_rtx (XFmode);
17176 rtx op1 = gen_reg_rtx (XFmode);
17178 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17179 emit_insn (gen_frndintxf2 (op0, op1));
17181 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17186 (define_expand "rintxf2"
17187 [(use (match_operand:XF 0 "register_operand" ""))
17188 (use (match_operand:XF 1 "register_operand" ""))]
17189 "TARGET_USE_FANCY_MATH_387
17190 && flag_unsafe_math_optimizations && !optimize_size"
17192 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17196 (define_expand "roundsf2"
17197 [(match_operand:SF 0 "register_operand" "")
17198 (match_operand:SF 1 "nonimmediate_operand" "")]
17199 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17200 && !flag_trapping_math && !flag_rounding_math
17203 ix86_expand_round (operand0, operand1);
17207 (define_expand "rounddf2"
17208 [(match_operand:DF 0 "register_operand" "")
17209 (match_operand:DF 1 "nonimmediate_operand" "")]
17210 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17211 && !flag_trapping_math && !flag_rounding_math
17215 ix86_expand_round (operand0, operand1);
17217 ix86_expand_rounddf_32 (operand0, operand1);
17221 (define_insn_and_split "*fistdi2_1"
17222 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17223 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17225 "TARGET_USE_FANCY_MATH_387
17226 && !(reload_completed || reload_in_progress)"
17231 if (memory_operand (operands[0], VOIDmode))
17232 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17235 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17236 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17241 [(set_attr "type" "fpspc")
17242 (set_attr "mode" "DI")])
17244 (define_insn "fistdi2"
17245 [(set (match_operand:DI 0 "memory_operand" "=m")
17246 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17248 (clobber (match_scratch:XF 2 "=&1f"))]
17249 "TARGET_USE_FANCY_MATH_387"
17250 "* return output_fix_trunc (insn, operands, 0);"
17251 [(set_attr "type" "fpspc")
17252 (set_attr "mode" "DI")])
17254 (define_insn "fistdi2_with_temp"
17255 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17256 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17258 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17259 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17260 "TARGET_USE_FANCY_MATH_387"
17262 [(set_attr "type" "fpspc")
17263 (set_attr "mode" "DI")])
17266 [(set (match_operand:DI 0 "register_operand" "")
17267 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17269 (clobber (match_operand:DI 2 "memory_operand" ""))
17270 (clobber (match_scratch 3 ""))]
17272 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17273 (clobber (match_dup 3))])
17274 (set (match_dup 0) (match_dup 2))]
17278 [(set (match_operand:DI 0 "memory_operand" "")
17279 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17281 (clobber (match_operand:DI 2 "memory_operand" ""))
17282 (clobber (match_scratch 3 ""))]
17284 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17285 (clobber (match_dup 3))])]
17288 (define_insn_and_split "*fist<mode>2_1"
17289 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17290 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17292 "TARGET_USE_FANCY_MATH_387
17293 && !(reload_completed || reload_in_progress)"
17298 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17299 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17303 [(set_attr "type" "fpspc")
17304 (set_attr "mode" "<MODE>")])
17306 (define_insn "fist<mode>2"
17307 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17308 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17310 "TARGET_USE_FANCY_MATH_387"
17311 "* return output_fix_trunc (insn, operands, 0);"
17312 [(set_attr "type" "fpspc")
17313 (set_attr "mode" "<MODE>")])
17315 (define_insn "fist<mode>2_with_temp"
17316 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17317 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17319 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17320 "TARGET_USE_FANCY_MATH_387"
17322 [(set_attr "type" "fpspc")
17323 (set_attr "mode" "<MODE>")])
17326 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17327 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17329 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17331 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17333 (set (match_dup 0) (match_dup 2))]
17337 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17338 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17340 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17342 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17346 (define_expand "lrintxf<mode>2"
17347 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17348 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17350 "TARGET_USE_FANCY_MATH_387"
17353 (define_expand "lrint<mode>di2"
17354 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17355 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17356 UNSPEC_FIX_NOTRUNC))]
17357 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17360 (define_expand "lrint<mode>si2"
17361 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17362 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17363 UNSPEC_FIX_NOTRUNC))]
17364 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17367 (define_expand "lround<mode>di2"
17368 [(match_operand:DI 0 "nonimmediate_operand" "")
17369 (match_operand:SSEMODEF 1 "register_operand" "")]
17370 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17371 && !flag_trapping_math && !flag_rounding_math
17374 ix86_expand_lround (operand0, operand1);
17378 (define_expand "lround<mode>si2"
17379 [(match_operand:SI 0 "nonimmediate_operand" "")
17380 (match_operand:SSEMODEF 1 "register_operand" "")]
17381 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17382 && !flag_trapping_math && !flag_rounding_math
17385 ix86_expand_lround (operand0, operand1);
17389 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17390 (define_insn_and_split "frndintxf2_floor"
17391 [(set (match_operand:XF 0 "register_operand" "=f")
17392 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17393 UNSPEC_FRNDINT_FLOOR))
17394 (clobber (reg:CC FLAGS_REG))]
17395 "TARGET_USE_FANCY_MATH_387
17396 && flag_unsafe_math_optimizations
17397 && !(reload_completed || reload_in_progress)"
17402 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17404 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17405 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17407 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17408 operands[2], operands[3]));
17411 [(set_attr "type" "frndint")
17412 (set_attr "i387_cw" "floor")
17413 (set_attr "mode" "XF")])
17415 (define_insn "frndintxf2_floor_i387"
17416 [(set (match_operand:XF 0 "register_operand" "=f")
17417 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17418 UNSPEC_FRNDINT_FLOOR))
17419 (use (match_operand:HI 2 "memory_operand" "m"))
17420 (use (match_operand:HI 3 "memory_operand" "m"))]
17421 "TARGET_USE_FANCY_MATH_387
17422 && flag_unsafe_math_optimizations"
17423 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17424 [(set_attr "type" "frndint")
17425 (set_attr "i387_cw" "floor")
17426 (set_attr "mode" "XF")])
17428 (define_expand "floorxf2"
17429 [(use (match_operand:XF 0 "register_operand" ""))
17430 (use (match_operand:XF 1 "register_operand" ""))]
17431 "TARGET_USE_FANCY_MATH_387
17432 && flag_unsafe_math_optimizations && !optimize_size"
17434 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17438 (define_expand "floordf2"
17439 [(use (match_operand:DF 0 "register_operand" ""))
17440 (use (match_operand:DF 1 "register_operand" ""))]
17441 "((TARGET_USE_FANCY_MATH_387
17442 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17443 && flag_unsafe_math_optimizations)
17444 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17445 && !flag_trapping_math))
17448 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17449 && !flag_trapping_math)
17452 ix86_expand_floorceil (operand0, operand1, true);
17454 ix86_expand_floorceildf_32 (operand0, operand1, true);
17458 rtx op0 = gen_reg_rtx (XFmode);
17459 rtx op1 = gen_reg_rtx (XFmode);
17461 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17462 emit_insn (gen_frndintxf2_floor (op0, op1));
17464 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17469 (define_expand "floorsf2"
17470 [(use (match_operand:SF 0 "register_operand" ""))
17471 (use (match_operand:SF 1 "register_operand" ""))]
17472 "((TARGET_USE_FANCY_MATH_387
17473 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17474 && flag_unsafe_math_optimizations)
17475 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17476 && !flag_trapping_math))
17479 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17480 && !flag_trapping_math)
17481 ix86_expand_floorceil (operand0, operand1, true);
17484 rtx op0 = gen_reg_rtx (XFmode);
17485 rtx op1 = gen_reg_rtx (XFmode);
17487 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17488 emit_insn (gen_frndintxf2_floor (op0, op1));
17490 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17495 (define_insn_and_split "*fist<mode>2_floor_1"
17496 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17497 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17498 UNSPEC_FIST_FLOOR))
17499 (clobber (reg:CC FLAGS_REG))]
17500 "TARGET_USE_FANCY_MATH_387
17501 && flag_unsafe_math_optimizations
17502 && !(reload_completed || reload_in_progress)"
17507 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17509 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17510 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17511 if (memory_operand (operands[0], VOIDmode))
17512 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17513 operands[2], operands[3]));
17516 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17517 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17518 operands[2], operands[3],
17523 [(set_attr "type" "fistp")
17524 (set_attr "i387_cw" "floor")
17525 (set_attr "mode" "<MODE>")])
17527 (define_insn "fistdi2_floor"
17528 [(set (match_operand:DI 0 "memory_operand" "=m")
17529 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17530 UNSPEC_FIST_FLOOR))
17531 (use (match_operand:HI 2 "memory_operand" "m"))
17532 (use (match_operand:HI 3 "memory_operand" "m"))
17533 (clobber (match_scratch:XF 4 "=&1f"))]
17534 "TARGET_USE_FANCY_MATH_387
17535 && flag_unsafe_math_optimizations"
17536 "* return output_fix_trunc (insn, operands, 0);"
17537 [(set_attr "type" "fistp")
17538 (set_attr "i387_cw" "floor")
17539 (set_attr "mode" "DI")])
17541 (define_insn "fistdi2_floor_with_temp"
17542 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17543 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17544 UNSPEC_FIST_FLOOR))
17545 (use (match_operand:HI 2 "memory_operand" "m,m"))
17546 (use (match_operand:HI 3 "memory_operand" "m,m"))
17547 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17548 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17549 "TARGET_USE_FANCY_MATH_387
17550 && flag_unsafe_math_optimizations"
17552 [(set_attr "type" "fistp")
17553 (set_attr "i387_cw" "floor")
17554 (set_attr "mode" "DI")])
17557 [(set (match_operand:DI 0 "register_operand" "")
17558 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17559 UNSPEC_FIST_FLOOR))
17560 (use (match_operand:HI 2 "memory_operand" ""))
17561 (use (match_operand:HI 3 "memory_operand" ""))
17562 (clobber (match_operand:DI 4 "memory_operand" ""))
17563 (clobber (match_scratch 5 ""))]
17565 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17566 (use (match_dup 2))
17567 (use (match_dup 3))
17568 (clobber (match_dup 5))])
17569 (set (match_dup 0) (match_dup 4))]
17573 [(set (match_operand:DI 0 "memory_operand" "")
17574 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17575 UNSPEC_FIST_FLOOR))
17576 (use (match_operand:HI 2 "memory_operand" ""))
17577 (use (match_operand:HI 3 "memory_operand" ""))
17578 (clobber (match_operand:DI 4 "memory_operand" ""))
17579 (clobber (match_scratch 5 ""))]
17581 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17582 (use (match_dup 2))
17583 (use (match_dup 3))
17584 (clobber (match_dup 5))])]
17587 (define_insn "fist<mode>2_floor"
17588 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17589 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17590 UNSPEC_FIST_FLOOR))
17591 (use (match_operand:HI 2 "memory_operand" "m"))
17592 (use (match_operand:HI 3 "memory_operand" "m"))]
17593 "TARGET_USE_FANCY_MATH_387
17594 && flag_unsafe_math_optimizations"
17595 "* return output_fix_trunc (insn, operands, 0);"
17596 [(set_attr "type" "fistp")
17597 (set_attr "i387_cw" "floor")
17598 (set_attr "mode" "<MODE>")])
17600 (define_insn "fist<mode>2_floor_with_temp"
17601 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17602 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17603 UNSPEC_FIST_FLOOR))
17604 (use (match_operand:HI 2 "memory_operand" "m,m"))
17605 (use (match_operand:HI 3 "memory_operand" "m,m"))
17606 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17607 "TARGET_USE_FANCY_MATH_387
17608 && flag_unsafe_math_optimizations"
17610 [(set_attr "type" "fistp")
17611 (set_attr "i387_cw" "floor")
17612 (set_attr "mode" "<MODE>")])
17615 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17616 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17617 UNSPEC_FIST_FLOOR))
17618 (use (match_operand:HI 2 "memory_operand" ""))
17619 (use (match_operand:HI 3 "memory_operand" ""))
17620 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17622 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17623 UNSPEC_FIST_FLOOR))
17624 (use (match_dup 2))
17625 (use (match_dup 3))])
17626 (set (match_dup 0) (match_dup 4))]
17630 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17631 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17632 UNSPEC_FIST_FLOOR))
17633 (use (match_operand:HI 2 "memory_operand" ""))
17634 (use (match_operand:HI 3 "memory_operand" ""))
17635 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17637 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17638 UNSPEC_FIST_FLOOR))
17639 (use (match_dup 2))
17640 (use (match_dup 3))])]
17643 (define_expand "lfloorxf<mode>2"
17644 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17645 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17646 UNSPEC_FIST_FLOOR))
17647 (clobber (reg:CC FLAGS_REG))])]
17648 "TARGET_USE_FANCY_MATH_387
17649 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17650 && flag_unsafe_math_optimizations"
17653 (define_expand "lfloor<mode>di2"
17654 [(match_operand:DI 0 "nonimmediate_operand" "")
17655 (match_operand:SSEMODEF 1 "register_operand" "")]
17656 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17657 && !flag_trapping_math
17660 ix86_expand_lfloorceil (operand0, operand1, true);
17664 (define_expand "lfloor<mode>si2"
17665 [(match_operand:SI 0 "nonimmediate_operand" "")
17666 (match_operand:SSEMODEF 1 "register_operand" "")]
17667 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17668 && !flag_trapping_math
17669 && (!optimize_size || !TARGET_64BIT)"
17671 ix86_expand_lfloorceil (operand0, operand1, true);
17675 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17676 (define_insn_and_split "frndintxf2_ceil"
17677 [(set (match_operand:XF 0 "register_operand" "=f")
17678 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17679 UNSPEC_FRNDINT_CEIL))
17680 (clobber (reg:CC FLAGS_REG))]
17681 "TARGET_USE_FANCY_MATH_387
17682 && flag_unsafe_math_optimizations
17683 && !(reload_completed || reload_in_progress)"
17688 ix86_optimize_mode_switching[I387_CEIL] = 1;
17690 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17691 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17693 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17694 operands[2], operands[3]));
17697 [(set_attr "type" "frndint")
17698 (set_attr "i387_cw" "ceil")
17699 (set_attr "mode" "XF")])
17701 (define_insn "frndintxf2_ceil_i387"
17702 [(set (match_operand:XF 0 "register_operand" "=f")
17703 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17704 UNSPEC_FRNDINT_CEIL))
17705 (use (match_operand:HI 2 "memory_operand" "m"))
17706 (use (match_operand:HI 3 "memory_operand" "m"))]
17707 "TARGET_USE_FANCY_MATH_387
17708 && flag_unsafe_math_optimizations"
17709 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17710 [(set_attr "type" "frndint")
17711 (set_attr "i387_cw" "ceil")
17712 (set_attr "mode" "XF")])
17714 (define_expand "ceilxf2"
17715 [(use (match_operand:XF 0 "register_operand" ""))
17716 (use (match_operand:XF 1 "register_operand" ""))]
17717 "TARGET_USE_FANCY_MATH_387
17718 && flag_unsafe_math_optimizations && !optimize_size"
17720 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17724 (define_expand "ceildf2"
17725 [(use (match_operand:DF 0 "register_operand" ""))
17726 (use (match_operand:DF 1 "register_operand" ""))]
17727 "((TARGET_USE_FANCY_MATH_387
17728 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17729 && flag_unsafe_math_optimizations)
17730 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17731 && !flag_trapping_math))
17734 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17735 && !flag_trapping_math)
17738 ix86_expand_floorceil (operand0, operand1, false);
17740 ix86_expand_floorceildf_32 (operand0, operand1, false);
17744 rtx op0 = gen_reg_rtx (XFmode);
17745 rtx op1 = gen_reg_rtx (XFmode);
17747 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17748 emit_insn (gen_frndintxf2_ceil (op0, op1));
17750 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17755 (define_expand "ceilsf2"
17756 [(use (match_operand:SF 0 "register_operand" ""))
17757 (use (match_operand:SF 1 "register_operand" ""))]
17758 "((TARGET_USE_FANCY_MATH_387
17759 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17760 && flag_unsafe_math_optimizations)
17761 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17762 && !flag_trapping_math))
17765 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17766 && !flag_trapping_math)
17767 ix86_expand_floorceil (operand0, operand1, false);
17770 rtx op0 = gen_reg_rtx (XFmode);
17771 rtx op1 = gen_reg_rtx (XFmode);
17773 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17774 emit_insn (gen_frndintxf2_ceil (op0, op1));
17776 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17781 (define_insn_and_split "*fist<mode>2_ceil_1"
17782 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17783 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17785 (clobber (reg:CC FLAGS_REG))]
17786 "TARGET_USE_FANCY_MATH_387
17787 && flag_unsafe_math_optimizations
17788 && !(reload_completed || reload_in_progress)"
17793 ix86_optimize_mode_switching[I387_CEIL] = 1;
17795 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17796 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17797 if (memory_operand (operands[0], VOIDmode))
17798 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17799 operands[2], operands[3]));
17802 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17803 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17804 operands[2], operands[3],
17809 [(set_attr "type" "fistp")
17810 (set_attr "i387_cw" "ceil")
17811 (set_attr "mode" "<MODE>")])
17813 (define_insn "fistdi2_ceil"
17814 [(set (match_operand:DI 0 "memory_operand" "=m")
17815 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17817 (use (match_operand:HI 2 "memory_operand" "m"))
17818 (use (match_operand:HI 3 "memory_operand" "m"))
17819 (clobber (match_scratch:XF 4 "=&1f"))]
17820 "TARGET_USE_FANCY_MATH_387
17821 && flag_unsafe_math_optimizations"
17822 "* return output_fix_trunc (insn, operands, 0);"
17823 [(set_attr "type" "fistp")
17824 (set_attr "i387_cw" "ceil")
17825 (set_attr "mode" "DI")])
17827 (define_insn "fistdi2_ceil_with_temp"
17828 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17829 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17831 (use (match_operand:HI 2 "memory_operand" "m,m"))
17832 (use (match_operand:HI 3 "memory_operand" "m,m"))
17833 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17834 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17835 "TARGET_USE_FANCY_MATH_387
17836 && flag_unsafe_math_optimizations"
17838 [(set_attr "type" "fistp")
17839 (set_attr "i387_cw" "ceil")
17840 (set_attr "mode" "DI")])
17843 [(set (match_operand:DI 0 "register_operand" "")
17844 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17846 (use (match_operand:HI 2 "memory_operand" ""))
17847 (use (match_operand:HI 3 "memory_operand" ""))
17848 (clobber (match_operand:DI 4 "memory_operand" ""))
17849 (clobber (match_scratch 5 ""))]
17851 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17852 (use (match_dup 2))
17853 (use (match_dup 3))
17854 (clobber (match_dup 5))])
17855 (set (match_dup 0) (match_dup 4))]
17859 [(set (match_operand:DI 0 "memory_operand" "")
17860 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17862 (use (match_operand:HI 2 "memory_operand" ""))
17863 (use (match_operand:HI 3 "memory_operand" ""))
17864 (clobber (match_operand:DI 4 "memory_operand" ""))
17865 (clobber (match_scratch 5 ""))]
17867 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17868 (use (match_dup 2))
17869 (use (match_dup 3))
17870 (clobber (match_dup 5))])]
17873 (define_insn "fist<mode>2_ceil"
17874 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17875 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17877 (use (match_operand:HI 2 "memory_operand" "m"))
17878 (use (match_operand:HI 3 "memory_operand" "m"))]
17879 "TARGET_USE_FANCY_MATH_387
17880 && flag_unsafe_math_optimizations"
17881 "* return output_fix_trunc (insn, operands, 0);"
17882 [(set_attr "type" "fistp")
17883 (set_attr "i387_cw" "ceil")
17884 (set_attr "mode" "<MODE>")])
17886 (define_insn "fist<mode>2_ceil_with_temp"
17887 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17888 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17890 (use (match_operand:HI 2 "memory_operand" "m,m"))
17891 (use (match_operand:HI 3 "memory_operand" "m,m"))
17892 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17893 "TARGET_USE_FANCY_MATH_387
17894 && flag_unsafe_math_optimizations"
17896 [(set_attr "type" "fistp")
17897 (set_attr "i387_cw" "ceil")
17898 (set_attr "mode" "<MODE>")])
17901 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17902 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17904 (use (match_operand:HI 2 "memory_operand" ""))
17905 (use (match_operand:HI 3 "memory_operand" ""))
17906 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17908 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17910 (use (match_dup 2))
17911 (use (match_dup 3))])
17912 (set (match_dup 0) (match_dup 4))]
17916 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17917 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17919 (use (match_operand:HI 2 "memory_operand" ""))
17920 (use (match_operand:HI 3 "memory_operand" ""))
17921 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17923 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17925 (use (match_dup 2))
17926 (use (match_dup 3))])]
17929 (define_expand "lceilxf<mode>2"
17930 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17931 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17933 (clobber (reg:CC FLAGS_REG))])]
17934 "TARGET_USE_FANCY_MATH_387
17935 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17936 && flag_unsafe_math_optimizations"
17939 (define_expand "lceil<mode>di2"
17940 [(match_operand:DI 0 "nonimmediate_operand" "")
17941 (match_operand:SSEMODEF 1 "register_operand" "")]
17942 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17943 && !flag_trapping_math"
17945 ix86_expand_lfloorceil (operand0, operand1, false);
17949 (define_expand "lceil<mode>si2"
17950 [(match_operand:SI 0 "nonimmediate_operand" "")
17951 (match_operand:SSEMODEF 1 "register_operand" "")]
17952 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17953 && !flag_trapping_math"
17955 ix86_expand_lfloorceil (operand0, operand1, false);
17959 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17960 (define_insn_and_split "frndintxf2_trunc"
17961 [(set (match_operand:XF 0 "register_operand" "=f")
17962 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17963 UNSPEC_FRNDINT_TRUNC))
17964 (clobber (reg:CC FLAGS_REG))]
17965 "TARGET_USE_FANCY_MATH_387
17966 && flag_unsafe_math_optimizations
17967 && !(reload_completed || reload_in_progress)"
17972 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17974 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17975 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17977 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17978 operands[2], operands[3]));
17981 [(set_attr "type" "frndint")
17982 (set_attr "i387_cw" "trunc")
17983 (set_attr "mode" "XF")])
17985 (define_insn "frndintxf2_trunc_i387"
17986 [(set (match_operand:XF 0 "register_operand" "=f")
17987 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17988 UNSPEC_FRNDINT_TRUNC))
17989 (use (match_operand:HI 2 "memory_operand" "m"))
17990 (use (match_operand:HI 3 "memory_operand" "m"))]
17991 "TARGET_USE_FANCY_MATH_387
17992 && flag_unsafe_math_optimizations"
17993 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17994 [(set_attr "type" "frndint")
17995 (set_attr "i387_cw" "trunc")
17996 (set_attr "mode" "XF")])
17998 (define_expand "btruncxf2"
17999 [(use (match_operand:XF 0 "register_operand" ""))
18000 (use (match_operand:XF 1 "register_operand" ""))]
18001 "TARGET_USE_FANCY_MATH_387
18002 && flag_unsafe_math_optimizations && !optimize_size"
18004 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18008 (define_expand "btruncdf2"
18009 [(use (match_operand:DF 0 "register_operand" ""))
18010 (use (match_operand:DF 1 "register_operand" ""))]
18011 "((TARGET_USE_FANCY_MATH_387
18012 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18013 && flag_unsafe_math_optimizations)
18014 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18015 && !flag_trapping_math))
18018 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18019 && !flag_trapping_math)
18022 ix86_expand_trunc (operand0, operand1);
18024 ix86_expand_truncdf_32 (operand0, operand1);
18028 rtx op0 = gen_reg_rtx (XFmode);
18029 rtx op1 = gen_reg_rtx (XFmode);
18031 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18032 emit_insn (gen_frndintxf2_trunc (op0, op1));
18034 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18039 (define_expand "btruncsf2"
18040 [(use (match_operand:SF 0 "register_operand" ""))
18041 (use (match_operand:SF 1 "register_operand" ""))]
18042 "((TARGET_USE_FANCY_MATH_387
18043 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18044 && flag_unsafe_math_optimizations)
18045 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18046 && !flag_trapping_math))
18049 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18050 && !flag_trapping_math)
18051 ix86_expand_trunc (operand0, operand1);
18054 rtx op0 = gen_reg_rtx (XFmode);
18055 rtx op1 = gen_reg_rtx (XFmode);
18057 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18058 emit_insn (gen_frndintxf2_trunc (op0, op1));
18060 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18065 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18066 (define_insn_and_split "frndintxf2_mask_pm"
18067 [(set (match_operand:XF 0 "register_operand" "=f")
18068 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18069 UNSPEC_FRNDINT_MASK_PM))
18070 (clobber (reg:CC FLAGS_REG))]
18071 "TARGET_USE_FANCY_MATH_387
18072 && flag_unsafe_math_optimizations
18073 && !(reload_completed || reload_in_progress)"
18078 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18080 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18081 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18083 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18084 operands[2], operands[3]));
18087 [(set_attr "type" "frndint")
18088 (set_attr "i387_cw" "mask_pm")
18089 (set_attr "mode" "XF")])
18091 (define_insn "frndintxf2_mask_pm_i387"
18092 [(set (match_operand:XF 0 "register_operand" "=f")
18093 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18094 UNSPEC_FRNDINT_MASK_PM))
18095 (use (match_operand:HI 2 "memory_operand" "m"))
18096 (use (match_operand:HI 3 "memory_operand" "m"))]
18097 "TARGET_USE_FANCY_MATH_387
18098 && flag_unsafe_math_optimizations"
18099 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18100 [(set_attr "type" "frndint")
18101 (set_attr "i387_cw" "mask_pm")
18102 (set_attr "mode" "XF")])
18104 (define_expand "nearbyintxf2"
18105 [(use (match_operand:XF 0 "register_operand" ""))
18106 (use (match_operand:XF 1 "register_operand" ""))]
18107 "TARGET_USE_FANCY_MATH_387
18108 && flag_unsafe_math_optimizations"
18110 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18115 (define_expand "nearbyintdf2"
18116 [(use (match_operand:DF 0 "register_operand" ""))
18117 (use (match_operand:DF 1 "register_operand" ""))]
18118 "TARGET_USE_FANCY_MATH_387
18119 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18120 && flag_unsafe_math_optimizations"
18122 rtx op0 = gen_reg_rtx (XFmode);
18123 rtx op1 = gen_reg_rtx (XFmode);
18125 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18126 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18128 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18132 (define_expand "nearbyintsf2"
18133 [(use (match_operand:SF 0 "register_operand" ""))
18134 (use (match_operand:SF 1 "register_operand" ""))]
18135 "TARGET_USE_FANCY_MATH_387
18136 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18137 && flag_unsafe_math_optimizations"
18139 rtx op0 = gen_reg_rtx (XFmode);
18140 rtx op1 = gen_reg_rtx (XFmode);
18142 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18143 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18145 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18150 ;; Block operation instructions
18153 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18156 [(set_attr "type" "cld")])
18158 (define_expand "movmemsi"
18159 [(use (match_operand:BLK 0 "memory_operand" ""))
18160 (use (match_operand:BLK 1 "memory_operand" ""))
18161 (use (match_operand:SI 2 "nonmemory_operand" ""))
18162 (use (match_operand:SI 3 "const_int_operand" ""))]
18163 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18165 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18171 (define_expand "movmemdi"
18172 [(use (match_operand:BLK 0 "memory_operand" ""))
18173 (use (match_operand:BLK 1 "memory_operand" ""))
18174 (use (match_operand:DI 2 "nonmemory_operand" ""))
18175 (use (match_operand:DI 3 "const_int_operand" ""))]
18178 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18184 ;; Most CPUs don't like single string operations
18185 ;; Handle this case here to simplify previous expander.
18187 (define_expand "strmov"
18188 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18189 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18190 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18191 (clobber (reg:CC FLAGS_REG))])
18192 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18193 (clobber (reg:CC FLAGS_REG))])]
18196 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18198 /* If .md ever supports :P for Pmode, these can be directly
18199 in the pattern above. */
18200 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18201 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18203 if (TARGET_SINGLE_STRINGOP || optimize_size)
18205 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18206 operands[2], operands[3],
18207 operands[5], operands[6]));
18211 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18214 (define_expand "strmov_singleop"
18215 [(parallel [(set (match_operand 1 "memory_operand" "")
18216 (match_operand 3 "memory_operand" ""))
18217 (set (match_operand 0 "register_operand" "")
18218 (match_operand 4 "" ""))
18219 (set (match_operand 2 "register_operand" "")
18220 (match_operand 5 "" ""))
18221 (use (reg:SI DIRFLAG_REG))])]
18222 "TARGET_SINGLE_STRINGOP || optimize_size"
18225 (define_insn "*strmovdi_rex_1"
18226 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18227 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18228 (set (match_operand:DI 0 "register_operand" "=D")
18229 (plus:DI (match_dup 2)
18231 (set (match_operand:DI 1 "register_operand" "=S")
18232 (plus:DI (match_dup 3)
18234 (use (reg:SI DIRFLAG_REG))]
18235 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18237 [(set_attr "type" "str")
18238 (set_attr "mode" "DI")
18239 (set_attr "memory" "both")])
18241 (define_insn "*strmovsi_1"
18242 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18243 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18244 (set (match_operand:SI 0 "register_operand" "=D")
18245 (plus:SI (match_dup 2)
18247 (set (match_operand:SI 1 "register_operand" "=S")
18248 (plus:SI (match_dup 3)
18250 (use (reg:SI DIRFLAG_REG))]
18251 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18253 [(set_attr "type" "str")
18254 (set_attr "mode" "SI")
18255 (set_attr "memory" "both")])
18257 (define_insn "*strmovsi_rex_1"
18258 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18259 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18260 (set (match_operand:DI 0 "register_operand" "=D")
18261 (plus:DI (match_dup 2)
18263 (set (match_operand:DI 1 "register_operand" "=S")
18264 (plus:DI (match_dup 3)
18266 (use (reg:SI DIRFLAG_REG))]
18267 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18269 [(set_attr "type" "str")
18270 (set_attr "mode" "SI")
18271 (set_attr "memory" "both")])
18273 (define_insn "*strmovhi_1"
18274 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18275 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18276 (set (match_operand:SI 0 "register_operand" "=D")
18277 (plus:SI (match_dup 2)
18279 (set (match_operand:SI 1 "register_operand" "=S")
18280 (plus:SI (match_dup 3)
18282 (use (reg:SI DIRFLAG_REG))]
18283 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18285 [(set_attr "type" "str")
18286 (set_attr "memory" "both")
18287 (set_attr "mode" "HI")])
18289 (define_insn "*strmovhi_rex_1"
18290 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18291 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18292 (set (match_operand:DI 0 "register_operand" "=D")
18293 (plus:DI (match_dup 2)
18295 (set (match_operand:DI 1 "register_operand" "=S")
18296 (plus:DI (match_dup 3)
18298 (use (reg:SI DIRFLAG_REG))]
18299 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18301 [(set_attr "type" "str")
18302 (set_attr "memory" "both")
18303 (set_attr "mode" "HI")])
18305 (define_insn "*strmovqi_1"
18306 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18307 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18308 (set (match_operand:SI 0 "register_operand" "=D")
18309 (plus:SI (match_dup 2)
18311 (set (match_operand:SI 1 "register_operand" "=S")
18312 (plus:SI (match_dup 3)
18314 (use (reg:SI DIRFLAG_REG))]
18315 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18317 [(set_attr "type" "str")
18318 (set_attr "memory" "both")
18319 (set_attr "mode" "QI")])
18321 (define_insn "*strmovqi_rex_1"
18322 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18323 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18324 (set (match_operand:DI 0 "register_operand" "=D")
18325 (plus:DI (match_dup 2)
18327 (set (match_operand:DI 1 "register_operand" "=S")
18328 (plus:DI (match_dup 3)
18330 (use (reg:SI DIRFLAG_REG))]
18331 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18333 [(set_attr "type" "str")
18334 (set_attr "memory" "both")
18335 (set_attr "mode" "QI")])
18337 (define_expand "rep_mov"
18338 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18339 (set (match_operand 0 "register_operand" "")
18340 (match_operand 5 "" ""))
18341 (set (match_operand 2 "register_operand" "")
18342 (match_operand 6 "" ""))
18343 (set (match_operand 1 "memory_operand" "")
18344 (match_operand 3 "memory_operand" ""))
18345 (use (match_dup 4))
18346 (use (reg:SI DIRFLAG_REG))])]
18350 (define_insn "*rep_movdi_rex64"
18351 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18352 (set (match_operand:DI 0 "register_operand" "=D")
18353 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18355 (match_operand:DI 3 "register_operand" "0")))
18356 (set (match_operand:DI 1 "register_operand" "=S")
18357 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18358 (match_operand:DI 4 "register_operand" "1")))
18359 (set (mem:BLK (match_dup 3))
18360 (mem:BLK (match_dup 4)))
18361 (use (match_dup 5))
18362 (use (reg:SI DIRFLAG_REG))]
18364 "{rep\;movsq|rep movsq}"
18365 [(set_attr "type" "str")
18366 (set_attr "prefix_rep" "1")
18367 (set_attr "memory" "both")
18368 (set_attr "mode" "DI")])
18370 (define_insn "*rep_movsi"
18371 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18372 (set (match_operand:SI 0 "register_operand" "=D")
18373 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18375 (match_operand:SI 3 "register_operand" "0")))
18376 (set (match_operand:SI 1 "register_operand" "=S")
18377 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18378 (match_operand:SI 4 "register_operand" "1")))
18379 (set (mem:BLK (match_dup 3))
18380 (mem:BLK (match_dup 4)))
18381 (use (match_dup 5))
18382 (use (reg:SI DIRFLAG_REG))]
18384 "{rep\;movsl|rep movsd}"
18385 [(set_attr "type" "str")
18386 (set_attr "prefix_rep" "1")
18387 (set_attr "memory" "both")
18388 (set_attr "mode" "SI")])
18390 (define_insn "*rep_movsi_rex64"
18391 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18392 (set (match_operand:DI 0 "register_operand" "=D")
18393 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18395 (match_operand:DI 3 "register_operand" "0")))
18396 (set (match_operand:DI 1 "register_operand" "=S")
18397 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18398 (match_operand:DI 4 "register_operand" "1")))
18399 (set (mem:BLK (match_dup 3))
18400 (mem:BLK (match_dup 4)))
18401 (use (match_dup 5))
18402 (use (reg:SI DIRFLAG_REG))]
18404 "{rep\;movsl|rep movsd}"
18405 [(set_attr "type" "str")
18406 (set_attr "prefix_rep" "1")
18407 (set_attr "memory" "both")
18408 (set_attr "mode" "SI")])
18410 (define_insn "*rep_movqi"
18411 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18412 (set (match_operand:SI 0 "register_operand" "=D")
18413 (plus:SI (match_operand:SI 3 "register_operand" "0")
18414 (match_operand:SI 5 "register_operand" "2")))
18415 (set (match_operand:SI 1 "register_operand" "=S")
18416 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18417 (set (mem:BLK (match_dup 3))
18418 (mem:BLK (match_dup 4)))
18419 (use (match_dup 5))
18420 (use (reg:SI DIRFLAG_REG))]
18422 "{rep\;movsb|rep movsb}"
18423 [(set_attr "type" "str")
18424 (set_attr "prefix_rep" "1")
18425 (set_attr "memory" "both")
18426 (set_attr "mode" "SI")])
18428 (define_insn "*rep_movqi_rex64"
18429 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18430 (set (match_operand:DI 0 "register_operand" "=D")
18431 (plus:DI (match_operand:DI 3 "register_operand" "0")
18432 (match_operand:DI 5 "register_operand" "2")))
18433 (set (match_operand:DI 1 "register_operand" "=S")
18434 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18435 (set (mem:BLK (match_dup 3))
18436 (mem:BLK (match_dup 4)))
18437 (use (match_dup 5))
18438 (use (reg:SI DIRFLAG_REG))]
18440 "{rep\;movsb|rep movsb}"
18441 [(set_attr "type" "str")
18442 (set_attr "prefix_rep" "1")
18443 (set_attr "memory" "both")
18444 (set_attr "mode" "SI")])
18446 (define_expand "setmemsi"
18447 [(use (match_operand:BLK 0 "memory_operand" ""))
18448 (use (match_operand:SI 1 "nonmemory_operand" ""))
18449 (use (match_operand 2 "const_int_operand" ""))
18450 (use (match_operand 3 "const_int_operand" ""))]
18453 /* If value to set is not zero, use the library routine. */
18454 if (operands[2] != const0_rtx)
18457 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18463 (define_expand "setmemdi"
18464 [(use (match_operand:BLK 0 "memory_operand" ""))
18465 (use (match_operand:DI 1 "nonmemory_operand" ""))
18466 (use (match_operand 2 "const_int_operand" ""))
18467 (use (match_operand 3 "const_int_operand" ""))]
18470 /* If value to set is not zero, use the library routine. */
18471 if (operands[2] != const0_rtx)
18474 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18480 ;; Most CPUs don't like single string operations
18481 ;; Handle this case here to simplify previous expander.
18483 (define_expand "strset"
18484 [(set (match_operand 1 "memory_operand" "")
18485 (match_operand 2 "register_operand" ""))
18486 (parallel [(set (match_operand 0 "register_operand" "")
18488 (clobber (reg:CC FLAGS_REG))])]
18491 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18492 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18494 /* If .md ever supports :P for Pmode, this can be directly
18495 in the pattern above. */
18496 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18497 GEN_INT (GET_MODE_SIZE (GET_MODE
18499 if (TARGET_SINGLE_STRINGOP || optimize_size)
18501 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18507 (define_expand "strset_singleop"
18508 [(parallel [(set (match_operand 1 "memory_operand" "")
18509 (match_operand 2 "register_operand" ""))
18510 (set (match_operand 0 "register_operand" "")
18511 (match_operand 3 "" ""))
18512 (use (reg:SI DIRFLAG_REG))])]
18513 "TARGET_SINGLE_STRINGOP || optimize_size"
18516 (define_insn "*strsetdi_rex_1"
18517 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18518 (match_operand:DI 2 "register_operand" "a"))
18519 (set (match_operand:DI 0 "register_operand" "=D")
18520 (plus:DI (match_dup 1)
18522 (use (reg:SI DIRFLAG_REG))]
18523 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18525 [(set_attr "type" "str")
18526 (set_attr "memory" "store")
18527 (set_attr "mode" "DI")])
18529 (define_insn "*strsetsi_1"
18530 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18531 (match_operand:SI 2 "register_operand" "a"))
18532 (set (match_operand:SI 0 "register_operand" "=D")
18533 (plus:SI (match_dup 1)
18535 (use (reg:SI DIRFLAG_REG))]
18536 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18538 [(set_attr "type" "str")
18539 (set_attr "memory" "store")
18540 (set_attr "mode" "SI")])
18542 (define_insn "*strsetsi_rex_1"
18543 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18544 (match_operand:SI 2 "register_operand" "a"))
18545 (set (match_operand:DI 0 "register_operand" "=D")
18546 (plus:DI (match_dup 1)
18548 (use (reg:SI DIRFLAG_REG))]
18549 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18551 [(set_attr "type" "str")
18552 (set_attr "memory" "store")
18553 (set_attr "mode" "SI")])
18555 (define_insn "*strsethi_1"
18556 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18557 (match_operand:HI 2 "register_operand" "a"))
18558 (set (match_operand:SI 0 "register_operand" "=D")
18559 (plus:SI (match_dup 1)
18561 (use (reg:SI DIRFLAG_REG))]
18562 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18564 [(set_attr "type" "str")
18565 (set_attr "memory" "store")
18566 (set_attr "mode" "HI")])
18568 (define_insn "*strsethi_rex_1"
18569 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18570 (match_operand:HI 2 "register_operand" "a"))
18571 (set (match_operand:DI 0 "register_operand" "=D")
18572 (plus:DI (match_dup 1)
18574 (use (reg:SI DIRFLAG_REG))]
18575 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18577 [(set_attr "type" "str")
18578 (set_attr "memory" "store")
18579 (set_attr "mode" "HI")])
18581 (define_insn "*strsetqi_1"
18582 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18583 (match_operand:QI 2 "register_operand" "a"))
18584 (set (match_operand:SI 0 "register_operand" "=D")
18585 (plus:SI (match_dup 1)
18587 (use (reg:SI DIRFLAG_REG))]
18588 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18590 [(set_attr "type" "str")
18591 (set_attr "memory" "store")
18592 (set_attr "mode" "QI")])
18594 (define_insn "*strsetqi_rex_1"
18595 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18596 (match_operand:QI 2 "register_operand" "a"))
18597 (set (match_operand:DI 0 "register_operand" "=D")
18598 (plus:DI (match_dup 1)
18600 (use (reg:SI DIRFLAG_REG))]
18601 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18603 [(set_attr "type" "str")
18604 (set_attr "memory" "store")
18605 (set_attr "mode" "QI")])
18607 (define_expand "rep_stos"
18608 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18609 (set (match_operand 0 "register_operand" "")
18610 (match_operand 4 "" ""))
18611 (set (match_operand 2 "memory_operand" "") (const_int 0))
18612 (use (match_operand 3 "register_operand" ""))
18613 (use (match_dup 1))
18614 (use (reg:SI DIRFLAG_REG))])]
18618 (define_insn "*rep_stosdi_rex64"
18619 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18620 (set (match_operand:DI 0 "register_operand" "=D")
18621 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18623 (match_operand:DI 3 "register_operand" "0")))
18624 (set (mem:BLK (match_dup 3))
18626 (use (match_operand:DI 2 "register_operand" "a"))
18627 (use (match_dup 4))
18628 (use (reg:SI DIRFLAG_REG))]
18630 "{rep\;stosq|rep stosq}"
18631 [(set_attr "type" "str")
18632 (set_attr "prefix_rep" "1")
18633 (set_attr "memory" "store")
18634 (set_attr "mode" "DI")])
18636 (define_insn "*rep_stossi"
18637 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18638 (set (match_operand:SI 0 "register_operand" "=D")
18639 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18641 (match_operand:SI 3 "register_operand" "0")))
18642 (set (mem:BLK (match_dup 3))
18644 (use (match_operand:SI 2 "register_operand" "a"))
18645 (use (match_dup 4))
18646 (use (reg:SI DIRFLAG_REG))]
18648 "{rep\;stosl|rep stosd}"
18649 [(set_attr "type" "str")
18650 (set_attr "prefix_rep" "1")
18651 (set_attr "memory" "store")
18652 (set_attr "mode" "SI")])
18654 (define_insn "*rep_stossi_rex64"
18655 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18656 (set (match_operand:DI 0 "register_operand" "=D")
18657 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18659 (match_operand:DI 3 "register_operand" "0")))
18660 (set (mem:BLK (match_dup 3))
18662 (use (match_operand:SI 2 "register_operand" "a"))
18663 (use (match_dup 4))
18664 (use (reg:SI DIRFLAG_REG))]
18666 "{rep\;stosl|rep stosd}"
18667 [(set_attr "type" "str")
18668 (set_attr "prefix_rep" "1")
18669 (set_attr "memory" "store")
18670 (set_attr "mode" "SI")])
18672 (define_insn "*rep_stosqi"
18673 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18674 (set (match_operand:SI 0 "register_operand" "=D")
18675 (plus:SI (match_operand:SI 3 "register_operand" "0")
18676 (match_operand:SI 4 "register_operand" "1")))
18677 (set (mem:BLK (match_dup 3))
18679 (use (match_operand:QI 2 "register_operand" "a"))
18680 (use (match_dup 4))
18681 (use (reg:SI DIRFLAG_REG))]
18683 "{rep\;stosb|rep stosb}"
18684 [(set_attr "type" "str")
18685 (set_attr "prefix_rep" "1")
18686 (set_attr "memory" "store")
18687 (set_attr "mode" "QI")])
18689 (define_insn "*rep_stosqi_rex64"
18690 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18691 (set (match_operand:DI 0 "register_operand" "=D")
18692 (plus:DI (match_operand:DI 3 "register_operand" "0")
18693 (match_operand:DI 4 "register_operand" "1")))
18694 (set (mem:BLK (match_dup 3))
18696 (use (match_operand:QI 2 "register_operand" "a"))
18697 (use (match_dup 4))
18698 (use (reg:SI DIRFLAG_REG))]
18700 "{rep\;stosb|rep stosb}"
18701 [(set_attr "type" "str")
18702 (set_attr "prefix_rep" "1")
18703 (set_attr "memory" "store")
18704 (set_attr "mode" "QI")])
18706 (define_expand "cmpstrnsi"
18707 [(set (match_operand:SI 0 "register_operand" "")
18708 (compare:SI (match_operand:BLK 1 "general_operand" "")
18709 (match_operand:BLK 2 "general_operand" "")))
18710 (use (match_operand 3 "general_operand" ""))
18711 (use (match_operand 4 "immediate_operand" ""))]
18712 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18714 rtx addr1, addr2, out, outlow, count, countreg, align;
18716 /* Can't use this if the user has appropriated esi or edi. */
18717 if (global_regs[4] || global_regs[5])
18721 if (GET_CODE (out) != REG)
18722 out = gen_reg_rtx (SImode);
18724 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18725 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18726 if (addr1 != XEXP (operands[1], 0))
18727 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18728 if (addr2 != XEXP (operands[2], 0))
18729 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18731 count = operands[3];
18732 countreg = ix86_zero_extend_to_Pmode (count);
18734 /* %%% Iff we are testing strict equality, we can use known alignment
18735 to good advantage. This may be possible with combine, particularly
18736 once cc0 is dead. */
18737 align = operands[4];
18739 emit_insn (gen_cld ());
18740 if (GET_CODE (count) == CONST_INT)
18742 if (INTVAL (count) == 0)
18744 emit_move_insn (operands[0], const0_rtx);
18747 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18748 operands[1], operands[2]));
18753 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18755 emit_insn (gen_cmpsi_1 (countreg, countreg));
18756 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18757 operands[1], operands[2]));
18760 outlow = gen_lowpart (QImode, out);
18761 emit_insn (gen_cmpintqi (outlow));
18762 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18764 if (operands[0] != out)
18765 emit_move_insn (operands[0], out);
18770 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18772 (define_expand "cmpintqi"
18773 [(set (match_dup 1)
18774 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18776 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18777 (parallel [(set (match_operand:QI 0 "register_operand" "")
18778 (minus:QI (match_dup 1)
18780 (clobber (reg:CC FLAGS_REG))])]
18782 "operands[1] = gen_reg_rtx (QImode);
18783 operands[2] = gen_reg_rtx (QImode);")
18785 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18786 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18788 (define_expand "cmpstrnqi_nz_1"
18789 [(parallel [(set (reg:CC FLAGS_REG)
18790 (compare:CC (match_operand 4 "memory_operand" "")
18791 (match_operand 5 "memory_operand" "")))
18792 (use (match_operand 2 "register_operand" ""))
18793 (use (match_operand:SI 3 "immediate_operand" ""))
18794 (use (reg:SI DIRFLAG_REG))
18795 (clobber (match_operand 0 "register_operand" ""))
18796 (clobber (match_operand 1 "register_operand" ""))
18797 (clobber (match_dup 2))])]
18801 (define_insn "*cmpstrnqi_nz_1"
18802 [(set (reg:CC FLAGS_REG)
18803 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18804 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18805 (use (match_operand:SI 6 "register_operand" "2"))
18806 (use (match_operand:SI 3 "immediate_operand" "i"))
18807 (use (reg:SI DIRFLAG_REG))
18808 (clobber (match_operand:SI 0 "register_operand" "=S"))
18809 (clobber (match_operand:SI 1 "register_operand" "=D"))
18810 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18813 [(set_attr "type" "str")
18814 (set_attr "mode" "QI")
18815 (set_attr "prefix_rep" "1")])
18817 (define_insn "*cmpstrnqi_nz_rex_1"
18818 [(set (reg:CC FLAGS_REG)
18819 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18820 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18821 (use (match_operand:DI 6 "register_operand" "2"))
18822 (use (match_operand:SI 3 "immediate_operand" "i"))
18823 (use (reg:SI DIRFLAG_REG))
18824 (clobber (match_operand:DI 0 "register_operand" "=S"))
18825 (clobber (match_operand:DI 1 "register_operand" "=D"))
18826 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18829 [(set_attr "type" "str")
18830 (set_attr "mode" "QI")
18831 (set_attr "prefix_rep" "1")])
18833 ;; The same, but the count is not known to not be zero.
18835 (define_expand "cmpstrnqi_1"
18836 [(parallel [(set (reg:CC FLAGS_REG)
18837 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18839 (compare:CC (match_operand 4 "memory_operand" "")
18840 (match_operand 5 "memory_operand" ""))
18842 (use (match_operand:SI 3 "immediate_operand" ""))
18843 (use (reg:CC FLAGS_REG))
18844 (use (reg:SI DIRFLAG_REG))
18845 (clobber (match_operand 0 "register_operand" ""))
18846 (clobber (match_operand 1 "register_operand" ""))
18847 (clobber (match_dup 2))])]
18851 (define_insn "*cmpstrnqi_1"
18852 [(set (reg:CC FLAGS_REG)
18853 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18855 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18856 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18858 (use (match_operand:SI 3 "immediate_operand" "i"))
18859 (use (reg:CC FLAGS_REG))
18860 (use (reg:SI DIRFLAG_REG))
18861 (clobber (match_operand:SI 0 "register_operand" "=S"))
18862 (clobber (match_operand:SI 1 "register_operand" "=D"))
18863 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18866 [(set_attr "type" "str")
18867 (set_attr "mode" "QI")
18868 (set_attr "prefix_rep" "1")])
18870 (define_insn "*cmpstrnqi_rex_1"
18871 [(set (reg:CC FLAGS_REG)
18872 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18874 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18875 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18877 (use (match_operand:SI 3 "immediate_operand" "i"))
18878 (use (reg:CC FLAGS_REG))
18879 (use (reg:SI DIRFLAG_REG))
18880 (clobber (match_operand:DI 0 "register_operand" "=S"))
18881 (clobber (match_operand:DI 1 "register_operand" "=D"))
18882 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18885 [(set_attr "type" "str")
18886 (set_attr "mode" "QI")
18887 (set_attr "prefix_rep" "1")])
18889 (define_expand "strlensi"
18890 [(set (match_operand:SI 0 "register_operand" "")
18891 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18892 (match_operand:QI 2 "immediate_operand" "")
18893 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18896 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18902 (define_expand "strlendi"
18903 [(set (match_operand:DI 0 "register_operand" "")
18904 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18905 (match_operand:QI 2 "immediate_operand" "")
18906 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18909 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18915 (define_expand "strlenqi_1"
18916 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18917 (use (reg:SI DIRFLAG_REG))
18918 (clobber (match_operand 1 "register_operand" ""))
18919 (clobber (reg:CC FLAGS_REG))])]
18923 (define_insn "*strlenqi_1"
18924 [(set (match_operand:SI 0 "register_operand" "=&c")
18925 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18926 (match_operand:QI 2 "register_operand" "a")
18927 (match_operand:SI 3 "immediate_operand" "i")
18928 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18929 (use (reg:SI DIRFLAG_REG))
18930 (clobber (match_operand:SI 1 "register_operand" "=D"))
18931 (clobber (reg:CC FLAGS_REG))]
18934 [(set_attr "type" "str")
18935 (set_attr "mode" "QI")
18936 (set_attr "prefix_rep" "1")])
18938 (define_insn "*strlenqi_rex_1"
18939 [(set (match_operand:DI 0 "register_operand" "=&c")
18940 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18941 (match_operand:QI 2 "register_operand" "a")
18942 (match_operand:DI 3 "immediate_operand" "i")
18943 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18944 (use (reg:SI DIRFLAG_REG))
18945 (clobber (match_operand:DI 1 "register_operand" "=D"))
18946 (clobber (reg:CC FLAGS_REG))]
18949 [(set_attr "type" "str")
18950 (set_attr "mode" "QI")
18951 (set_attr "prefix_rep" "1")])
18953 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18954 ;; handled in combine, but it is not currently up to the task.
18955 ;; When used for their truth value, the cmpstrn* expanders generate
18964 ;; The intermediate three instructions are unnecessary.
18966 ;; This one handles cmpstrn*_nz_1...
18969 (set (reg:CC FLAGS_REG)
18970 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18971 (mem:BLK (match_operand 5 "register_operand" ""))))
18972 (use (match_operand 6 "register_operand" ""))
18973 (use (match_operand:SI 3 "immediate_operand" ""))
18974 (use (reg:SI DIRFLAG_REG))
18975 (clobber (match_operand 0 "register_operand" ""))
18976 (clobber (match_operand 1 "register_operand" ""))
18977 (clobber (match_operand 2 "register_operand" ""))])
18978 (set (match_operand:QI 7 "register_operand" "")
18979 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18980 (set (match_operand:QI 8 "register_operand" "")
18981 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18982 (set (reg FLAGS_REG)
18983 (compare (match_dup 7) (match_dup 8)))
18985 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18987 (set (reg:CC FLAGS_REG)
18988 (compare:CC (mem:BLK (match_dup 4))
18989 (mem:BLK (match_dup 5))))
18990 (use (match_dup 6))
18991 (use (match_dup 3))
18992 (use (reg:SI DIRFLAG_REG))
18993 (clobber (match_dup 0))
18994 (clobber (match_dup 1))
18995 (clobber (match_dup 2))])]
18998 ;; ...and this one handles cmpstrn*_1.
19001 (set (reg:CC FLAGS_REG)
19002 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19004 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19005 (mem:BLK (match_operand 5 "register_operand" "")))
19007 (use (match_operand:SI 3 "immediate_operand" ""))
19008 (use (reg:CC FLAGS_REG))
19009 (use (reg:SI DIRFLAG_REG))
19010 (clobber (match_operand 0 "register_operand" ""))
19011 (clobber (match_operand 1 "register_operand" ""))
19012 (clobber (match_operand 2 "register_operand" ""))])
19013 (set (match_operand:QI 7 "register_operand" "")
19014 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19015 (set (match_operand:QI 8 "register_operand" "")
19016 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19017 (set (reg FLAGS_REG)
19018 (compare (match_dup 7) (match_dup 8)))
19020 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19022 (set (reg:CC FLAGS_REG)
19023 (if_then_else:CC (ne (match_dup 6)
19025 (compare:CC (mem:BLK (match_dup 4))
19026 (mem:BLK (match_dup 5)))
19028 (use (match_dup 3))
19029 (use (reg:CC FLAGS_REG))
19030 (use (reg:SI DIRFLAG_REG))
19031 (clobber (match_dup 0))
19032 (clobber (match_dup 1))
19033 (clobber (match_dup 2))])]
19038 ;; Conditional move instructions.
19040 (define_expand "movdicc"
19041 [(set (match_operand:DI 0 "register_operand" "")
19042 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19043 (match_operand:DI 2 "general_operand" "")
19044 (match_operand:DI 3 "general_operand" "")))]
19046 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19048 (define_insn "x86_movdicc_0_m1_rex64"
19049 [(set (match_operand:DI 0 "register_operand" "=r")
19050 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19053 (clobber (reg:CC FLAGS_REG))]
19056 ; Since we don't have the proper number of operands for an alu insn,
19057 ; fill in all the blanks.
19058 [(set_attr "type" "alu")
19059 (set_attr "pent_pair" "pu")
19060 (set_attr "memory" "none")
19061 (set_attr "imm_disp" "false")
19062 (set_attr "mode" "DI")
19063 (set_attr "length_immediate" "0")])
19065 (define_insn "*movdicc_c_rex64"
19066 [(set (match_operand:DI 0 "register_operand" "=r,r")
19067 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19068 [(reg FLAGS_REG) (const_int 0)])
19069 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19070 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19071 "TARGET_64BIT && TARGET_CMOVE
19072 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19074 cmov%O2%C1\t{%2, %0|%0, %2}
19075 cmov%O2%c1\t{%3, %0|%0, %3}"
19076 [(set_attr "type" "icmov")
19077 (set_attr "mode" "DI")])
19079 (define_expand "movsicc"
19080 [(set (match_operand:SI 0 "register_operand" "")
19081 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19082 (match_operand:SI 2 "general_operand" "")
19083 (match_operand:SI 3 "general_operand" "")))]
19085 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19087 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19088 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19089 ;; So just document what we're doing explicitly.
19091 (define_insn "x86_movsicc_0_m1"
19092 [(set (match_operand:SI 0 "register_operand" "=r")
19093 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19096 (clobber (reg:CC FLAGS_REG))]
19099 ; Since we don't have the proper number of operands for an alu insn,
19100 ; fill in all the blanks.
19101 [(set_attr "type" "alu")
19102 (set_attr "pent_pair" "pu")
19103 (set_attr "memory" "none")
19104 (set_attr "imm_disp" "false")
19105 (set_attr "mode" "SI")
19106 (set_attr "length_immediate" "0")])
19108 (define_insn "*movsicc_noc"
19109 [(set (match_operand:SI 0 "register_operand" "=r,r")
19110 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19111 [(reg FLAGS_REG) (const_int 0)])
19112 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19113 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19115 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19117 cmov%O2%C1\t{%2, %0|%0, %2}
19118 cmov%O2%c1\t{%3, %0|%0, %3}"
19119 [(set_attr "type" "icmov")
19120 (set_attr "mode" "SI")])
19122 (define_expand "movhicc"
19123 [(set (match_operand:HI 0 "register_operand" "")
19124 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19125 (match_operand:HI 2 "general_operand" "")
19126 (match_operand:HI 3 "general_operand" "")))]
19127 "TARGET_HIMODE_MATH"
19128 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19130 (define_insn "*movhicc_noc"
19131 [(set (match_operand:HI 0 "register_operand" "=r,r")
19132 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19133 [(reg FLAGS_REG) (const_int 0)])
19134 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19135 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19137 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19139 cmov%O2%C1\t{%2, %0|%0, %2}
19140 cmov%O2%c1\t{%3, %0|%0, %3}"
19141 [(set_attr "type" "icmov")
19142 (set_attr "mode" "HI")])
19144 (define_expand "movqicc"
19145 [(set (match_operand:QI 0 "register_operand" "")
19146 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19147 (match_operand:QI 2 "general_operand" "")
19148 (match_operand:QI 3 "general_operand" "")))]
19149 "TARGET_QIMODE_MATH"
19150 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19152 (define_insn_and_split "*movqicc_noc"
19153 [(set (match_operand:QI 0 "register_operand" "=r,r")
19154 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19155 [(match_operand 4 "flags_reg_operand" "")
19157 (match_operand:QI 2 "register_operand" "r,0")
19158 (match_operand:QI 3 "register_operand" "0,r")))]
19159 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19161 "&& reload_completed"
19162 [(set (match_dup 0)
19163 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19166 "operands[0] = gen_lowpart (SImode, operands[0]);
19167 operands[2] = gen_lowpart (SImode, operands[2]);
19168 operands[3] = gen_lowpart (SImode, operands[3]);"
19169 [(set_attr "type" "icmov")
19170 (set_attr "mode" "SI")])
19172 (define_expand "movsfcc"
19173 [(set (match_operand:SF 0 "register_operand" "")
19174 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19175 (match_operand:SF 2 "register_operand" "")
19176 (match_operand:SF 3 "register_operand" "")))]
19177 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19178 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19180 (define_insn "*movsfcc_1_387"
19181 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19182 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19183 [(reg FLAGS_REG) (const_int 0)])
19184 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19185 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19186 "TARGET_80387 && TARGET_CMOVE
19187 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19189 fcmov%F1\t{%2, %0|%0, %2}
19190 fcmov%f1\t{%3, %0|%0, %3}
19191 cmov%O2%C1\t{%2, %0|%0, %2}
19192 cmov%O2%c1\t{%3, %0|%0, %3}"
19193 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19194 (set_attr "mode" "SF,SF,SI,SI")])
19196 (define_expand "movdfcc"
19197 [(set (match_operand:DF 0 "register_operand" "")
19198 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19199 (match_operand:DF 2 "register_operand" "")
19200 (match_operand:DF 3 "register_operand" "")))]
19201 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19202 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19204 (define_insn "*movdfcc_1"
19205 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19206 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19207 [(reg FLAGS_REG) (const_int 0)])
19208 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19209 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19210 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19211 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19213 fcmov%F1\t{%2, %0|%0, %2}
19214 fcmov%f1\t{%3, %0|%0, %3}
19217 [(set_attr "type" "fcmov,fcmov,multi,multi")
19218 (set_attr "mode" "DF")])
19220 (define_insn "*movdfcc_1_rex64"
19221 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19222 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19223 [(reg FLAGS_REG) (const_int 0)])
19224 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19225 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19226 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19227 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19229 fcmov%F1\t{%2, %0|%0, %2}
19230 fcmov%f1\t{%3, %0|%0, %3}
19231 cmov%O2%C1\t{%2, %0|%0, %2}
19232 cmov%O2%c1\t{%3, %0|%0, %3}"
19233 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19234 (set_attr "mode" "DF")])
19237 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19238 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19239 [(match_operand 4 "flags_reg_operand" "")
19241 (match_operand:DF 2 "nonimmediate_operand" "")
19242 (match_operand:DF 3 "nonimmediate_operand" "")))]
19243 "!TARGET_64BIT && reload_completed"
19244 [(set (match_dup 2)
19245 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19249 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19252 "split_di (operands+2, 1, operands+5, operands+6);
19253 split_di (operands+3, 1, operands+7, operands+8);
19254 split_di (operands, 1, operands+2, operands+3);")
19256 (define_expand "movxfcc"
19257 [(set (match_operand:XF 0 "register_operand" "")
19258 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19259 (match_operand:XF 2 "register_operand" "")
19260 (match_operand:XF 3 "register_operand" "")))]
19261 "TARGET_80387 && TARGET_CMOVE"
19262 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19264 (define_insn "*movxfcc_1"
19265 [(set (match_operand:XF 0 "register_operand" "=f,f")
19266 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19267 [(reg FLAGS_REG) (const_int 0)])
19268 (match_operand:XF 2 "register_operand" "f,0")
19269 (match_operand:XF 3 "register_operand" "0,f")))]
19270 "TARGET_80387 && TARGET_CMOVE"
19272 fcmov%F1\t{%2, %0|%0, %2}
19273 fcmov%f1\t{%3, %0|%0, %3}"
19274 [(set_attr "type" "fcmov")
19275 (set_attr "mode" "XF")])
19277 ;; These versions of the min/max patterns are intentionally ignorant of
19278 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19279 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19280 ;; are undefined in this condition, we're certain this is correct.
19282 (define_insn "sminsf3"
19283 [(set (match_operand:SF 0 "register_operand" "=x")
19284 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19285 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19287 "minss\t{%2, %0|%0, %2}"
19288 [(set_attr "type" "sseadd")
19289 (set_attr "mode" "SF")])
19291 (define_insn "smaxsf3"
19292 [(set (match_operand:SF 0 "register_operand" "=x")
19293 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19294 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19296 "maxss\t{%2, %0|%0, %2}"
19297 [(set_attr "type" "sseadd")
19298 (set_attr "mode" "SF")])
19300 (define_insn "smindf3"
19301 [(set (match_operand:DF 0 "register_operand" "=x")
19302 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19303 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19304 "TARGET_SSE2 && TARGET_SSE_MATH"
19305 "minsd\t{%2, %0|%0, %2}"
19306 [(set_attr "type" "sseadd")
19307 (set_attr "mode" "DF")])
19309 (define_insn "smaxdf3"
19310 [(set (match_operand:DF 0 "register_operand" "=x")
19311 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19312 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19313 "TARGET_SSE2 && TARGET_SSE_MATH"
19314 "maxsd\t{%2, %0|%0, %2}"
19315 [(set_attr "type" "sseadd")
19316 (set_attr "mode" "DF")])
19318 ;; These versions of the min/max patterns implement exactly the operations
19319 ;; min = (op1 < op2 ? op1 : op2)
19320 ;; max = (!(op1 < op2) ? op1 : op2)
19321 ;; Their operands are not commutative, and thus they may be used in the
19322 ;; presence of -0.0 and NaN.
19324 (define_insn "*ieee_sminsf3"
19325 [(set (match_operand:SF 0 "register_operand" "=x")
19326 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19327 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19330 "minss\t{%2, %0|%0, %2}"
19331 [(set_attr "type" "sseadd")
19332 (set_attr "mode" "SF")])
19334 (define_insn "*ieee_smaxsf3"
19335 [(set (match_operand:SF 0 "register_operand" "=x")
19336 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19337 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19340 "maxss\t{%2, %0|%0, %2}"
19341 [(set_attr "type" "sseadd")
19342 (set_attr "mode" "SF")])
19344 (define_insn "*ieee_smindf3"
19345 [(set (match_operand:DF 0 "register_operand" "=x")
19346 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19347 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19349 "TARGET_SSE2 && TARGET_SSE_MATH"
19350 "minsd\t{%2, %0|%0, %2}"
19351 [(set_attr "type" "sseadd")
19352 (set_attr "mode" "DF")])
19354 (define_insn "*ieee_smaxdf3"
19355 [(set (match_operand:DF 0 "register_operand" "=x")
19356 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19357 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19359 "TARGET_SSE2 && TARGET_SSE_MATH"
19360 "maxsd\t{%2, %0|%0, %2}"
19361 [(set_attr "type" "sseadd")
19362 (set_attr "mode" "DF")])
19364 ;; Make two stack loads independent:
19366 ;; fld %st(0) -> fld bb
19367 ;; fmul bb fmul %st(1), %st
19369 ;; Actually we only match the last two instructions for simplicity.
19371 [(set (match_operand 0 "fp_register_operand" "")
19372 (match_operand 1 "fp_register_operand" ""))
19374 (match_operator 2 "binary_fp_operator"
19376 (match_operand 3 "memory_operand" "")]))]
19377 "REGNO (operands[0]) != REGNO (operands[1])"
19378 [(set (match_dup 0) (match_dup 3))
19379 (set (match_dup 0) (match_dup 4))]
19381 ;; The % modifier is not operational anymore in peephole2's, so we have to
19382 ;; swap the operands manually in the case of addition and multiplication.
19383 "if (COMMUTATIVE_ARITH_P (operands[2]))
19384 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19385 operands[0], operands[1]);
19387 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19388 operands[1], operands[0]);")
19390 ;; Conditional addition patterns
19391 (define_expand "addqicc"
19392 [(match_operand:QI 0 "register_operand" "")
19393 (match_operand 1 "comparison_operator" "")
19394 (match_operand:QI 2 "register_operand" "")
19395 (match_operand:QI 3 "const_int_operand" "")]
19397 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19399 (define_expand "addhicc"
19400 [(match_operand:HI 0 "register_operand" "")
19401 (match_operand 1 "comparison_operator" "")
19402 (match_operand:HI 2 "register_operand" "")
19403 (match_operand:HI 3 "const_int_operand" "")]
19405 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19407 (define_expand "addsicc"
19408 [(match_operand:SI 0 "register_operand" "")
19409 (match_operand 1 "comparison_operator" "")
19410 (match_operand:SI 2 "register_operand" "")
19411 (match_operand:SI 3 "const_int_operand" "")]
19413 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19415 (define_expand "adddicc"
19416 [(match_operand:DI 0 "register_operand" "")
19417 (match_operand 1 "comparison_operator" "")
19418 (match_operand:DI 2 "register_operand" "")
19419 (match_operand:DI 3 "const_int_operand" "")]
19421 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19424 ;; Misc patterns (?)
19426 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19427 ;; Otherwise there will be nothing to keep
19429 ;; [(set (reg ebp) (reg esp))]
19430 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19431 ;; (clobber (eflags)]
19432 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19434 ;; in proper program order.
19435 (define_insn "pro_epilogue_adjust_stack_1"
19436 [(set (match_operand:SI 0 "register_operand" "=r,r")
19437 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19438 (match_operand:SI 2 "immediate_operand" "i,i")))
19439 (clobber (reg:CC FLAGS_REG))
19440 (clobber (mem:BLK (scratch)))]
19443 switch (get_attr_type (insn))
19446 return "mov{l}\t{%1, %0|%0, %1}";
19449 if (GET_CODE (operands[2]) == CONST_INT
19450 && (INTVAL (operands[2]) == 128
19451 || (INTVAL (operands[2]) < 0
19452 && INTVAL (operands[2]) != -128)))
19454 operands[2] = GEN_INT (-INTVAL (operands[2]));
19455 return "sub{l}\t{%2, %0|%0, %2}";
19457 return "add{l}\t{%2, %0|%0, %2}";
19460 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19461 return "lea{l}\t{%a2, %0|%0, %a2}";
19464 gcc_unreachable ();
19467 [(set (attr "type")
19468 (cond [(eq_attr "alternative" "0")
19469 (const_string "alu")
19470 (match_operand:SI 2 "const0_operand" "")
19471 (const_string "imov")
19473 (const_string "lea")))
19474 (set_attr "mode" "SI")])
19476 (define_insn "pro_epilogue_adjust_stack_rex64"
19477 [(set (match_operand:DI 0 "register_operand" "=r,r")
19478 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19479 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19480 (clobber (reg:CC FLAGS_REG))
19481 (clobber (mem:BLK (scratch)))]
19484 switch (get_attr_type (insn))
19487 return "mov{q}\t{%1, %0|%0, %1}";
19490 if (GET_CODE (operands[2]) == CONST_INT
19491 /* Avoid overflows. */
19492 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19493 && (INTVAL (operands[2]) == 128
19494 || (INTVAL (operands[2]) < 0
19495 && INTVAL (operands[2]) != -128)))
19497 operands[2] = GEN_INT (-INTVAL (operands[2]));
19498 return "sub{q}\t{%2, %0|%0, %2}";
19500 return "add{q}\t{%2, %0|%0, %2}";
19503 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19504 return "lea{q}\t{%a2, %0|%0, %a2}";
19507 gcc_unreachable ();
19510 [(set (attr "type")
19511 (cond [(eq_attr "alternative" "0")
19512 (const_string "alu")
19513 (match_operand:DI 2 "const0_operand" "")
19514 (const_string "imov")
19516 (const_string "lea")))
19517 (set_attr "mode" "DI")])
19519 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19520 [(set (match_operand:DI 0 "register_operand" "=r,r")
19521 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19522 (match_operand:DI 3 "immediate_operand" "i,i")))
19523 (use (match_operand:DI 2 "register_operand" "r,r"))
19524 (clobber (reg:CC FLAGS_REG))
19525 (clobber (mem:BLK (scratch)))]
19528 switch (get_attr_type (insn))
19531 return "add{q}\t{%2, %0|%0, %2}";
19534 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19535 return "lea{q}\t{%a2, %0|%0, %a2}";
19538 gcc_unreachable ();
19541 [(set_attr "type" "alu,lea")
19542 (set_attr "mode" "DI")])
19544 (define_expand "allocate_stack_worker"
19545 [(match_operand:SI 0 "register_operand" "")]
19546 "TARGET_STACK_PROBE"
19548 if (reload_completed)
19551 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19553 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19558 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19560 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19565 (define_insn "allocate_stack_worker_1"
19566 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19567 UNSPECV_STACK_PROBE)
19568 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19569 (clobber (match_scratch:SI 1 "=0"))
19570 (clobber (reg:CC FLAGS_REG))]
19571 "!TARGET_64BIT && TARGET_STACK_PROBE"
19573 [(set_attr "type" "multi")
19574 (set_attr "length" "5")])
19576 (define_expand "allocate_stack_worker_postreload"
19577 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19578 UNSPECV_STACK_PROBE)
19579 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19580 (clobber (match_dup 0))
19581 (clobber (reg:CC FLAGS_REG))])]
19585 (define_insn "allocate_stack_worker_rex64"
19586 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19587 UNSPECV_STACK_PROBE)
19588 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19589 (clobber (match_scratch:DI 1 "=0"))
19590 (clobber (reg:CC FLAGS_REG))]
19591 "TARGET_64BIT && TARGET_STACK_PROBE"
19593 [(set_attr "type" "multi")
19594 (set_attr "length" "5")])
19596 (define_expand "allocate_stack_worker_rex64_postreload"
19597 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19598 UNSPECV_STACK_PROBE)
19599 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19600 (clobber (match_dup 0))
19601 (clobber (reg:CC FLAGS_REG))])]
19605 (define_expand "allocate_stack"
19606 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19607 (minus:SI (reg:SI SP_REG)
19608 (match_operand:SI 1 "general_operand" "")))
19609 (clobber (reg:CC FLAGS_REG))])
19610 (parallel [(set (reg:SI SP_REG)
19611 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19612 (clobber (reg:CC FLAGS_REG))])]
19613 "TARGET_STACK_PROBE"
19615 #ifdef CHECK_STACK_LIMIT
19616 if (GET_CODE (operands[1]) == CONST_INT
19617 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19618 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19622 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19625 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19629 (define_expand "builtin_setjmp_receiver"
19630 [(label_ref (match_operand 0 "" ""))]
19631 "!TARGET_64BIT && flag_pic"
19636 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19637 rtx label_rtx = gen_label_rtx ();
19638 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19639 xops[0] = xops[1] = picreg;
19640 xops[2] = gen_rtx_CONST (SImode,
19641 gen_rtx_MINUS (SImode,
19642 gen_rtx_LABEL_REF (SImode, label_rtx),
19643 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19644 ix86_expand_binary_operator (MINUS, SImode, xops);
19647 emit_insn (gen_set_got (pic_offset_table_rtx));
19651 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19654 [(set (match_operand 0 "register_operand" "")
19655 (match_operator 3 "promotable_binary_operator"
19656 [(match_operand 1 "register_operand" "")
19657 (match_operand 2 "aligned_operand" "")]))
19658 (clobber (reg:CC FLAGS_REG))]
19659 "! TARGET_PARTIAL_REG_STALL && reload_completed
19660 && ((GET_MODE (operands[0]) == HImode
19661 && ((!optimize_size && !TARGET_FAST_PREFIX)
19662 /* ??? next two lines just !satisfies_constraint_K (...) */
19663 || GET_CODE (operands[2]) != CONST_INT
19664 || satisfies_constraint_K (operands[2])))
19665 || (GET_MODE (operands[0]) == QImode
19666 && (TARGET_PROMOTE_QImode || optimize_size)))"
19667 [(parallel [(set (match_dup 0)
19668 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19669 (clobber (reg:CC FLAGS_REG))])]
19670 "operands[0] = gen_lowpart (SImode, operands[0]);
19671 operands[1] = gen_lowpart (SImode, operands[1]);
19672 if (GET_CODE (operands[3]) != ASHIFT)
19673 operands[2] = gen_lowpart (SImode, operands[2]);
19674 PUT_MODE (operands[3], SImode);")
19676 ; Promote the QImode tests, as i386 has encoding of the AND
19677 ; instruction with 32-bit sign-extended immediate and thus the
19678 ; instruction size is unchanged, except in the %eax case for
19679 ; which it is increased by one byte, hence the ! optimize_size.
19681 [(set (match_operand 0 "flags_reg_operand" "")
19682 (match_operator 2 "compare_operator"
19683 [(and (match_operand 3 "aligned_operand" "")
19684 (match_operand 4 "const_int_operand" ""))
19686 (set (match_operand 1 "register_operand" "")
19687 (and (match_dup 3) (match_dup 4)))]
19688 "! TARGET_PARTIAL_REG_STALL && reload_completed
19689 /* Ensure that the operand will remain sign-extended immediate. */
19690 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19692 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19693 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19694 [(parallel [(set (match_dup 0)
19695 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19698 (and:SI (match_dup 3) (match_dup 4)))])]
19701 = gen_int_mode (INTVAL (operands[4])
19702 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19703 operands[1] = gen_lowpart (SImode, operands[1]);
19704 operands[3] = gen_lowpart (SImode, operands[3]);
19707 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19708 ; the TEST instruction with 32-bit sign-extended immediate and thus
19709 ; the instruction size would at least double, which is not what we
19710 ; want even with ! optimize_size.
19712 [(set (match_operand 0 "flags_reg_operand" "")
19713 (match_operator 1 "compare_operator"
19714 [(and (match_operand:HI 2 "aligned_operand" "")
19715 (match_operand:HI 3 "const_int_operand" ""))
19717 "! TARGET_PARTIAL_REG_STALL && reload_completed
19718 /* Ensure that the operand will remain sign-extended immediate. */
19719 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19720 && ! TARGET_FAST_PREFIX
19721 && ! optimize_size"
19722 [(set (match_dup 0)
19723 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19727 = gen_int_mode (INTVAL (operands[3])
19728 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19729 operands[2] = gen_lowpart (SImode, operands[2]);
19733 [(set (match_operand 0 "register_operand" "")
19734 (neg (match_operand 1 "register_operand" "")))
19735 (clobber (reg:CC FLAGS_REG))]
19736 "! TARGET_PARTIAL_REG_STALL && reload_completed
19737 && (GET_MODE (operands[0]) == HImode
19738 || (GET_MODE (operands[0]) == QImode
19739 && (TARGET_PROMOTE_QImode || optimize_size)))"
19740 [(parallel [(set (match_dup 0)
19741 (neg:SI (match_dup 1)))
19742 (clobber (reg:CC FLAGS_REG))])]
19743 "operands[0] = gen_lowpart (SImode, operands[0]);
19744 operands[1] = gen_lowpart (SImode, operands[1]);")
19747 [(set (match_operand 0 "register_operand" "")
19748 (not (match_operand 1 "register_operand" "")))]
19749 "! TARGET_PARTIAL_REG_STALL && reload_completed
19750 && (GET_MODE (operands[0]) == HImode
19751 || (GET_MODE (operands[0]) == QImode
19752 && (TARGET_PROMOTE_QImode || optimize_size)))"
19753 [(set (match_dup 0)
19754 (not:SI (match_dup 1)))]
19755 "operands[0] = gen_lowpart (SImode, operands[0]);
19756 operands[1] = gen_lowpart (SImode, operands[1]);")
19759 [(set (match_operand 0 "register_operand" "")
19760 (if_then_else (match_operator 1 "comparison_operator"
19761 [(reg FLAGS_REG) (const_int 0)])
19762 (match_operand 2 "register_operand" "")
19763 (match_operand 3 "register_operand" "")))]
19764 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19765 && (GET_MODE (operands[0]) == HImode
19766 || (GET_MODE (operands[0]) == QImode
19767 && (TARGET_PROMOTE_QImode || optimize_size)))"
19768 [(set (match_dup 0)
19769 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19770 "operands[0] = gen_lowpart (SImode, operands[0]);
19771 operands[2] = gen_lowpart (SImode, operands[2]);
19772 operands[3] = gen_lowpart (SImode, operands[3]);")
19775 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19776 ;; transform a complex memory operation into two memory to register operations.
19778 ;; Don't push memory operands
19780 [(set (match_operand:SI 0 "push_operand" "")
19781 (match_operand:SI 1 "memory_operand" ""))
19782 (match_scratch:SI 2 "r")]
19783 "!optimize_size && !TARGET_PUSH_MEMORY
19784 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19785 [(set (match_dup 2) (match_dup 1))
19786 (set (match_dup 0) (match_dup 2))]
19790 [(set (match_operand:DI 0 "push_operand" "")
19791 (match_operand:DI 1 "memory_operand" ""))
19792 (match_scratch:DI 2 "r")]
19793 "!optimize_size && !TARGET_PUSH_MEMORY
19794 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19795 [(set (match_dup 2) (match_dup 1))
19796 (set (match_dup 0) (match_dup 2))]
19799 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19802 [(set (match_operand:SF 0 "push_operand" "")
19803 (match_operand:SF 1 "memory_operand" ""))
19804 (match_scratch:SF 2 "r")]
19805 "!optimize_size && !TARGET_PUSH_MEMORY
19806 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19807 [(set (match_dup 2) (match_dup 1))
19808 (set (match_dup 0) (match_dup 2))]
19812 [(set (match_operand:HI 0 "push_operand" "")
19813 (match_operand:HI 1 "memory_operand" ""))
19814 (match_scratch:HI 2 "r")]
19815 "!optimize_size && !TARGET_PUSH_MEMORY
19816 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19817 [(set (match_dup 2) (match_dup 1))
19818 (set (match_dup 0) (match_dup 2))]
19822 [(set (match_operand:QI 0 "push_operand" "")
19823 (match_operand:QI 1 "memory_operand" ""))
19824 (match_scratch:QI 2 "q")]
19825 "!optimize_size && !TARGET_PUSH_MEMORY
19826 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19827 [(set (match_dup 2) (match_dup 1))
19828 (set (match_dup 0) (match_dup 2))]
19831 ;; Don't move an immediate directly to memory when the instruction
19834 [(match_scratch:SI 1 "r")
19835 (set (match_operand:SI 0 "memory_operand" "")
19838 && ! TARGET_USE_MOV0
19839 && TARGET_SPLIT_LONG_MOVES
19840 && get_attr_length (insn) >= ix86_cost->large_insn
19841 && peep2_regno_dead_p (0, FLAGS_REG)"
19842 [(parallel [(set (match_dup 1) (const_int 0))
19843 (clobber (reg:CC FLAGS_REG))])
19844 (set (match_dup 0) (match_dup 1))]
19848 [(match_scratch:HI 1 "r")
19849 (set (match_operand:HI 0 "memory_operand" "")
19852 && ! TARGET_USE_MOV0
19853 && TARGET_SPLIT_LONG_MOVES
19854 && get_attr_length (insn) >= ix86_cost->large_insn
19855 && peep2_regno_dead_p (0, FLAGS_REG)"
19856 [(parallel [(set (match_dup 2) (const_int 0))
19857 (clobber (reg:CC FLAGS_REG))])
19858 (set (match_dup 0) (match_dup 1))]
19859 "operands[2] = gen_lowpart (SImode, operands[1]);")
19862 [(match_scratch:QI 1 "q")
19863 (set (match_operand:QI 0 "memory_operand" "")
19866 && ! TARGET_USE_MOV0
19867 && TARGET_SPLIT_LONG_MOVES
19868 && get_attr_length (insn) >= ix86_cost->large_insn
19869 && peep2_regno_dead_p (0, FLAGS_REG)"
19870 [(parallel [(set (match_dup 2) (const_int 0))
19871 (clobber (reg:CC FLAGS_REG))])
19872 (set (match_dup 0) (match_dup 1))]
19873 "operands[2] = gen_lowpart (SImode, operands[1]);")
19876 [(match_scratch:SI 2 "r")
19877 (set (match_operand:SI 0 "memory_operand" "")
19878 (match_operand:SI 1 "immediate_operand" ""))]
19880 && get_attr_length (insn) >= ix86_cost->large_insn
19881 && TARGET_SPLIT_LONG_MOVES"
19882 [(set (match_dup 2) (match_dup 1))
19883 (set (match_dup 0) (match_dup 2))]
19887 [(match_scratch:HI 2 "r")
19888 (set (match_operand:HI 0 "memory_operand" "")
19889 (match_operand:HI 1 "immediate_operand" ""))]
19890 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19891 && TARGET_SPLIT_LONG_MOVES"
19892 [(set (match_dup 2) (match_dup 1))
19893 (set (match_dup 0) (match_dup 2))]
19897 [(match_scratch:QI 2 "q")
19898 (set (match_operand:QI 0 "memory_operand" "")
19899 (match_operand:QI 1 "immediate_operand" ""))]
19900 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19901 && TARGET_SPLIT_LONG_MOVES"
19902 [(set (match_dup 2) (match_dup 1))
19903 (set (match_dup 0) (match_dup 2))]
19906 ;; Don't compare memory with zero, load and use a test instead.
19908 [(set (match_operand 0 "flags_reg_operand" "")
19909 (match_operator 1 "compare_operator"
19910 [(match_operand:SI 2 "memory_operand" "")
19912 (match_scratch:SI 3 "r")]
19913 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19914 [(set (match_dup 3) (match_dup 2))
19915 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19918 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19919 ;; Don't split NOTs with a displacement operand, because resulting XOR
19920 ;; will not be pairable anyway.
19922 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19923 ;; represented using a modRM byte. The XOR replacement is long decoded,
19924 ;; so this split helps here as well.
19926 ;; Note: Can't do this as a regular split because we can't get proper
19927 ;; lifetime information then.
19930 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19931 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19933 && peep2_regno_dead_p (0, FLAGS_REG)
19934 && ((TARGET_PENTIUM
19935 && (GET_CODE (operands[0]) != MEM
19936 || !memory_displacement_operand (operands[0], SImode)))
19937 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19938 [(parallel [(set (match_dup 0)
19939 (xor:SI (match_dup 1) (const_int -1)))
19940 (clobber (reg:CC FLAGS_REG))])]
19944 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19945 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19947 && peep2_regno_dead_p (0, FLAGS_REG)
19948 && ((TARGET_PENTIUM
19949 && (GET_CODE (operands[0]) != MEM
19950 || !memory_displacement_operand (operands[0], HImode)))
19951 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19952 [(parallel [(set (match_dup 0)
19953 (xor:HI (match_dup 1) (const_int -1)))
19954 (clobber (reg:CC FLAGS_REG))])]
19958 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19959 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19961 && peep2_regno_dead_p (0, FLAGS_REG)
19962 && ((TARGET_PENTIUM
19963 && (GET_CODE (operands[0]) != MEM
19964 || !memory_displacement_operand (operands[0], QImode)))
19965 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19966 [(parallel [(set (match_dup 0)
19967 (xor:QI (match_dup 1) (const_int -1)))
19968 (clobber (reg:CC FLAGS_REG))])]
19971 ;; Non pairable "test imm, reg" instructions can be translated to
19972 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19973 ;; byte opcode instead of two, have a short form for byte operands),
19974 ;; so do it for other CPUs as well. Given that the value was dead,
19975 ;; this should not create any new dependencies. Pass on the sub-word
19976 ;; versions if we're concerned about partial register stalls.
19979 [(set (match_operand 0 "flags_reg_operand" "")
19980 (match_operator 1 "compare_operator"
19981 [(and:SI (match_operand:SI 2 "register_operand" "")
19982 (match_operand:SI 3 "immediate_operand" ""))
19984 "ix86_match_ccmode (insn, CCNOmode)
19985 && (true_regnum (operands[2]) != 0
19986 || satisfies_constraint_K (operands[3]))
19987 && peep2_reg_dead_p (1, operands[2])"
19989 [(set (match_dup 0)
19990 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19993 (and:SI (match_dup 2) (match_dup 3)))])]
19996 ;; We don't need to handle HImode case, because it will be promoted to SImode
19997 ;; on ! TARGET_PARTIAL_REG_STALL
20000 [(set (match_operand 0 "flags_reg_operand" "")
20001 (match_operator 1 "compare_operator"
20002 [(and:QI (match_operand:QI 2 "register_operand" "")
20003 (match_operand:QI 3 "immediate_operand" ""))
20005 "! TARGET_PARTIAL_REG_STALL
20006 && ix86_match_ccmode (insn, CCNOmode)
20007 && true_regnum (operands[2]) != 0
20008 && peep2_reg_dead_p (1, operands[2])"
20010 [(set (match_dup 0)
20011 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20014 (and:QI (match_dup 2) (match_dup 3)))])]
20018 [(set (match_operand 0 "flags_reg_operand" "")
20019 (match_operator 1 "compare_operator"
20022 (match_operand 2 "ext_register_operand" "")
20025 (match_operand 3 "const_int_operand" ""))
20027 "! TARGET_PARTIAL_REG_STALL
20028 && ix86_match_ccmode (insn, CCNOmode)
20029 && true_regnum (operands[2]) != 0
20030 && peep2_reg_dead_p (1, operands[2])"
20031 [(parallel [(set (match_dup 0)
20040 (set (zero_extract:SI (match_dup 2)
20051 ;; Don't do logical operations with memory inputs.
20053 [(match_scratch:SI 2 "r")
20054 (parallel [(set (match_operand:SI 0 "register_operand" "")
20055 (match_operator:SI 3 "arith_or_logical_operator"
20057 (match_operand:SI 1 "memory_operand" "")]))
20058 (clobber (reg:CC FLAGS_REG))])]
20059 "! optimize_size && ! TARGET_READ_MODIFY"
20060 [(set (match_dup 2) (match_dup 1))
20061 (parallel [(set (match_dup 0)
20062 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20063 (clobber (reg:CC FLAGS_REG))])]
20067 [(match_scratch:SI 2 "r")
20068 (parallel [(set (match_operand:SI 0 "register_operand" "")
20069 (match_operator:SI 3 "arith_or_logical_operator"
20070 [(match_operand:SI 1 "memory_operand" "")
20072 (clobber (reg:CC FLAGS_REG))])]
20073 "! optimize_size && ! TARGET_READ_MODIFY"
20074 [(set (match_dup 2) (match_dup 1))
20075 (parallel [(set (match_dup 0)
20076 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20077 (clobber (reg:CC FLAGS_REG))])]
20080 ; Don't do logical operations with memory outputs
20082 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20083 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20084 ; the same decoder scheduling characteristics as the original.
20087 [(match_scratch:SI 2 "r")
20088 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20089 (match_operator:SI 3 "arith_or_logical_operator"
20091 (match_operand:SI 1 "nonmemory_operand" "")]))
20092 (clobber (reg:CC FLAGS_REG))])]
20093 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20094 [(set (match_dup 2) (match_dup 0))
20095 (parallel [(set (match_dup 2)
20096 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20097 (clobber (reg:CC FLAGS_REG))])
20098 (set (match_dup 0) (match_dup 2))]
20102 [(match_scratch:SI 2 "r")
20103 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20104 (match_operator:SI 3 "arith_or_logical_operator"
20105 [(match_operand:SI 1 "nonmemory_operand" "")
20107 (clobber (reg:CC FLAGS_REG))])]
20108 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20109 [(set (match_dup 2) (match_dup 0))
20110 (parallel [(set (match_dup 2)
20111 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20112 (clobber (reg:CC FLAGS_REG))])
20113 (set (match_dup 0) (match_dup 2))]
20116 ;; Attempt to always use XOR for zeroing registers.
20118 [(set (match_operand 0 "register_operand" "")
20119 (match_operand 1 "const0_operand" ""))]
20120 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20121 && (! TARGET_USE_MOV0 || optimize_size)
20122 && GENERAL_REG_P (operands[0])
20123 && peep2_regno_dead_p (0, FLAGS_REG)"
20124 [(parallel [(set (match_dup 0) (const_int 0))
20125 (clobber (reg:CC FLAGS_REG))])]
20127 operands[0] = gen_lowpart (word_mode, operands[0]);
20131 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20133 "(GET_MODE (operands[0]) == QImode
20134 || GET_MODE (operands[0]) == HImode)
20135 && (! TARGET_USE_MOV0 || optimize_size)
20136 && peep2_regno_dead_p (0, FLAGS_REG)"
20137 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20138 (clobber (reg:CC FLAGS_REG))])])
20140 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20142 [(set (match_operand 0 "register_operand" "")
20144 "(GET_MODE (operands[0]) == HImode
20145 || GET_MODE (operands[0]) == SImode
20146 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20147 && (optimize_size || TARGET_PENTIUM)
20148 && peep2_regno_dead_p (0, FLAGS_REG)"
20149 [(parallel [(set (match_dup 0) (const_int -1))
20150 (clobber (reg:CC FLAGS_REG))])]
20151 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20154 ;; Attempt to convert simple leas to adds. These can be created by
20157 [(set (match_operand:SI 0 "register_operand" "")
20158 (plus:SI (match_dup 0)
20159 (match_operand:SI 1 "nonmemory_operand" "")))]
20160 "peep2_regno_dead_p (0, FLAGS_REG)"
20161 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20162 (clobber (reg:CC FLAGS_REG))])]
20166 [(set (match_operand:SI 0 "register_operand" "")
20167 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20168 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20169 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20170 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20171 (clobber (reg:CC FLAGS_REG))])]
20172 "operands[2] = gen_lowpart (SImode, operands[2]);")
20175 [(set (match_operand:DI 0 "register_operand" "")
20176 (plus:DI (match_dup 0)
20177 (match_operand:DI 1 "x86_64_general_operand" "")))]
20178 "peep2_regno_dead_p (0, FLAGS_REG)"
20179 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20180 (clobber (reg:CC FLAGS_REG))])]
20184 [(set (match_operand:SI 0 "register_operand" "")
20185 (mult:SI (match_dup 0)
20186 (match_operand:SI 1 "const_int_operand" "")))]
20187 "exact_log2 (INTVAL (operands[1])) >= 0
20188 && peep2_regno_dead_p (0, FLAGS_REG)"
20189 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20190 (clobber (reg:CC FLAGS_REG))])]
20191 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20194 [(set (match_operand:DI 0 "register_operand" "")
20195 (mult:DI (match_dup 0)
20196 (match_operand:DI 1 "const_int_operand" "")))]
20197 "exact_log2 (INTVAL (operands[1])) >= 0
20198 && peep2_regno_dead_p (0, FLAGS_REG)"
20199 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20200 (clobber (reg:CC FLAGS_REG))])]
20201 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20204 [(set (match_operand:SI 0 "register_operand" "")
20205 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20206 (match_operand:DI 2 "const_int_operand" "")) 0))]
20207 "exact_log2 (INTVAL (operands[2])) >= 0
20208 && REGNO (operands[0]) == REGNO (operands[1])
20209 && peep2_regno_dead_p (0, FLAGS_REG)"
20210 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20211 (clobber (reg:CC FLAGS_REG))])]
20212 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20214 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20215 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20216 ;; many CPUs it is also faster, since special hardware to avoid esp
20217 ;; dependencies is present.
20219 ;; While some of these conversions may be done using splitters, we use peepholes
20220 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20222 ;; Convert prologue esp subtractions to push.
20223 ;; We need register to push. In order to keep verify_flow_info happy we have
20225 ;; - use scratch and clobber it in order to avoid dependencies
20226 ;; - use already live register
20227 ;; We can't use the second way right now, since there is no reliable way how to
20228 ;; verify that given register is live. First choice will also most likely in
20229 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20230 ;; call clobbered registers are dead. We may want to use base pointer as an
20231 ;; alternative when no register is available later.
20234 [(match_scratch:SI 0 "r")
20235 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20236 (clobber (reg:CC FLAGS_REG))
20237 (clobber (mem:BLK (scratch)))])]
20238 "optimize_size || !TARGET_SUB_ESP_4"
20239 [(clobber (match_dup 0))
20240 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20241 (clobber (mem:BLK (scratch)))])])
20244 [(match_scratch:SI 0 "r")
20245 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20246 (clobber (reg:CC FLAGS_REG))
20247 (clobber (mem:BLK (scratch)))])]
20248 "optimize_size || !TARGET_SUB_ESP_8"
20249 [(clobber (match_dup 0))
20250 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20251 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20252 (clobber (mem:BLK (scratch)))])])
20254 ;; Convert esp subtractions to push.
20256 [(match_scratch:SI 0 "r")
20257 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20258 (clobber (reg:CC FLAGS_REG))])]
20259 "optimize_size || !TARGET_SUB_ESP_4"
20260 [(clobber (match_dup 0))
20261 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20264 [(match_scratch:SI 0 "r")
20265 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20266 (clobber (reg:CC FLAGS_REG))])]
20267 "optimize_size || !TARGET_SUB_ESP_8"
20268 [(clobber (match_dup 0))
20269 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20270 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20272 ;; Convert epilogue deallocator to pop.
20274 [(match_scratch:SI 0 "r")
20275 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20276 (clobber (reg:CC FLAGS_REG))
20277 (clobber (mem:BLK (scratch)))])]
20278 "optimize_size || !TARGET_ADD_ESP_4"
20279 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20280 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20281 (clobber (mem:BLK (scratch)))])]
20284 ;; Two pops case is tricky, since pop causes dependency on destination register.
20285 ;; We use two registers if available.
20287 [(match_scratch:SI 0 "r")
20288 (match_scratch:SI 1 "r")
20289 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20290 (clobber (reg:CC FLAGS_REG))
20291 (clobber (mem:BLK (scratch)))])]
20292 "optimize_size || !TARGET_ADD_ESP_8"
20293 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20294 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20295 (clobber (mem:BLK (scratch)))])
20296 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20297 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20301 [(match_scratch:SI 0 "r")
20302 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20303 (clobber (reg:CC FLAGS_REG))
20304 (clobber (mem:BLK (scratch)))])]
20306 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20307 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20308 (clobber (mem:BLK (scratch)))])
20309 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20310 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20313 ;; Convert esp additions to pop.
20315 [(match_scratch:SI 0 "r")
20316 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20317 (clobber (reg:CC FLAGS_REG))])]
20319 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20320 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20323 ;; Two pops case is tricky, since pop causes dependency on destination register.
20324 ;; We use two registers if available.
20326 [(match_scratch:SI 0 "r")
20327 (match_scratch:SI 1 "r")
20328 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20329 (clobber (reg:CC FLAGS_REG))])]
20331 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20332 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20333 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20334 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20338 [(match_scratch:SI 0 "r")
20339 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20340 (clobber (reg:CC FLAGS_REG))])]
20342 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20343 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20344 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20345 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20348 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20349 ;; required and register dies. Similarly for 128 to plus -128.
20351 [(set (match_operand 0 "flags_reg_operand" "")
20352 (match_operator 1 "compare_operator"
20353 [(match_operand 2 "register_operand" "")
20354 (match_operand 3 "const_int_operand" "")]))]
20355 "(INTVAL (operands[3]) == -1
20356 || INTVAL (operands[3]) == 1
20357 || INTVAL (operands[3]) == 128)
20358 && ix86_match_ccmode (insn, CCGCmode)
20359 && peep2_reg_dead_p (1, operands[2])"
20360 [(parallel [(set (match_dup 0)
20361 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20362 (clobber (match_dup 2))])]
20366 [(match_scratch:DI 0 "r")
20367 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20368 (clobber (reg:CC FLAGS_REG))
20369 (clobber (mem:BLK (scratch)))])]
20370 "optimize_size || !TARGET_SUB_ESP_4"
20371 [(clobber (match_dup 0))
20372 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20373 (clobber (mem:BLK (scratch)))])])
20376 [(match_scratch:DI 0 "r")
20377 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20378 (clobber (reg:CC FLAGS_REG))
20379 (clobber (mem:BLK (scratch)))])]
20380 "optimize_size || !TARGET_SUB_ESP_8"
20381 [(clobber (match_dup 0))
20382 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20383 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20384 (clobber (mem:BLK (scratch)))])])
20386 ;; Convert esp subtractions to push.
20388 [(match_scratch:DI 0 "r")
20389 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20390 (clobber (reg:CC FLAGS_REG))])]
20391 "optimize_size || !TARGET_SUB_ESP_4"
20392 [(clobber (match_dup 0))
20393 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20396 [(match_scratch:DI 0 "r")
20397 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20398 (clobber (reg:CC FLAGS_REG))])]
20399 "optimize_size || !TARGET_SUB_ESP_8"
20400 [(clobber (match_dup 0))
20401 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20402 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20404 ;; Convert epilogue deallocator to pop.
20406 [(match_scratch:DI 0 "r")
20407 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20408 (clobber (reg:CC FLAGS_REG))
20409 (clobber (mem:BLK (scratch)))])]
20410 "optimize_size || !TARGET_ADD_ESP_4"
20411 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20412 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20413 (clobber (mem:BLK (scratch)))])]
20416 ;; Two pops case is tricky, since pop causes dependency on destination register.
20417 ;; We use two registers if available.
20419 [(match_scratch:DI 0 "r")
20420 (match_scratch:DI 1 "r")
20421 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20422 (clobber (reg:CC FLAGS_REG))
20423 (clobber (mem:BLK (scratch)))])]
20424 "optimize_size || !TARGET_ADD_ESP_8"
20425 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20426 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20427 (clobber (mem:BLK (scratch)))])
20428 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20429 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20433 [(match_scratch:DI 0 "r")
20434 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20435 (clobber (reg:CC FLAGS_REG))
20436 (clobber (mem:BLK (scratch)))])]
20438 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20439 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20440 (clobber (mem:BLK (scratch)))])
20441 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20442 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20445 ;; Convert esp additions to pop.
20447 [(match_scratch:DI 0 "r")
20448 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20449 (clobber (reg:CC FLAGS_REG))])]
20451 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20452 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20455 ;; Two pops case is tricky, since pop causes dependency on destination register.
20456 ;; We use two registers if available.
20458 [(match_scratch:DI 0 "r")
20459 (match_scratch:DI 1 "r")
20460 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20461 (clobber (reg:CC FLAGS_REG))])]
20463 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20464 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20465 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20466 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20470 [(match_scratch:DI 0 "r")
20471 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20472 (clobber (reg:CC FLAGS_REG))])]
20474 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20475 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20476 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20477 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20480 ;; Convert imul by three, five and nine into lea
20483 [(set (match_operand:SI 0 "register_operand" "")
20484 (mult:SI (match_operand:SI 1 "register_operand" "")
20485 (match_operand:SI 2 "const_int_operand" "")))
20486 (clobber (reg:CC FLAGS_REG))])]
20487 "INTVAL (operands[2]) == 3
20488 || INTVAL (operands[2]) == 5
20489 || INTVAL (operands[2]) == 9"
20490 [(set (match_dup 0)
20491 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20493 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20497 [(set (match_operand:SI 0 "register_operand" "")
20498 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20499 (match_operand:SI 2 "const_int_operand" "")))
20500 (clobber (reg:CC FLAGS_REG))])]
20502 && (INTVAL (operands[2]) == 3
20503 || INTVAL (operands[2]) == 5
20504 || INTVAL (operands[2]) == 9)"
20505 [(set (match_dup 0) (match_dup 1))
20507 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20509 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20513 [(set (match_operand:DI 0 "register_operand" "")
20514 (mult:DI (match_operand:DI 1 "register_operand" "")
20515 (match_operand:DI 2 "const_int_operand" "")))
20516 (clobber (reg:CC FLAGS_REG))])]
20518 && (INTVAL (operands[2]) == 3
20519 || INTVAL (operands[2]) == 5
20520 || INTVAL (operands[2]) == 9)"
20521 [(set (match_dup 0)
20522 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20524 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20528 [(set (match_operand:DI 0 "register_operand" "")
20529 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20530 (match_operand:DI 2 "const_int_operand" "")))
20531 (clobber (reg:CC FLAGS_REG))])]
20534 && (INTVAL (operands[2]) == 3
20535 || INTVAL (operands[2]) == 5
20536 || INTVAL (operands[2]) == 9)"
20537 [(set (match_dup 0) (match_dup 1))
20539 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20541 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20543 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20544 ;; imul $32bit_imm, reg, reg is direct decoded.
20546 [(match_scratch:DI 3 "r")
20547 (parallel [(set (match_operand:DI 0 "register_operand" "")
20548 (mult:DI (match_operand:DI 1 "memory_operand" "")
20549 (match_operand:DI 2 "immediate_operand" "")))
20550 (clobber (reg:CC FLAGS_REG))])]
20551 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20552 && !satisfies_constraint_K (operands[2])"
20553 [(set (match_dup 3) (match_dup 1))
20554 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20555 (clobber (reg:CC FLAGS_REG))])]
20559 [(match_scratch:SI 3 "r")
20560 (parallel [(set (match_operand:SI 0 "register_operand" "")
20561 (mult:SI (match_operand:SI 1 "memory_operand" "")
20562 (match_operand:SI 2 "immediate_operand" "")))
20563 (clobber (reg:CC FLAGS_REG))])]
20564 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20565 && !satisfies_constraint_K (operands[2])"
20566 [(set (match_dup 3) (match_dup 1))
20567 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20568 (clobber (reg:CC FLAGS_REG))])]
20572 [(match_scratch:SI 3 "r")
20573 (parallel [(set (match_operand:DI 0 "register_operand" "")
20575 (mult:SI (match_operand:SI 1 "memory_operand" "")
20576 (match_operand:SI 2 "immediate_operand" ""))))
20577 (clobber (reg:CC FLAGS_REG))])]
20578 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20579 && !satisfies_constraint_K (operands[2])"
20580 [(set (match_dup 3) (match_dup 1))
20581 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20582 (clobber (reg:CC FLAGS_REG))])]
20585 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20586 ;; Convert it into imul reg, reg
20587 ;; It would be better to force assembler to encode instruction using long
20588 ;; immediate, but there is apparently no way to do so.
20590 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20591 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20592 (match_operand:DI 2 "const_int_operand" "")))
20593 (clobber (reg:CC FLAGS_REG))])
20594 (match_scratch:DI 3 "r")]
20595 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20596 && satisfies_constraint_K (operands[2])"
20597 [(set (match_dup 3) (match_dup 2))
20598 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20599 (clobber (reg:CC FLAGS_REG))])]
20601 if (!rtx_equal_p (operands[0], operands[1]))
20602 emit_move_insn (operands[0], operands[1]);
20606 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20607 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20608 (match_operand:SI 2 "const_int_operand" "")))
20609 (clobber (reg:CC FLAGS_REG))])
20610 (match_scratch:SI 3 "r")]
20611 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20612 && satisfies_constraint_K (operands[2])"
20613 [(set (match_dup 3) (match_dup 2))
20614 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20615 (clobber (reg:CC FLAGS_REG))])]
20617 if (!rtx_equal_p (operands[0], operands[1]))
20618 emit_move_insn (operands[0], operands[1]);
20622 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20623 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20624 (match_operand:HI 2 "immediate_operand" "")))
20625 (clobber (reg:CC FLAGS_REG))])
20626 (match_scratch:HI 3 "r")]
20627 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20628 [(set (match_dup 3) (match_dup 2))
20629 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20630 (clobber (reg:CC FLAGS_REG))])]
20632 if (!rtx_equal_p (operands[0], operands[1]))
20633 emit_move_insn (operands[0], operands[1]);
20636 ;; After splitting up read-modify operations, array accesses with memory
20637 ;; operands might end up in form:
20639 ;; movl 4(%esp), %edx
20641 ;; instead of pre-splitting:
20643 ;; addl 4(%esp), %eax
20645 ;; movl 4(%esp), %edx
20646 ;; leal (%edx,%eax,4), %eax
20649 [(parallel [(set (match_operand 0 "register_operand" "")
20650 (ashift (match_operand 1 "register_operand" "")
20651 (match_operand 2 "const_int_operand" "")))
20652 (clobber (reg:CC FLAGS_REG))])
20653 (set (match_operand 3 "register_operand")
20654 (match_operand 4 "x86_64_general_operand" ""))
20655 (parallel [(set (match_operand 5 "register_operand" "")
20656 (plus (match_operand 6 "register_operand" "")
20657 (match_operand 7 "register_operand" "")))
20658 (clobber (reg:CC FLAGS_REG))])]
20659 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20660 /* Validate MODE for lea. */
20661 && ((!TARGET_PARTIAL_REG_STALL
20662 && (GET_MODE (operands[0]) == QImode
20663 || GET_MODE (operands[0]) == HImode))
20664 || GET_MODE (operands[0]) == SImode
20665 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20666 /* We reorder load and the shift. */
20667 && !rtx_equal_p (operands[1], operands[3])
20668 && !reg_overlap_mentioned_p (operands[0], operands[4])
20669 /* Last PLUS must consist of operand 0 and 3. */
20670 && !rtx_equal_p (operands[0], operands[3])
20671 && (rtx_equal_p (operands[3], operands[6])
20672 || rtx_equal_p (operands[3], operands[7]))
20673 && (rtx_equal_p (operands[0], operands[6])
20674 || rtx_equal_p (operands[0], operands[7]))
20675 /* The intermediate operand 0 must die or be same as output. */
20676 && (rtx_equal_p (operands[0], operands[5])
20677 || peep2_reg_dead_p (3, operands[0]))"
20678 [(set (match_dup 3) (match_dup 4))
20679 (set (match_dup 0) (match_dup 1))]
20681 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20682 int scale = 1 << INTVAL (operands[2]);
20683 rtx index = gen_lowpart (Pmode, operands[1]);
20684 rtx base = gen_lowpart (Pmode, operands[3]);
20685 rtx dest = gen_lowpart (mode, operands[5]);
20687 operands[1] = gen_rtx_PLUS (Pmode, base,
20688 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20690 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20691 operands[0] = dest;
20694 ;; Call-value patterns last so that the wildcard operand does not
20695 ;; disrupt insn-recog's switch tables.
20697 (define_insn "*call_value_pop_0"
20698 [(set (match_operand 0 "" "")
20699 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20700 (match_operand:SI 2 "" "")))
20701 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20702 (match_operand:SI 3 "immediate_operand" "")))]
20705 if (SIBLING_CALL_P (insn))
20708 return "call\t%P1";
20710 [(set_attr "type" "callv")])
20712 (define_insn "*call_value_pop_1"
20713 [(set (match_operand 0 "" "")
20714 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20715 (match_operand:SI 2 "" "")))
20716 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20717 (match_operand:SI 3 "immediate_operand" "i")))]
20720 if (constant_call_address_operand (operands[1], Pmode))
20722 if (SIBLING_CALL_P (insn))
20725 return "call\t%P1";
20727 if (SIBLING_CALL_P (insn))
20730 return "call\t%A1";
20732 [(set_attr "type" "callv")])
20734 (define_insn "*call_value_0"
20735 [(set (match_operand 0 "" "")
20736 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20737 (match_operand:SI 2 "" "")))]
20740 if (SIBLING_CALL_P (insn))
20743 return "call\t%P1";
20745 [(set_attr "type" "callv")])
20747 (define_insn "*call_value_0_rex64"
20748 [(set (match_operand 0 "" "")
20749 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20750 (match_operand:DI 2 "const_int_operand" "")))]
20753 if (SIBLING_CALL_P (insn))
20756 return "call\t%P1";
20758 [(set_attr "type" "callv")])
20760 (define_insn "*call_value_1"
20761 [(set (match_operand 0 "" "")
20762 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20763 (match_operand:SI 2 "" "")))]
20764 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20766 if (constant_call_address_operand (operands[1], Pmode))
20767 return "call\t%P1";
20768 return "call\t%A1";
20770 [(set_attr "type" "callv")])
20772 (define_insn "*sibcall_value_1"
20773 [(set (match_operand 0 "" "")
20774 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20775 (match_operand:SI 2 "" "")))]
20776 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20778 if (constant_call_address_operand (operands[1], Pmode))
20782 [(set_attr "type" "callv")])
20784 (define_insn "*call_value_1_rex64"
20785 [(set (match_operand 0 "" "")
20786 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20787 (match_operand:DI 2 "" "")))]
20788 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20790 if (constant_call_address_operand (operands[1], Pmode))
20791 return "call\t%P1";
20792 return "call\t%A1";
20794 [(set_attr "type" "callv")])
20796 (define_insn "*sibcall_value_1_rex64"
20797 [(set (match_operand 0 "" "")
20798 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20799 (match_operand:DI 2 "" "")))]
20800 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20802 [(set_attr "type" "callv")])
20804 (define_insn "*sibcall_value_1_rex64_v"
20805 [(set (match_operand 0 "" "")
20806 (call (mem:QI (reg:DI R11_REG))
20807 (match_operand:DI 1 "" "")))]
20808 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20810 [(set_attr "type" "callv")])
20812 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20813 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20814 ;; caught for use by garbage collectors and the like. Using an insn that
20815 ;; maps to SIGILL makes it more likely the program will rightfully die.
20816 ;; Keeping with tradition, "6" is in honor of #UD.
20817 (define_insn "trap"
20818 [(trap_if (const_int 1) (const_int 6))]
20820 { return ASM_SHORT "0x0b0f"; }
20821 [(set_attr "length" "2")])
20823 (define_expand "sse_prologue_save"
20824 [(parallel [(set (match_operand:BLK 0 "" "")
20825 (unspec:BLK [(reg:DI 22)
20832 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20833 (use (match_operand:DI 1 "register_operand" ""))
20834 (use (match_operand:DI 2 "immediate_operand" ""))
20835 (use (label_ref:DI (match_operand 3 "" "")))])]
20839 (define_insn "*sse_prologue_save_insn"
20840 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20841 (match_operand:DI 4 "const_int_operand" "n")))
20842 (unspec:BLK [(reg:DI 22)
20849 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20850 (use (match_operand:DI 1 "register_operand" "r"))
20851 (use (match_operand:DI 2 "const_int_operand" "i"))
20852 (use (label_ref:DI (match_operand 3 "" "X")))]
20854 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20855 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20859 operands[0] = gen_rtx_MEM (Pmode,
20860 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20861 output_asm_insn (\"jmp\\t%A1\", operands);
20862 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20864 operands[4] = adjust_address (operands[0], DImode, i*16);
20865 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20866 PUT_MODE (operands[4], TImode);
20867 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20868 output_asm_insn (\"rex\", operands);
20869 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20871 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20872 CODE_LABEL_NUMBER (operands[3]));
20876 [(set_attr "type" "other")
20877 (set_attr "length_immediate" "0")
20878 (set_attr "length_address" "0")
20879 (set_attr "length" "135")
20880 (set_attr "memory" "store")
20881 (set_attr "modrm" "0")
20882 (set_attr "mode" "DI")])
20884 (define_expand "prefetch"
20885 [(prefetch (match_operand 0 "address_operand" "")
20886 (match_operand:SI 1 "const_int_operand" "")
20887 (match_operand:SI 2 "const_int_operand" ""))]
20888 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20890 int rw = INTVAL (operands[1]);
20891 int locality = INTVAL (operands[2]);
20893 gcc_assert (rw == 0 || rw == 1);
20894 gcc_assert (locality >= 0 && locality <= 3);
20895 gcc_assert (GET_MODE (operands[0]) == Pmode
20896 || GET_MODE (operands[0]) == VOIDmode);
20898 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20899 supported by SSE counterpart or the SSE prefetch is not available
20900 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20902 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20903 operands[2] = GEN_INT (3);
20905 operands[1] = const0_rtx;
20908 (define_insn "*prefetch_sse"
20909 [(prefetch (match_operand:SI 0 "address_operand" "p")
20911 (match_operand:SI 1 "const_int_operand" ""))]
20912 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20914 static const char * const patterns[4] = {
20915 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20918 int locality = INTVAL (operands[1]);
20919 gcc_assert (locality >= 0 && locality <= 3);
20921 return patterns[locality];
20923 [(set_attr "type" "sse")
20924 (set_attr "memory" "none")])
20926 (define_insn "*prefetch_sse_rex"
20927 [(prefetch (match_operand:DI 0 "address_operand" "p")
20929 (match_operand:SI 1 "const_int_operand" ""))]
20930 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20932 static const char * const patterns[4] = {
20933 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20936 int locality = INTVAL (operands[1]);
20937 gcc_assert (locality >= 0 && locality <= 3);
20939 return patterns[locality];
20941 [(set_attr "type" "sse")
20942 (set_attr "memory" "none")])
20944 (define_insn "*prefetch_3dnow"
20945 [(prefetch (match_operand:SI 0 "address_operand" "p")
20946 (match_operand:SI 1 "const_int_operand" "n")
20948 "TARGET_3DNOW && !TARGET_64BIT"
20950 if (INTVAL (operands[1]) == 0)
20951 return "prefetch\t%a0";
20953 return "prefetchw\t%a0";
20955 [(set_attr "type" "mmx")
20956 (set_attr "memory" "none")])
20958 (define_insn "*prefetch_3dnow_rex"
20959 [(prefetch (match_operand:DI 0 "address_operand" "p")
20960 (match_operand:SI 1 "const_int_operand" "n")
20962 "TARGET_3DNOW && TARGET_64BIT"
20964 if (INTVAL (operands[1]) == 0)
20965 return "prefetch\t%a0";
20967 return "prefetchw\t%a0";
20969 [(set_attr "type" "mmx")
20970 (set_attr "memory" "none")])
20972 (define_expand "stack_protect_set"
20973 [(match_operand 0 "memory_operand" "")
20974 (match_operand 1 "memory_operand" "")]
20977 #ifdef TARGET_THREAD_SSP_OFFSET
20979 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20980 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20982 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20983 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20986 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20988 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20993 (define_insn "stack_protect_set_si"
20994 [(set (match_operand:SI 0 "memory_operand" "=m")
20995 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20996 (set (match_scratch:SI 2 "=&r") (const_int 0))
20997 (clobber (reg:CC FLAGS_REG))]
20999 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21000 [(set_attr "type" "multi")])
21002 (define_insn "stack_protect_set_di"
21003 [(set (match_operand:DI 0 "memory_operand" "=m")
21004 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21005 (set (match_scratch:DI 2 "=&r") (const_int 0))
21006 (clobber (reg:CC FLAGS_REG))]
21008 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21009 [(set_attr "type" "multi")])
21011 (define_insn "stack_tls_protect_set_si"
21012 [(set (match_operand:SI 0 "memory_operand" "=m")
21013 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21014 (set (match_scratch:SI 2 "=&r") (const_int 0))
21015 (clobber (reg:CC FLAGS_REG))]
21017 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21018 [(set_attr "type" "multi")])
21020 (define_insn "stack_tls_protect_set_di"
21021 [(set (match_operand:DI 0 "memory_operand" "=m")
21022 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21023 (set (match_scratch:DI 2 "=&r") (const_int 0))
21024 (clobber (reg:CC FLAGS_REG))]
21027 /* The kernel uses a different segment register for performance reasons; a
21028 system call would not have to trash the userspace segment register,
21029 which would be expensive */
21030 if (ix86_cmodel != CM_KERNEL)
21031 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21033 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21035 [(set_attr "type" "multi")])
21037 (define_expand "stack_protect_test"
21038 [(match_operand 0 "memory_operand" "")
21039 (match_operand 1 "memory_operand" "")
21040 (match_operand 2 "" "")]
21043 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21044 ix86_compare_op0 = operands[0];
21045 ix86_compare_op1 = operands[1];
21046 ix86_compare_emitted = flags;
21048 #ifdef TARGET_THREAD_SSP_OFFSET
21050 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21051 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21053 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21054 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21057 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21059 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21061 emit_jump_insn (gen_beq (operands[2]));
21065 (define_insn "stack_protect_test_si"
21066 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21067 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21068 (match_operand:SI 2 "memory_operand" "m")]
21070 (clobber (match_scratch:SI 3 "=&r"))]
21072 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21073 [(set_attr "type" "multi")])
21075 (define_insn "stack_protect_test_di"
21076 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21077 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21078 (match_operand:DI 2 "memory_operand" "m")]
21080 (clobber (match_scratch:DI 3 "=&r"))]
21082 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21083 [(set_attr "type" "multi")])
21085 (define_insn "stack_tls_protect_test_si"
21086 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21087 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21088 (match_operand:SI 2 "const_int_operand" "i")]
21089 UNSPEC_SP_TLS_TEST))
21090 (clobber (match_scratch:SI 3 "=r"))]
21092 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21093 [(set_attr "type" "multi")])
21095 (define_insn "stack_tls_protect_test_di"
21096 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21097 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21098 (match_operand:DI 2 "const_int_operand" "i")]
21099 UNSPEC_SP_TLS_TEST))
21100 (clobber (match_scratch:DI 3 "=r"))]
21103 /* The kernel uses a different segment register for performance reasons; a
21104 system call would not have to trash the userspace segment register,
21105 which would be expensive */
21106 if (ix86_cmodel != CM_KERNEL)
21107 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21109 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21111 [(set_attr "type" "multi")])
21115 (include "sync.md")