1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
73 (UNSPEC_TLS_LD_BASE 17)
75 ; Other random patterns
85 ; For SSE/MMX support:
86 (UNSPEC_FIX_NOTRUNC 30)
94 (UNSPEC_NOP 38) ; prevents combiner cleverness
105 ; Generic math support
107 (UNSPEC_IEEE_MIN 51) ; not commutative
108 (UNSPEC_IEEE_MAX 52) ; not commutative
121 (UNSPEC_FRNDINT_FLOOR 70)
122 (UNSPEC_FRNDINT_CEIL 71)
123 (UNSPEC_FRNDINT_TRUNC 72)
124 (UNSPEC_FRNDINT_MASK_PM 73)
125 (UNSPEC_FIST_FLOOR 74)
126 (UNSPEC_FIST_CEIL 75)
128 ; x87 Double output FP
129 (UNSPEC_SINCOS_COS 80)
130 (UNSPEC_SINCOS_SIN 81)
133 (UNSPEC_XTRACT_FRACT 84)
134 (UNSPEC_XTRACT_EXP 85)
135 (UNSPEC_FSCALE_FRACT 86)
136 (UNSPEC_FSCALE_EXP 87)
145 (UNSPEC_SP_TLS_SET 102)
146 (UNSPEC_SP_TLS_TEST 103)
150 [(UNSPECV_BLOCKAGE 0)
151 (UNSPECV_STACK_PROBE 1)
160 (UNSPECV_CMPXCHG_1 10)
161 (UNSPECV_CMPXCHG_2 11)
166 ;; Registers by name.
175 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
178 ;; In C guard expressions, put expressions which may be compile-time
179 ;; constants first. This allows for better optimization. For
180 ;; example, write "TARGET_64BIT && reload_completed", not
181 ;; "reload_completed && TARGET_64BIT".
184 ;; Processor type. This attribute must exactly match the processor_type
185 ;; enumeration in i386.h.
186 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
187 (const (symbol_ref "ix86_tune")))
189 ;; A basic instruction type. Refinements due to arguments to be
190 ;; provided in other attributes.
193 alu,alu1,negnot,imov,imovx,lea,
194 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
195 icmp,test,ibr,setcc,icmov,
196 push,pop,call,callv,leave,
198 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
199 sselog,sselog1,sseiadd,sseishft,sseimul,
200 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
201 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
202 (const_string "other"))
204 ;; Main data type used by the insn
206 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
207 (const_string "unknown"))
209 ;; The CPU unit operations uses.
210 (define_attr "unit" "integer,i387,sse,mmx,unknown"
211 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
212 (const_string "i387")
213 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
214 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
216 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
218 (eq_attr "type" "other")
219 (const_string "unknown")]
220 (const_string "integer")))
222 ;; The (bounding maximum) length of an instruction immediate.
223 (define_attr "length_immediate" ""
224 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
226 (eq_attr "unit" "i387,sse,mmx")
228 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
230 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
231 (eq_attr "type" "imov,test")
232 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
233 (eq_attr "type" "call")
234 (if_then_else (match_operand 0 "constant_call_address_operand" "")
237 (eq_attr "type" "callv")
238 (if_then_else (match_operand 1 "constant_call_address_operand" "")
241 ;; We don't know the size before shorten_branches. Expect
242 ;; the instruction to fit for better scheduling.
243 (eq_attr "type" "ibr")
246 (symbol_ref "/* Update immediate_length and other attributes! */
247 gcc_unreachable (),1")))
249 ;; The (bounding maximum) length of an instruction address.
250 (define_attr "length_address" ""
251 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
253 (and (eq_attr "type" "call")
254 (match_operand 0 "constant_call_address_operand" ""))
256 (and (eq_attr "type" "callv")
257 (match_operand 1 "constant_call_address_operand" ""))
260 (symbol_ref "ix86_attr_length_address_default (insn)")))
262 ;; Set when length prefix is used.
263 (define_attr "prefix_data16" ""
264 (if_then_else (ior (eq_attr "mode" "HI")
265 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
269 ;; Set when string REP prefix is used.
270 (define_attr "prefix_rep" ""
271 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
275 ;; Set when 0f opcode prefix is used.
276 (define_attr "prefix_0f" ""
278 (ior (eq_attr "type" "imovx,setcc,icmov")
279 (eq_attr "unit" "sse,mmx"))
283 ;; Set when REX opcode prefix is used.
284 (define_attr "prefix_rex" ""
285 (cond [(and (eq_attr "mode" "DI")
286 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
288 (and (eq_attr "mode" "QI")
289 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
292 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
298 ;; Set when modrm byte is used.
299 (define_attr "modrm" ""
300 (cond [(eq_attr "type" "str,cld,leave")
302 (eq_attr "unit" "i387")
304 (and (eq_attr "type" "incdec")
305 (ior (match_operand:SI 1 "register_operand" "")
306 (match_operand:HI 1 "register_operand" "")))
308 (and (eq_attr "type" "push")
309 (not (match_operand 1 "memory_operand" "")))
311 (and (eq_attr "type" "pop")
312 (not (match_operand 0 "memory_operand" "")))
314 (and (eq_attr "type" "imov")
315 (and (match_operand 0 "register_operand" "")
316 (match_operand 1 "immediate_operand" "")))
318 (and (eq_attr "type" "call")
319 (match_operand 0 "constant_call_address_operand" ""))
321 (and (eq_attr "type" "callv")
322 (match_operand 1 "constant_call_address_operand" ""))
327 ;; The (bounding maximum) length of an instruction in bytes.
328 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
329 ;; Later we may want to split them and compute proper length as for
331 (define_attr "length" ""
332 (cond [(eq_attr "type" "other,multi,fistp,frndint")
334 (eq_attr "type" "fcmp")
336 (eq_attr "unit" "i387")
338 (plus (attr "prefix_data16")
339 (attr "length_address")))]
340 (plus (plus (attr "modrm")
341 (plus (attr "prefix_0f")
342 (plus (attr "prefix_rex")
344 (plus (attr "prefix_rep")
345 (plus (attr "prefix_data16")
346 (plus (attr "length_immediate")
347 (attr "length_address")))))))
349 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
350 ;; `store' if there is a simple memory reference therein, or `unknown'
351 ;; if the instruction is complex.
353 (define_attr "memory" "none,load,store,both,unknown"
354 (cond [(eq_attr "type" "other,multi,str")
355 (const_string "unknown")
356 (eq_attr "type" "lea,fcmov,fpspc,cld")
357 (const_string "none")
358 (eq_attr "type" "fistp,leave")
359 (const_string "both")
360 (eq_attr "type" "frndint")
361 (const_string "load")
362 (eq_attr "type" "push")
363 (if_then_else (match_operand 1 "memory_operand" "")
364 (const_string "both")
365 (const_string "store"))
366 (eq_attr "type" "pop")
367 (if_then_else (match_operand 0 "memory_operand" "")
368 (const_string "both")
369 (const_string "load"))
370 (eq_attr "type" "setcc")
371 (if_then_else (match_operand 0 "memory_operand" "")
372 (const_string "store")
373 (const_string "none"))
374 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
375 (if_then_else (ior (match_operand 0 "memory_operand" "")
376 (match_operand 1 "memory_operand" ""))
377 (const_string "load")
378 (const_string "none"))
379 (eq_attr "type" "ibr")
380 (if_then_else (match_operand 0 "memory_operand" "")
381 (const_string "load")
382 (const_string "none"))
383 (eq_attr "type" "call")
384 (if_then_else (match_operand 0 "constant_call_address_operand" "")
385 (const_string "none")
386 (const_string "load"))
387 (eq_attr "type" "callv")
388 (if_then_else (match_operand 1 "constant_call_address_operand" "")
389 (const_string "none")
390 (const_string "load"))
391 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
392 (match_operand 1 "memory_operand" ""))
393 (const_string "both")
394 (and (match_operand 0 "memory_operand" "")
395 (match_operand 1 "memory_operand" ""))
396 (const_string "both")
397 (match_operand 0 "memory_operand" "")
398 (const_string "store")
399 (match_operand 1 "memory_operand" "")
400 (const_string "load")
402 "!alu1,negnot,ishift1,
403 imov,imovx,icmp,test,
405 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
406 mmx,mmxmov,mmxcmp,mmxcvt")
407 (match_operand 2 "memory_operand" ""))
408 (const_string "load")
409 (and (eq_attr "type" "icmov")
410 (match_operand 3 "memory_operand" ""))
411 (const_string "load")
413 (const_string "none")))
415 ;; Indicates if an instruction has both an immediate and a displacement.
417 (define_attr "imm_disp" "false,true,unknown"
418 (cond [(eq_attr "type" "other,multi")
419 (const_string "unknown")
420 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
421 (and (match_operand 0 "memory_displacement_operand" "")
422 (match_operand 1 "immediate_operand" "")))
423 (const_string "true")
424 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
425 (and (match_operand 0 "memory_displacement_operand" "")
426 (match_operand 2 "immediate_operand" "")))
427 (const_string "true")
429 (const_string "false")))
431 ;; Indicates if an FP operation has an integer source.
433 (define_attr "fp_int_src" "false,true"
434 (const_string "false"))
436 ;; Defines rounding mode of an FP operation.
438 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
439 (const_string "any"))
441 ;; Describe a user's asm statement.
442 (define_asm_attributes
443 [(set_attr "length" "128")
444 (set_attr "type" "multi")])
446 ;; All x87 floating point modes
447 (define_mode_macro X87MODEF [SF DF XF])
449 ;; All integer modes handled by x87 fisttp operator.
450 (define_mode_macro X87MODEI [HI SI DI])
452 ;; All integer modes handled by integer x87 operators.
453 (define_mode_macro X87MODEI12 [HI SI])
455 ;; All SSE floating point modes
456 (define_mode_macro SSEMODEF [SF DF])
458 ;; All integer modes handled by SSE cvtts?2si* operators.
459 (define_mode_macro SSEMODEI24 [SI DI])
462 ;; Scheduling descriptions
464 (include "pentium.md")
467 (include "athlon.md")
470 ;; Operand and operator predicates
472 (include "predicates.md")
475 ;; Compare instructions.
477 ;; All compare insns have expanders that save the operands away without
478 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
479 ;; after the cmp) will actually emit the cmpM.
481 (define_expand "cmpti"
482 [(set (reg:CC FLAGS_REG)
483 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
484 (match_operand:TI 1 "x86_64_general_operand" "")))]
487 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
488 operands[0] = force_reg (TImode, operands[0]);
489 ix86_compare_op0 = operands[0];
490 ix86_compare_op1 = operands[1];
494 (define_expand "cmpdi"
495 [(set (reg:CC FLAGS_REG)
496 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
497 (match_operand:DI 1 "x86_64_general_operand" "")))]
500 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
501 operands[0] = force_reg (DImode, operands[0]);
502 ix86_compare_op0 = operands[0];
503 ix86_compare_op1 = operands[1];
507 (define_expand "cmpsi"
508 [(set (reg:CC FLAGS_REG)
509 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
510 (match_operand:SI 1 "general_operand" "")))]
513 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
514 operands[0] = force_reg (SImode, operands[0]);
515 ix86_compare_op0 = operands[0];
516 ix86_compare_op1 = operands[1];
520 (define_expand "cmphi"
521 [(set (reg:CC FLAGS_REG)
522 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
523 (match_operand:HI 1 "general_operand" "")))]
526 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
527 operands[0] = force_reg (HImode, operands[0]);
528 ix86_compare_op0 = operands[0];
529 ix86_compare_op1 = operands[1];
533 (define_expand "cmpqi"
534 [(set (reg:CC FLAGS_REG)
535 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
536 (match_operand:QI 1 "general_operand" "")))]
539 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
540 operands[0] = force_reg (QImode, operands[0]);
541 ix86_compare_op0 = operands[0];
542 ix86_compare_op1 = operands[1];
546 (define_insn "cmpdi_ccno_1_rex64"
547 [(set (reg FLAGS_REG)
548 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
549 (match_operand:DI 1 "const0_operand" "n,n")))]
550 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
552 test{q}\t{%0, %0|%0, %0}
553 cmp{q}\t{%1, %0|%0, %1}"
554 [(set_attr "type" "test,icmp")
555 (set_attr "length_immediate" "0,1")
556 (set_attr "mode" "DI")])
558 (define_insn "*cmpdi_minus_1_rex64"
559 [(set (reg FLAGS_REG)
560 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
561 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
563 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
564 "cmp{q}\t{%1, %0|%0, %1}"
565 [(set_attr "type" "icmp")
566 (set_attr "mode" "DI")])
568 (define_expand "cmpdi_1_rex64"
569 [(set (reg:CC FLAGS_REG)
570 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
571 (match_operand:DI 1 "general_operand" "")))]
575 (define_insn "cmpdi_1_insn_rex64"
576 [(set (reg FLAGS_REG)
577 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
578 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
579 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
580 "cmp{q}\t{%1, %0|%0, %1}"
581 [(set_attr "type" "icmp")
582 (set_attr "mode" "DI")])
585 (define_insn "*cmpsi_ccno_1"
586 [(set (reg FLAGS_REG)
587 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
588 (match_operand:SI 1 "const0_operand" "n,n")))]
589 "ix86_match_ccmode (insn, CCNOmode)"
591 test{l}\t{%0, %0|%0, %0}
592 cmp{l}\t{%1, %0|%0, %1}"
593 [(set_attr "type" "test,icmp")
594 (set_attr "length_immediate" "0,1")
595 (set_attr "mode" "SI")])
597 (define_insn "*cmpsi_minus_1"
598 [(set (reg FLAGS_REG)
599 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
600 (match_operand:SI 1 "general_operand" "ri,mr"))
602 "ix86_match_ccmode (insn, CCGOCmode)"
603 "cmp{l}\t{%1, %0|%0, %1}"
604 [(set_attr "type" "icmp")
605 (set_attr "mode" "SI")])
607 (define_expand "cmpsi_1"
608 [(set (reg:CC FLAGS_REG)
609 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
610 (match_operand:SI 1 "general_operand" "ri,mr")))]
614 (define_insn "*cmpsi_1_insn"
615 [(set (reg FLAGS_REG)
616 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
617 (match_operand:SI 1 "general_operand" "ri,mr")))]
618 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
619 && ix86_match_ccmode (insn, CCmode)"
620 "cmp{l}\t{%1, %0|%0, %1}"
621 [(set_attr "type" "icmp")
622 (set_attr "mode" "SI")])
624 (define_insn "*cmphi_ccno_1"
625 [(set (reg FLAGS_REG)
626 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
627 (match_operand:HI 1 "const0_operand" "n,n")))]
628 "ix86_match_ccmode (insn, CCNOmode)"
630 test{w}\t{%0, %0|%0, %0}
631 cmp{w}\t{%1, %0|%0, %1}"
632 [(set_attr "type" "test,icmp")
633 (set_attr "length_immediate" "0,1")
634 (set_attr "mode" "HI")])
636 (define_insn "*cmphi_minus_1"
637 [(set (reg FLAGS_REG)
638 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
639 (match_operand:HI 1 "general_operand" "ri,mr"))
641 "ix86_match_ccmode (insn, CCGOCmode)"
642 "cmp{w}\t{%1, %0|%0, %1}"
643 [(set_attr "type" "icmp")
644 (set_attr "mode" "HI")])
646 (define_insn "*cmphi_1"
647 [(set (reg FLAGS_REG)
648 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
649 (match_operand:HI 1 "general_operand" "ri,mr")))]
650 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
651 && ix86_match_ccmode (insn, CCmode)"
652 "cmp{w}\t{%1, %0|%0, %1}"
653 [(set_attr "type" "icmp")
654 (set_attr "mode" "HI")])
656 (define_insn "*cmpqi_ccno_1"
657 [(set (reg FLAGS_REG)
658 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
659 (match_operand:QI 1 "const0_operand" "n,n")))]
660 "ix86_match_ccmode (insn, CCNOmode)"
662 test{b}\t{%0, %0|%0, %0}
663 cmp{b}\t{$0, %0|%0, 0}"
664 [(set_attr "type" "test,icmp")
665 (set_attr "length_immediate" "0,1")
666 (set_attr "mode" "QI")])
668 (define_insn "*cmpqi_1"
669 [(set (reg FLAGS_REG)
670 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
671 (match_operand:QI 1 "general_operand" "qi,mq")))]
672 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
673 && ix86_match_ccmode (insn, CCmode)"
674 "cmp{b}\t{%1, %0|%0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "QI")])
678 (define_insn "*cmpqi_minus_1"
679 [(set (reg FLAGS_REG)
680 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
681 (match_operand:QI 1 "general_operand" "qi,mq"))
683 "ix86_match_ccmode (insn, CCGOCmode)"
684 "cmp{b}\t{%1, %0|%0, %1}"
685 [(set_attr "type" "icmp")
686 (set_attr "mode" "QI")])
688 (define_insn "*cmpqi_ext_1"
689 [(set (reg FLAGS_REG)
691 (match_operand:QI 0 "general_operand" "Qm")
694 (match_operand 1 "ext_register_operand" "Q")
697 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
698 "cmp{b}\t{%h1, %0|%0, %h1}"
699 [(set_attr "type" "icmp")
700 (set_attr "mode" "QI")])
702 (define_insn "*cmpqi_ext_1_rex64"
703 [(set (reg FLAGS_REG)
705 (match_operand:QI 0 "register_operand" "Q")
708 (match_operand 1 "ext_register_operand" "Q")
711 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
712 "cmp{b}\t{%h1, %0|%0, %h1}"
713 [(set_attr "type" "icmp")
714 (set_attr "mode" "QI")])
716 (define_insn "*cmpqi_ext_2"
717 [(set (reg FLAGS_REG)
721 (match_operand 0 "ext_register_operand" "Q")
724 (match_operand:QI 1 "const0_operand" "n")))]
725 "ix86_match_ccmode (insn, CCNOmode)"
727 [(set_attr "type" "test")
728 (set_attr "length_immediate" "0")
729 (set_attr "mode" "QI")])
731 (define_expand "cmpqi_ext_3"
732 [(set (reg:CC FLAGS_REG)
736 (match_operand 0 "ext_register_operand" "")
739 (match_operand:QI 1 "general_operand" "")))]
743 (define_insn "cmpqi_ext_3_insn"
744 [(set (reg FLAGS_REG)
748 (match_operand 0 "ext_register_operand" "Q")
751 (match_operand:QI 1 "general_operand" "Qmn")))]
752 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
753 "cmp{b}\t{%1, %h0|%h0, %1}"
754 [(set_attr "type" "icmp")
755 (set_attr "mode" "QI")])
757 (define_insn "cmpqi_ext_3_insn_rex64"
758 [(set (reg FLAGS_REG)
762 (match_operand 0 "ext_register_operand" "Q")
765 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
766 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
767 "cmp{b}\t{%1, %h0|%h0, %1}"
768 [(set_attr "type" "icmp")
769 (set_attr "mode" "QI")])
771 (define_insn "*cmpqi_ext_4"
772 [(set (reg FLAGS_REG)
776 (match_operand 0 "ext_register_operand" "Q")
781 (match_operand 1 "ext_register_operand" "Q")
784 "ix86_match_ccmode (insn, CCmode)"
785 "cmp{b}\t{%h1, %h0|%h0, %h1}"
786 [(set_attr "type" "icmp")
787 (set_attr "mode" "QI")])
789 ;; These implement float point compares.
790 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
791 ;; which would allow mix and match FP modes on the compares. Which is what
792 ;; the old patterns did, but with many more of them.
794 (define_expand "cmpxf"
795 [(set (reg:CC FLAGS_REG)
796 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
797 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
800 ix86_compare_op0 = operands[0];
801 ix86_compare_op1 = operands[1];
805 (define_expand "cmpdf"
806 [(set (reg:CC FLAGS_REG)
807 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
808 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
809 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
811 ix86_compare_op0 = operands[0];
812 ix86_compare_op1 = operands[1];
816 (define_expand "cmpsf"
817 [(set (reg:CC FLAGS_REG)
818 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
819 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
820 "TARGET_80387 || TARGET_SSE_MATH"
822 ix86_compare_op0 = operands[0];
823 ix86_compare_op1 = operands[1];
827 ;; FP compares, step 1:
828 ;; Set the FP condition codes.
830 ;; CCFPmode compare with exceptions
831 ;; CCFPUmode compare with no exceptions
833 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
834 ;; used to manage the reg stack popping would not be preserved.
836 (define_insn "*cmpfp_0"
837 [(set (match_operand:HI 0 "register_operand" "=a")
840 (match_operand 1 "register_operand" "f")
841 (match_operand 2 "const0_operand" "X"))]
844 && FLOAT_MODE_P (GET_MODE (operands[1]))
845 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
846 "* return output_fp_compare (insn, operands, 0, 0);"
847 [(set_attr "type" "multi")
848 (set_attr "unit" "i387")
850 (cond [(match_operand:SF 1 "" "")
852 (match_operand:DF 1 "" "")
855 (const_string "XF")))])
857 (define_insn "*cmpfp_sf"
858 [(set (match_operand:HI 0 "register_operand" "=a")
861 (match_operand:SF 1 "register_operand" "f")
862 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
865 "* return output_fp_compare (insn, operands, 0, 0);"
866 [(set_attr "type" "multi")
867 (set_attr "unit" "i387")
868 (set_attr "mode" "SF")])
870 (define_insn "*cmpfp_df"
871 [(set (match_operand:HI 0 "register_operand" "=a")
874 (match_operand:DF 1 "register_operand" "f")
875 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
878 "* return output_fp_compare (insn, operands, 0, 0);"
879 [(set_attr "type" "multi")
880 (set_attr "unit" "i387")
881 (set_attr "mode" "DF")])
883 (define_insn "*cmpfp_xf"
884 [(set (match_operand:HI 0 "register_operand" "=a")
887 (match_operand:XF 1 "register_operand" "f")
888 (match_operand:XF 2 "register_operand" "f"))]
891 "* return output_fp_compare (insn, operands, 0, 0);"
892 [(set_attr "type" "multi")
893 (set_attr "unit" "i387")
894 (set_attr "mode" "XF")])
896 (define_insn "*cmpfp_u"
897 [(set (match_operand:HI 0 "register_operand" "=a")
900 (match_operand 1 "register_operand" "f")
901 (match_operand 2 "register_operand" "f"))]
904 && FLOAT_MODE_P (GET_MODE (operands[1]))
905 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
906 "* return output_fp_compare (insn, operands, 0, 1);"
907 [(set_attr "type" "multi")
908 (set_attr "unit" "i387")
910 (cond [(match_operand:SF 1 "" "")
912 (match_operand:DF 1 "" "")
915 (const_string "XF")))])
917 (define_insn "*cmpfp_<mode>"
918 [(set (match_operand:HI 0 "register_operand" "=a")
921 (match_operand 1 "register_operand" "f")
922 (match_operator 3 "float_operator"
923 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
925 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
926 && FLOAT_MODE_P (GET_MODE (operands[1]))
927 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
928 "* return output_fp_compare (insn, operands, 0, 0);"
929 [(set_attr "type" "multi")
930 (set_attr "unit" "i387")
931 (set_attr "fp_int_src" "true")
932 (set_attr "mode" "<MODE>")])
934 ;; FP compares, step 2
935 ;; Move the fpsw to ax.
937 (define_insn "x86_fnstsw_1"
938 [(set (match_operand:HI 0 "register_operand" "=a")
939 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
942 [(set_attr "length" "2")
943 (set_attr "mode" "SI")
944 (set_attr "unit" "i387")])
946 ;; FP compares, step 3
947 ;; Get ax into flags, general case.
949 (define_insn "x86_sahf_1"
950 [(set (reg:CC FLAGS_REG)
951 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
954 [(set_attr "length" "1")
955 (set_attr "athlon_decode" "vector")
956 (set_attr "mode" "SI")])
958 ;; Pentium Pro can do steps 1 through 3 in one go.
960 (define_insn "*cmpfp_i_mixed"
961 [(set (reg:CCFP FLAGS_REG)
962 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
963 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
965 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
966 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
967 "* return output_fp_compare (insn, operands, 1, 0);"
968 [(set_attr "type" "fcmp,ssecomi")
970 (if_then_else (match_operand:SF 1 "" "")
972 (const_string "DF")))
973 (set_attr "athlon_decode" "vector")])
975 (define_insn "*cmpfp_i_sse"
976 [(set (reg:CCFP FLAGS_REG)
977 (compare:CCFP (match_operand 0 "register_operand" "x")
978 (match_operand 1 "nonimmediate_operand" "xm")))]
980 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
981 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
982 "* return output_fp_compare (insn, operands, 1, 0);"
983 [(set_attr "type" "ssecomi")
985 (if_then_else (match_operand:SF 1 "" "")
987 (const_string "DF")))
988 (set_attr "athlon_decode" "vector")])
990 (define_insn "*cmpfp_i_i387"
991 [(set (reg:CCFP FLAGS_REG)
992 (compare:CCFP (match_operand 0 "register_operand" "f")
993 (match_operand 1 "register_operand" "f")))]
994 "TARGET_80387 && TARGET_CMOVE
995 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
996 && FLOAT_MODE_P (GET_MODE (operands[0]))
997 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
998 "* return output_fp_compare (insn, operands, 1, 0);"
999 [(set_attr "type" "fcmp")
1001 (cond [(match_operand:SF 1 "" "")
1003 (match_operand:DF 1 "" "")
1006 (const_string "XF")))
1007 (set_attr "athlon_decode" "vector")])
1009 (define_insn "*cmpfp_iu_mixed"
1010 [(set (reg:CCFPU FLAGS_REG)
1011 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1012 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1013 "TARGET_MIX_SSE_I387
1014 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016 "* return output_fp_compare (insn, operands, 1, 1);"
1017 [(set_attr "type" "fcmp,ssecomi")
1019 (if_then_else (match_operand:SF 1 "" "")
1021 (const_string "DF")))
1022 (set_attr "athlon_decode" "vector")])
1024 (define_insn "*cmpfp_iu_sse"
1025 [(set (reg:CCFPU FLAGS_REG)
1026 (compare:CCFPU (match_operand 0 "register_operand" "x")
1027 (match_operand 1 "nonimmediate_operand" "xm")))]
1029 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1030 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1031 "* return output_fp_compare (insn, operands, 1, 1);"
1032 [(set_attr "type" "ssecomi")
1034 (if_then_else (match_operand:SF 1 "" "")
1036 (const_string "DF")))
1037 (set_attr "athlon_decode" "vector")])
1039 (define_insn "*cmpfp_iu_387"
1040 [(set (reg:CCFPU FLAGS_REG)
1041 (compare:CCFPU (match_operand 0 "register_operand" "f")
1042 (match_operand 1 "register_operand" "f")))]
1043 "TARGET_80387 && TARGET_CMOVE
1044 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1045 && FLOAT_MODE_P (GET_MODE (operands[0]))
1046 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1047 "* return output_fp_compare (insn, operands, 1, 1);"
1048 [(set_attr "type" "fcmp")
1050 (cond [(match_operand:SF 1 "" "")
1052 (match_operand:DF 1 "" "")
1055 (const_string "XF")))
1056 (set_attr "athlon_decode" "vector")])
1058 ;; Move instructions.
1060 ;; General case of fullword move.
1062 (define_expand "movsi"
1063 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1064 (match_operand:SI 1 "general_operand" ""))]
1066 "ix86_expand_move (SImode, operands); DONE;")
1068 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1071 ;; %%% We don't use a post-inc memory reference because x86 is not a
1072 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1073 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1074 ;; targets without our curiosities, and it is just as easy to represent
1075 ;; this differently.
1077 (define_insn "*pushsi2"
1078 [(set (match_operand:SI 0 "push_operand" "=<")
1079 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1082 [(set_attr "type" "push")
1083 (set_attr "mode" "SI")])
1085 ;; For 64BIT abi we always round up to 8 bytes.
1086 (define_insn "*pushsi2_rex64"
1087 [(set (match_operand:SI 0 "push_operand" "=X")
1088 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1091 [(set_attr "type" "push")
1092 (set_attr "mode" "SI")])
1094 (define_insn "*pushsi2_prologue"
1095 [(set (match_operand:SI 0 "push_operand" "=<")
1096 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1097 (clobber (mem:BLK (scratch)))]
1100 [(set_attr "type" "push")
1101 (set_attr "mode" "SI")])
1103 (define_insn "*popsi1_epilogue"
1104 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1105 (mem:SI (reg:SI SP_REG)))
1106 (set (reg:SI SP_REG)
1107 (plus:SI (reg:SI SP_REG) (const_int 4)))
1108 (clobber (mem:BLK (scratch)))]
1111 [(set_attr "type" "pop")
1112 (set_attr "mode" "SI")])
1114 (define_insn "popsi1"
1115 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1116 (mem:SI (reg:SI SP_REG)))
1117 (set (reg:SI SP_REG)
1118 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1121 [(set_attr "type" "pop")
1122 (set_attr "mode" "SI")])
1124 (define_insn "*movsi_xor"
1125 [(set (match_operand:SI 0 "register_operand" "=r")
1126 (match_operand:SI 1 "const0_operand" "i"))
1127 (clobber (reg:CC FLAGS_REG))]
1128 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1129 "xor{l}\t{%0, %0|%0, %0}"
1130 [(set_attr "type" "alu1")
1131 (set_attr "mode" "SI")
1132 (set_attr "length_immediate" "0")])
1134 (define_insn "*movsi_or"
1135 [(set (match_operand:SI 0 "register_operand" "=r")
1136 (match_operand:SI 1 "immediate_operand" "i"))
1137 (clobber (reg:CC FLAGS_REG))]
1139 && operands[1] == constm1_rtx
1140 && (TARGET_PENTIUM || optimize_size)"
1142 operands[1] = constm1_rtx;
1143 return "or{l}\t{%1, %0|%0, %1}";
1145 [(set_attr "type" "alu1")
1146 (set_attr "mode" "SI")
1147 (set_attr "length_immediate" "1")])
1149 (define_insn "*movsi_1"
1150 [(set (match_operand:SI 0 "nonimmediate_operand"
1151 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1152 (match_operand:SI 1 "general_operand"
1153 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1154 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1156 switch (get_attr_type (insn))
1159 if (get_attr_mode (insn) == MODE_TI)
1160 return "pxor\t%0, %0";
1161 return "xorps\t%0, %0";
1164 switch (get_attr_mode (insn))
1167 return "movdqa\t{%1, %0|%0, %1}";
1169 return "movaps\t{%1, %0|%0, %1}";
1171 return "movd\t{%1, %0|%0, %1}";
1173 return "movss\t{%1, %0|%0, %1}";
1179 return "pxor\t%0, %0";
1182 if (get_attr_mode (insn) == MODE_DI)
1183 return "movq\t{%1, %0|%0, %1}";
1184 return "movd\t{%1, %0|%0, %1}";
1187 return "lea{l}\t{%1, %0|%0, %1}";
1190 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1191 return "mov{l}\t{%1, %0|%0, %1}";
1195 (cond [(eq_attr "alternative" "2")
1196 (const_string "mmx")
1197 (eq_attr "alternative" "3,4,5")
1198 (const_string "mmxmov")
1199 (eq_attr "alternative" "6")
1200 (const_string "sselog1")
1201 (eq_attr "alternative" "7,8,9,10,11")
1202 (const_string "ssemov")
1203 (and (ne (symbol_ref "flag_pic") (const_int 0))
1204 (match_operand:SI 1 "symbolic_operand" ""))
1205 (const_string "lea")
1207 (const_string "imov")))
1209 (cond [(eq_attr "alternative" "2,3")
1211 (eq_attr "alternative" "6,7")
1213 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1214 (const_string "V4SF")
1215 (const_string "TI"))
1216 (and (eq_attr "alternative" "8,9,10,11")
1217 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1220 (const_string "SI")))])
1222 ;; Stores and loads of ax to arbitrary constant address.
1223 ;; We fake an second form of instruction to force reload to load address
1224 ;; into register when rax is not available
1225 (define_insn "*movabssi_1_rex64"
1226 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1227 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1228 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1230 movabs{l}\t{%1, %P0|%P0, %1}
1231 mov{l}\t{%1, %a0|%a0, %1}"
1232 [(set_attr "type" "imov")
1233 (set_attr "modrm" "0,*")
1234 (set_attr "length_address" "8,0")
1235 (set_attr "length_immediate" "0,*")
1236 (set_attr "memory" "store")
1237 (set_attr "mode" "SI")])
1239 (define_insn "*movabssi_2_rex64"
1240 [(set (match_operand:SI 0 "register_operand" "=a,r")
1241 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1242 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1244 movabs{l}\t{%P1, %0|%0, %P1}
1245 mov{l}\t{%a1, %0|%0, %a1}"
1246 [(set_attr "type" "imov")
1247 (set_attr "modrm" "0,*")
1248 (set_attr "length_address" "8,0")
1249 (set_attr "length_immediate" "0")
1250 (set_attr "memory" "load")
1251 (set_attr "mode" "SI")])
1253 (define_insn "*swapsi"
1254 [(set (match_operand:SI 0 "register_operand" "+r")
1255 (match_operand:SI 1 "register_operand" "+r"))
1260 [(set_attr "type" "imov")
1261 (set_attr "mode" "SI")
1262 (set_attr "pent_pair" "np")
1263 (set_attr "athlon_decode" "vector")])
1265 (define_expand "movhi"
1266 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1267 (match_operand:HI 1 "general_operand" ""))]
1269 "ix86_expand_move (HImode, operands); DONE;")
1271 (define_insn "*pushhi2"
1272 [(set (match_operand:HI 0 "push_operand" "=<,<")
1273 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1276 push{w}\t{|WORD PTR }%1
1278 [(set_attr "type" "push")
1279 (set_attr "mode" "HI")])
1281 ;; For 64BIT abi we always round up to 8 bytes.
1282 (define_insn "*pushhi2_rex64"
1283 [(set (match_operand:HI 0 "push_operand" "=X")
1284 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1287 [(set_attr "type" "push")
1288 (set_attr "mode" "QI")])
1290 (define_insn "*movhi_1"
1291 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1292 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1293 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1295 switch (get_attr_type (insn))
1298 /* movzwl is faster than movw on p2 due to partial word stalls,
1299 though not as fast as an aligned movl. */
1300 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1302 if (get_attr_mode (insn) == MODE_SI)
1303 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1305 return "mov{w}\t{%1, %0|%0, %1}";
1309 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1310 (const_string "imov")
1311 (and (eq_attr "alternative" "0")
1312 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1314 (eq (symbol_ref "TARGET_HIMODE_MATH")
1316 (const_string "imov")
1317 (and (eq_attr "alternative" "1,2")
1318 (match_operand:HI 1 "aligned_operand" ""))
1319 (const_string "imov")
1320 (and (ne (symbol_ref "TARGET_MOVX")
1322 (eq_attr "alternative" "0,2"))
1323 (const_string "imovx")
1325 (const_string "imov")))
1327 (cond [(eq_attr "type" "imovx")
1329 (and (eq_attr "alternative" "1,2")
1330 (match_operand:HI 1 "aligned_operand" ""))
1332 (and (eq_attr "alternative" "0")
1333 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1335 (eq (symbol_ref "TARGET_HIMODE_MATH")
1339 (const_string "HI")))])
1341 ;; Stores and loads of ax to arbitrary constant address.
1342 ;; We fake an second form of instruction to force reload to load address
1343 ;; into register when rax is not available
1344 (define_insn "*movabshi_1_rex64"
1345 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1346 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1347 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1349 movabs{w}\t{%1, %P0|%P0, %1}
1350 mov{w}\t{%1, %a0|%a0, %1}"
1351 [(set_attr "type" "imov")
1352 (set_attr "modrm" "0,*")
1353 (set_attr "length_address" "8,0")
1354 (set_attr "length_immediate" "0,*")
1355 (set_attr "memory" "store")
1356 (set_attr "mode" "HI")])
1358 (define_insn "*movabshi_2_rex64"
1359 [(set (match_operand:HI 0 "register_operand" "=a,r")
1360 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1361 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1363 movabs{w}\t{%P1, %0|%0, %P1}
1364 mov{w}\t{%a1, %0|%0, %a1}"
1365 [(set_attr "type" "imov")
1366 (set_attr "modrm" "0,*")
1367 (set_attr "length_address" "8,0")
1368 (set_attr "length_immediate" "0")
1369 (set_attr "memory" "load")
1370 (set_attr "mode" "HI")])
1372 (define_insn "*swaphi_1"
1373 [(set (match_operand:HI 0 "register_operand" "+r")
1374 (match_operand:HI 1 "register_operand" "+r"))
1377 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1379 [(set_attr "type" "imov")
1380 (set_attr "mode" "SI")
1381 (set_attr "pent_pair" "np")
1382 (set_attr "athlon_decode" "vector")])
1384 (define_insn "*swaphi_2"
1385 [(set (match_operand:HI 0 "register_operand" "+r")
1386 (match_operand:HI 1 "register_operand" "+r"))
1389 "TARGET_PARTIAL_REG_STALL"
1391 [(set_attr "type" "imov")
1392 (set_attr "mode" "HI")
1393 (set_attr "pent_pair" "np")
1394 (set_attr "athlon_decode" "vector")])
1396 (define_expand "movstricthi"
1397 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1398 (match_operand:HI 1 "general_operand" ""))]
1399 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1401 /* Don't generate memory->memory moves, go through a register */
1402 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1403 operands[1] = force_reg (HImode, operands[1]);
1406 (define_insn "*movstricthi_1"
1407 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1408 (match_operand:HI 1 "general_operand" "rn,m"))]
1409 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1410 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1411 "mov{w}\t{%1, %0|%0, %1}"
1412 [(set_attr "type" "imov")
1413 (set_attr "mode" "HI")])
1415 (define_insn "*movstricthi_xor"
1416 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1417 (match_operand:HI 1 "const0_operand" "i"))
1418 (clobber (reg:CC FLAGS_REG))]
1420 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1421 "xor{w}\t{%0, %0|%0, %0}"
1422 [(set_attr "type" "alu1")
1423 (set_attr "mode" "HI")
1424 (set_attr "length_immediate" "0")])
1426 (define_expand "movqi"
1427 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1428 (match_operand:QI 1 "general_operand" ""))]
1430 "ix86_expand_move (QImode, operands); DONE;")
1432 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1433 ;; "push a byte". But actually we use pushw, which has the effect
1434 ;; of rounding the amount pushed up to a halfword.
1436 (define_insn "*pushqi2"
1437 [(set (match_operand:QI 0 "push_operand" "=X,X")
1438 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1441 push{w}\t{|word ptr }%1
1443 [(set_attr "type" "push")
1444 (set_attr "mode" "HI")])
1446 ;; For 64BIT abi we always round up to 8 bytes.
1447 (define_insn "*pushqi2_rex64"
1448 [(set (match_operand:QI 0 "push_operand" "=X")
1449 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1452 [(set_attr "type" "push")
1453 (set_attr "mode" "QI")])
1455 ;; Situation is quite tricky about when to choose full sized (SImode) move
1456 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1457 ;; partial register dependency machines (such as AMD Athlon), where QImode
1458 ;; moves issue extra dependency and for partial register stalls machines
1459 ;; that don't use QImode patterns (and QImode move cause stall on the next
1462 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1463 ;; register stall machines with, where we use QImode instructions, since
1464 ;; partial register stall can be caused there. Then we use movzx.
1465 (define_insn "*movqi_1"
1466 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1467 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,m ,qn"))]
1468 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1470 switch (get_attr_type (insn))
1473 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1474 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1476 if (get_attr_mode (insn) == MODE_SI)
1477 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1479 return "mov{b}\t{%1, %0|%0, %1}";
1483 (cond [(eq_attr "alternative" "5")
1484 (const_string "imovx")
1485 (ne (symbol_ref "optimize_size") (const_int 0))
1486 (const_string "imov")
1487 (and (eq_attr "alternative" "3")
1488 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1490 (eq (symbol_ref "TARGET_QIMODE_MATH")
1492 (const_string "imov")
1493 (eq_attr "alternative" "3")
1494 (const_string "imovx")
1495 (and (ne (symbol_ref "TARGET_MOVX")
1497 (eq_attr "alternative" "2"))
1498 (const_string "imovx")
1500 (const_string "imov")))
1502 (cond [(eq_attr "alternative" "3,4,5")
1504 (eq_attr "alternative" "6")
1506 (eq_attr "type" "imovx")
1508 (and (eq_attr "type" "imov")
1509 (and (eq_attr "alternative" "0,1")
1510 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1513 ;; Avoid partial register stalls when not using QImode arithmetic
1514 (and (eq_attr "type" "imov")
1515 (and (eq_attr "alternative" "0,1")
1516 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1518 (eq (symbol_ref "TARGET_QIMODE_MATH")
1522 (const_string "QI")))])
1524 (define_expand "reload_outqi"
1525 [(parallel [(match_operand:QI 0 "" "=m")
1526 (match_operand:QI 1 "register_operand" "r")
1527 (match_operand:QI 2 "register_operand" "=&q")])]
1531 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1533 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1534 if (! q_regs_operand (op1, QImode))
1536 emit_insn (gen_movqi (op2, op1));
1539 emit_insn (gen_movqi (op0, op1));
1543 (define_insn "*swapqi_1"
1544 [(set (match_operand:QI 0 "register_operand" "+r")
1545 (match_operand:QI 1 "register_operand" "+r"))
1548 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1550 [(set_attr "type" "imov")
1551 (set_attr "mode" "SI")
1552 (set_attr "pent_pair" "np")
1553 (set_attr "athlon_decode" "vector")])
1555 (define_insn "*swapqi_2"
1556 [(set (match_operand:QI 0 "register_operand" "+q")
1557 (match_operand:QI 1 "register_operand" "+q"))
1560 "TARGET_PARTIAL_REG_STALL"
1562 [(set_attr "type" "imov")
1563 (set_attr "mode" "QI")
1564 (set_attr "pent_pair" "np")
1565 (set_attr "athlon_decode" "vector")])
1567 (define_expand "movstrictqi"
1568 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1569 (match_operand:QI 1 "general_operand" ""))]
1570 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1572 /* Don't generate memory->memory moves, go through a register. */
1573 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1574 operands[1] = force_reg (QImode, operands[1]);
1577 (define_insn "*movstrictqi_1"
1578 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1579 (match_operand:QI 1 "general_operand" "*qn,m"))]
1580 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1581 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1582 "mov{b}\t{%1, %0|%0, %1}"
1583 [(set_attr "type" "imov")
1584 (set_attr "mode" "QI")])
1586 (define_insn "*movstrictqi_xor"
1587 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1588 (match_operand:QI 1 "const0_operand" "i"))
1589 (clobber (reg:CC FLAGS_REG))]
1590 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1591 "xor{b}\t{%0, %0|%0, %0}"
1592 [(set_attr "type" "alu1")
1593 (set_attr "mode" "QI")
1594 (set_attr "length_immediate" "0")])
1596 (define_insn "*movsi_extv_1"
1597 [(set (match_operand:SI 0 "register_operand" "=R")
1598 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1602 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1603 [(set_attr "type" "imovx")
1604 (set_attr "mode" "SI")])
1606 (define_insn "*movhi_extv_1"
1607 [(set (match_operand:HI 0 "register_operand" "=R")
1608 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1612 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1613 [(set_attr "type" "imovx")
1614 (set_attr "mode" "SI")])
1616 (define_insn "*movqi_extv_1"
1617 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1618 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1623 switch (get_attr_type (insn))
1626 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1628 return "mov{b}\t{%h1, %0|%0, %h1}";
1632 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1633 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1634 (ne (symbol_ref "TARGET_MOVX")
1636 (const_string "imovx")
1637 (const_string "imov")))
1639 (if_then_else (eq_attr "type" "imovx")
1641 (const_string "QI")))])
1643 (define_insn "*movqi_extv_1_rex64"
1644 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1645 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1650 switch (get_attr_type (insn))
1653 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1655 return "mov{b}\t{%h1, %0|%0, %h1}";
1659 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1660 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1661 (ne (symbol_ref "TARGET_MOVX")
1663 (const_string "imovx")
1664 (const_string "imov")))
1666 (if_then_else (eq_attr "type" "imovx")
1668 (const_string "QI")))])
1670 ;; Stores and loads of ax to arbitrary constant address.
1671 ;; We fake an second form of instruction to force reload to load address
1672 ;; into register when rax is not available
1673 (define_insn "*movabsqi_1_rex64"
1674 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1675 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1676 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1678 movabs{b}\t{%1, %P0|%P0, %1}
1679 mov{b}\t{%1, %a0|%a0, %1}"
1680 [(set_attr "type" "imov")
1681 (set_attr "modrm" "0,*")
1682 (set_attr "length_address" "8,0")
1683 (set_attr "length_immediate" "0,*")
1684 (set_attr "memory" "store")
1685 (set_attr "mode" "QI")])
1687 (define_insn "*movabsqi_2_rex64"
1688 [(set (match_operand:QI 0 "register_operand" "=a,r")
1689 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1690 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1692 movabs{b}\t{%P1, %0|%0, %P1}
1693 mov{b}\t{%a1, %0|%0, %a1}"
1694 [(set_attr "type" "imov")
1695 (set_attr "modrm" "0,*")
1696 (set_attr "length_address" "8,0")
1697 (set_attr "length_immediate" "0")
1698 (set_attr "memory" "load")
1699 (set_attr "mode" "QI")])
1701 (define_insn "*movdi_extzv_1"
1702 [(set (match_operand:DI 0 "register_operand" "=R")
1703 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1707 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1708 [(set_attr "type" "imovx")
1709 (set_attr "mode" "DI")])
1711 (define_insn "*movsi_extzv_1"
1712 [(set (match_operand:SI 0 "register_operand" "=R")
1713 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1717 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1718 [(set_attr "type" "imovx")
1719 (set_attr "mode" "SI")])
1721 (define_insn "*movqi_extzv_2"
1722 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1723 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1728 switch (get_attr_type (insn))
1731 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1733 return "mov{b}\t{%h1, %0|%0, %h1}";
1737 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1738 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1739 (ne (symbol_ref "TARGET_MOVX")
1741 (const_string "imovx")
1742 (const_string "imov")))
1744 (if_then_else (eq_attr "type" "imovx")
1746 (const_string "QI")))])
1748 (define_insn "*movqi_extzv_2_rex64"
1749 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1750 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1755 switch (get_attr_type (insn))
1758 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1760 return "mov{b}\t{%h1, %0|%0, %h1}";
1764 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1765 (ne (symbol_ref "TARGET_MOVX")
1767 (const_string "imovx")
1768 (const_string "imov")))
1770 (if_then_else (eq_attr "type" "imovx")
1772 (const_string "QI")))])
1774 (define_insn "movsi_insv_1"
1775 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1778 (match_operand:SI 1 "general_operand" "Qmn"))]
1780 "mov{b}\t{%b1, %h0|%h0, %b1}"
1781 [(set_attr "type" "imov")
1782 (set_attr "mode" "QI")])
1784 (define_insn "movdi_insv_1_rex64"
1785 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1788 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1790 "mov{b}\t{%b1, %h0|%h0, %b1}"
1791 [(set_attr "type" "imov")
1792 (set_attr "mode" "QI")])
1794 (define_insn "*movqi_insv_2"
1795 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1798 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1801 "mov{b}\t{%h1, %h0|%h0, %h1}"
1802 [(set_attr "type" "imov")
1803 (set_attr "mode" "QI")])
1805 (define_expand "movdi"
1806 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1807 (match_operand:DI 1 "general_operand" ""))]
1809 "ix86_expand_move (DImode, operands); DONE;")
1811 (define_insn "*pushdi"
1812 [(set (match_operand:DI 0 "push_operand" "=<")
1813 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1817 (define_insn "*pushdi2_rex64"
1818 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1819 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1824 [(set_attr "type" "push,multi")
1825 (set_attr "mode" "DI")])
1827 ;; Convert impossible pushes of immediate to existing instructions.
1828 ;; First try to get scratch register and go through it. In case this
1829 ;; fails, push sign extended lower part first and then overwrite
1830 ;; upper part by 32bit move.
1832 [(match_scratch:DI 2 "r")
1833 (set (match_operand:DI 0 "push_operand" "")
1834 (match_operand:DI 1 "immediate_operand" ""))]
1835 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1836 && !x86_64_immediate_operand (operands[1], DImode)"
1837 [(set (match_dup 2) (match_dup 1))
1838 (set (match_dup 0) (match_dup 2))]
1841 ;; We need to define this as both peepholer and splitter for case
1842 ;; peephole2 pass is not run.
1843 ;; "&& 1" is needed to keep it from matching the previous pattern.
1845 [(set (match_operand:DI 0 "push_operand" "")
1846 (match_operand:DI 1 "immediate_operand" ""))]
1847 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1848 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1849 [(set (match_dup 0) (match_dup 1))
1850 (set (match_dup 2) (match_dup 3))]
1851 "split_di (operands + 1, 1, operands + 2, operands + 3);
1852 operands[1] = gen_lowpart (DImode, operands[2]);
1853 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1858 [(set (match_operand:DI 0 "push_operand" "")
1859 (match_operand:DI 1 "immediate_operand" ""))]
1860 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1861 && !symbolic_operand (operands[1], DImode)
1862 && !x86_64_immediate_operand (operands[1], DImode)"
1863 [(set (match_dup 0) (match_dup 1))
1864 (set (match_dup 2) (match_dup 3))]
1865 "split_di (operands + 1, 1, operands + 2, operands + 3);
1866 operands[1] = gen_lowpart (DImode, operands[2]);
1867 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1871 (define_insn "*pushdi2_prologue_rex64"
1872 [(set (match_operand:DI 0 "push_operand" "=<")
1873 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1874 (clobber (mem:BLK (scratch)))]
1877 [(set_attr "type" "push")
1878 (set_attr "mode" "DI")])
1880 (define_insn "*popdi1_epilogue_rex64"
1881 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1882 (mem:DI (reg:DI SP_REG)))
1883 (set (reg:DI SP_REG)
1884 (plus:DI (reg:DI SP_REG) (const_int 8)))
1885 (clobber (mem:BLK (scratch)))]
1888 [(set_attr "type" "pop")
1889 (set_attr "mode" "DI")])
1891 (define_insn "popdi1"
1892 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1893 (mem:DI (reg:DI SP_REG)))
1894 (set (reg:DI SP_REG)
1895 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1898 [(set_attr "type" "pop")
1899 (set_attr "mode" "DI")])
1901 (define_insn "*movdi_xor_rex64"
1902 [(set (match_operand:DI 0 "register_operand" "=r")
1903 (match_operand:DI 1 "const0_operand" "i"))
1904 (clobber (reg:CC FLAGS_REG))]
1905 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1906 && reload_completed"
1907 "xor{l}\t{%k0, %k0|%k0, %k0}"
1908 [(set_attr "type" "alu1")
1909 (set_attr "mode" "SI")
1910 (set_attr "length_immediate" "0")])
1912 (define_insn "*movdi_or_rex64"
1913 [(set (match_operand:DI 0 "register_operand" "=r")
1914 (match_operand:DI 1 "const_int_operand" "i"))
1915 (clobber (reg:CC FLAGS_REG))]
1916 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1918 && operands[1] == constm1_rtx"
1920 operands[1] = constm1_rtx;
1921 return "or{q}\t{%1, %0|%0, %1}";
1923 [(set_attr "type" "alu1")
1924 (set_attr "mode" "DI")
1925 (set_attr "length_immediate" "1")])
1927 (define_insn "*movdi_2"
1928 [(set (match_operand:DI 0 "nonimmediate_operand"
1929 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1930 (match_operand:DI 1 "general_operand"
1931 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1932 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1937 movq\t{%1, %0|%0, %1}
1938 movq\t{%1, %0|%0, %1}
1940 movq\t{%1, %0|%0, %1}
1941 movdqa\t{%1, %0|%0, %1}
1942 movq\t{%1, %0|%0, %1}
1944 movlps\t{%1, %0|%0, %1}
1945 movaps\t{%1, %0|%0, %1}
1946 movlps\t{%1, %0|%0, %1}"
1947 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1948 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1951 [(set (match_operand:DI 0 "push_operand" "")
1952 (match_operand:DI 1 "general_operand" ""))]
1953 "!TARGET_64BIT && reload_completed
1954 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1956 "ix86_split_long_move (operands); DONE;")
1958 ;; %%% This multiword shite has got to go.
1960 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1961 (match_operand:DI 1 "general_operand" ""))]
1962 "!TARGET_64BIT && reload_completed
1963 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1964 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1966 "ix86_split_long_move (operands); DONE;")
1968 (define_insn "*movdi_1_rex64"
1969 [(set (match_operand:DI 0 "nonimmediate_operand"
1970 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1971 (match_operand:DI 1 "general_operand"
1972 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1973 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1975 switch (get_attr_type (insn))
1978 if (which_alternative == 13)
1979 return "movq2dq\t{%1, %0|%0, %1}";
1981 return "movdq2q\t{%1, %0|%0, %1}";
1983 if (get_attr_mode (insn) == MODE_TI)
1984 return "movdqa\t{%1, %0|%0, %1}";
1987 /* Moves from and into integer register is done using movd opcode with
1989 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1990 return "movd\t{%1, %0|%0, %1}";
1991 return "movq\t{%1, %0|%0, %1}";
1994 return "pxor\t%0, %0";
1998 return "lea{q}\t{%a1, %0|%0, %a1}";
2000 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2001 if (get_attr_mode (insn) == MODE_SI)
2002 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2003 else if (which_alternative == 2)
2004 return "movabs{q}\t{%1, %0|%0, %1}";
2006 return "mov{q}\t{%1, %0|%0, %1}";
2010 (cond [(eq_attr "alternative" "5")
2011 (const_string "mmx")
2012 (eq_attr "alternative" "6,7,8")
2013 (const_string "mmxmov")
2014 (eq_attr "alternative" "9")
2015 (const_string "sselog1")
2016 (eq_attr "alternative" "10,11,12")
2017 (const_string "ssemov")
2018 (eq_attr "alternative" "13,14")
2019 (const_string "ssecvt")
2020 (eq_attr "alternative" "4")
2021 (const_string "multi")
2022 (and (ne (symbol_ref "flag_pic") (const_int 0))
2023 (match_operand:DI 1 "symbolic_operand" ""))
2024 (const_string "lea")
2026 (const_string "imov")))
2027 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2028 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2029 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2031 ;; Stores and loads of ax to arbitrary constant address.
2032 ;; We fake an second form of instruction to force reload to load address
2033 ;; into register when rax is not available
2034 (define_insn "*movabsdi_1_rex64"
2035 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2036 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2037 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2039 movabs{q}\t{%1, %P0|%P0, %1}
2040 mov{q}\t{%1, %a0|%a0, %1}"
2041 [(set_attr "type" "imov")
2042 (set_attr "modrm" "0,*")
2043 (set_attr "length_address" "8,0")
2044 (set_attr "length_immediate" "0,*")
2045 (set_attr "memory" "store")
2046 (set_attr "mode" "DI")])
2048 (define_insn "*movabsdi_2_rex64"
2049 [(set (match_operand:DI 0 "register_operand" "=a,r")
2050 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2051 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2053 movabs{q}\t{%P1, %0|%0, %P1}
2054 mov{q}\t{%a1, %0|%0, %a1}"
2055 [(set_attr "type" "imov")
2056 (set_attr "modrm" "0,*")
2057 (set_attr "length_address" "8,0")
2058 (set_attr "length_immediate" "0")
2059 (set_attr "memory" "load")
2060 (set_attr "mode" "DI")])
2062 ;; Convert impossible stores of immediate to existing instructions.
2063 ;; First try to get scratch register and go through it. In case this
2064 ;; fails, move by 32bit parts.
2066 [(match_scratch:DI 2 "r")
2067 (set (match_operand:DI 0 "memory_operand" "")
2068 (match_operand:DI 1 "immediate_operand" ""))]
2069 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2070 && !x86_64_immediate_operand (operands[1], DImode)"
2071 [(set (match_dup 2) (match_dup 1))
2072 (set (match_dup 0) (match_dup 2))]
2075 ;; We need to define this as both peepholer and splitter for case
2076 ;; peephole2 pass is not run.
2077 ;; "&& 1" is needed to keep it from matching the previous pattern.
2079 [(set (match_operand:DI 0 "memory_operand" "")
2080 (match_operand:DI 1 "immediate_operand" ""))]
2081 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2082 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2083 [(set (match_dup 2) (match_dup 3))
2084 (set (match_dup 4) (match_dup 5))]
2085 "split_di (operands, 2, operands + 2, operands + 4);")
2088 [(set (match_operand:DI 0 "memory_operand" "")
2089 (match_operand:DI 1 "immediate_operand" ""))]
2090 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2091 && !symbolic_operand (operands[1], DImode)
2092 && !x86_64_immediate_operand (operands[1], DImode)"
2093 [(set (match_dup 2) (match_dup 3))
2094 (set (match_dup 4) (match_dup 5))]
2095 "split_di (operands, 2, operands + 2, operands + 4);")
2097 (define_insn "*swapdi_rex64"
2098 [(set (match_operand:DI 0 "register_operand" "+r")
2099 (match_operand:DI 1 "register_operand" "+r"))
2104 [(set_attr "type" "imov")
2105 (set_attr "mode" "DI")
2106 (set_attr "pent_pair" "np")
2107 (set_attr "athlon_decode" "vector")])
2109 (define_expand "movti"
2110 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2111 (match_operand:TI 1 "nonimmediate_operand" ""))]
2112 "TARGET_SSE || TARGET_64BIT"
2115 ix86_expand_move (TImode, operands);
2117 ix86_expand_vector_move (TImode, operands);
2121 (define_insn "*movti_internal"
2122 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2123 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2124 "TARGET_SSE && !TARGET_64BIT
2125 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2127 switch (which_alternative)
2130 if (get_attr_mode (insn) == MODE_V4SF)
2131 return "xorps\t%0, %0";
2133 return "pxor\t%0, %0";
2136 if (get_attr_mode (insn) == MODE_V4SF)
2137 return "movaps\t{%1, %0|%0, %1}";
2139 return "movdqa\t{%1, %0|%0, %1}";
2144 [(set_attr "type" "ssemov,ssemov,ssemov")
2146 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2147 (const_string "V4SF")
2149 (eq_attr "alternative" "0,1")
2151 (ne (symbol_ref "optimize_size")
2153 (const_string "V4SF")
2154 (const_string "TI"))
2155 (eq_attr "alternative" "2")
2157 (ne (symbol_ref "optimize_size")
2159 (const_string "V4SF")
2160 (const_string "TI"))]
2161 (const_string "TI")))])
2163 (define_insn "*movti_rex64"
2164 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2165 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2167 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2169 switch (which_alternative)
2175 if (get_attr_mode (insn) == MODE_V4SF)
2176 return "xorps\t%0, %0";
2178 return "pxor\t%0, %0";
2181 if (get_attr_mode (insn) == MODE_V4SF)
2182 return "movaps\t{%1, %0|%0, %1}";
2184 return "movdqa\t{%1, %0|%0, %1}";
2189 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2191 (cond [(eq_attr "alternative" "2,3")
2193 (ne (symbol_ref "optimize_size")
2195 (const_string "V4SF")
2196 (const_string "TI"))
2197 (eq_attr "alternative" "4")
2199 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2201 (ne (symbol_ref "optimize_size")
2203 (const_string "V4SF")
2204 (const_string "TI"))]
2205 (const_string "DI")))])
2208 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2209 (match_operand:TI 1 "general_operand" ""))]
2210 "reload_completed && !SSE_REG_P (operands[0])
2211 && !SSE_REG_P (operands[1])"
2213 "ix86_split_long_move (operands); DONE;")
2215 (define_expand "movsf"
2216 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2217 (match_operand:SF 1 "general_operand" ""))]
2219 "ix86_expand_move (SFmode, operands); DONE;")
2221 (define_insn "*pushsf"
2222 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2223 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2226 /* Anything else should be already split before reg-stack. */
2227 gcc_assert (which_alternative == 1);
2228 return "push{l}\t%1";
2230 [(set_attr "type" "multi,push,multi")
2231 (set_attr "unit" "i387,*,*")
2232 (set_attr "mode" "SF,SI,SF")])
2234 (define_insn "*pushsf_rex64"
2235 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2236 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2239 /* Anything else should be already split before reg-stack. */
2240 gcc_assert (which_alternative == 1);
2241 return "push{q}\t%q1";
2243 [(set_attr "type" "multi,push,multi")
2244 (set_attr "unit" "i387,*,*")
2245 (set_attr "mode" "SF,DI,SF")])
2248 [(set (match_operand:SF 0 "push_operand" "")
2249 (match_operand:SF 1 "memory_operand" ""))]
2251 && GET_CODE (operands[1]) == MEM
2252 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2253 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2256 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2259 ;; %%% Kill this when call knows how to work this out.
2261 [(set (match_operand:SF 0 "push_operand" "")
2262 (match_operand:SF 1 "any_fp_register_operand" ""))]
2264 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2265 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2268 [(set (match_operand:SF 0 "push_operand" "")
2269 (match_operand:SF 1 "any_fp_register_operand" ""))]
2271 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2272 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2274 (define_insn "*movsf_1"
2275 [(set (match_operand:SF 0 "nonimmediate_operand"
2276 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2277 (match_operand:SF 1 "general_operand"
2278 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2279 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2280 && (reload_in_progress || reload_completed
2281 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2282 || GET_CODE (operands[1]) != CONST_DOUBLE
2283 || memory_operand (operands[0], SFmode))"
2285 switch (which_alternative)
2288 return output_387_reg_move (insn, operands);
2291 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2292 return "fstp%z0\t%y0";
2294 return "fst%z0\t%y0";
2297 return standard_80387_constant_opcode (operands[1]);
2301 return "mov{l}\t{%1, %0|%0, %1}";
2303 if (get_attr_mode (insn) == MODE_TI)
2304 return "pxor\t%0, %0";
2306 return "xorps\t%0, %0";
2308 if (get_attr_mode (insn) == MODE_V4SF)
2309 return "movaps\t{%1, %0|%0, %1}";
2311 return "movss\t{%1, %0|%0, %1}";
2314 return "movss\t{%1, %0|%0, %1}";
2318 return "movd\t{%1, %0|%0, %1}";
2321 return "movq\t{%1, %0|%0, %1}";
2327 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2329 (cond [(eq_attr "alternative" "3,4,9,10")
2331 (eq_attr "alternative" "5")
2333 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2335 (ne (symbol_ref "TARGET_SSE2")
2337 (eq (symbol_ref "optimize_size")
2340 (const_string "V4SF"))
2341 /* For architectures resolving dependencies on
2342 whole SSE registers use APS move to break dependency
2343 chains, otherwise use short move to avoid extra work.
2345 Do the same for architectures resolving dependencies on
2346 the parts. While in DF mode it is better to always handle
2347 just register parts, the SF mode is different due to lack
2348 of instructions to load just part of the register. It is
2349 better to maintain the whole registers in single format
2350 to avoid problems on using packed logical operations. */
2351 (eq_attr "alternative" "6")
2353 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2355 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2357 (const_string "V4SF")
2358 (const_string "SF"))
2359 (eq_attr "alternative" "11")
2360 (const_string "DI")]
2361 (const_string "SF")))])
2363 (define_insn "*swapsf"
2364 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2365 (match_operand:SF 1 "fp_register_operand" "+f"))
2368 "reload_completed || TARGET_80387"
2370 if (STACK_TOP_P (operands[0]))
2375 [(set_attr "type" "fxch")
2376 (set_attr "mode" "SF")])
2378 (define_expand "movdf"
2379 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2380 (match_operand:DF 1 "general_operand" ""))]
2382 "ix86_expand_move (DFmode, operands); DONE;")
2384 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2385 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2386 ;; On the average, pushdf using integers can be still shorter. Allow this
2387 ;; pattern for optimize_size too.
2389 (define_insn "*pushdf_nointeger"
2390 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2391 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2392 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2394 /* This insn should be already split before reg-stack. */
2397 [(set_attr "type" "multi")
2398 (set_attr "unit" "i387,*,*,*")
2399 (set_attr "mode" "DF,SI,SI,DF")])
2401 (define_insn "*pushdf_integer"
2402 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2403 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2404 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2406 /* This insn should be already split before reg-stack. */
2409 [(set_attr "type" "multi")
2410 (set_attr "unit" "i387,*,*")
2411 (set_attr "mode" "DF,SI,DF")])
2413 ;; %%% Kill this when call knows how to work this out.
2415 [(set (match_operand:DF 0 "push_operand" "")
2416 (match_operand:DF 1 "any_fp_register_operand" ""))]
2417 "!TARGET_64BIT && reload_completed"
2418 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2419 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2423 [(set (match_operand:DF 0 "push_operand" "")
2424 (match_operand:DF 1 "any_fp_register_operand" ""))]
2425 "TARGET_64BIT && reload_completed"
2426 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2427 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2431 [(set (match_operand:DF 0 "push_operand" "")
2432 (match_operand:DF 1 "general_operand" ""))]
2435 "ix86_split_long_move (operands); DONE;")
2437 ;; Moving is usually shorter when only FP registers are used. This separate
2438 ;; movdf pattern avoids the use of integer registers for FP operations
2439 ;; when optimizing for size.
2441 (define_insn "*movdf_nointeger"
2442 [(set (match_operand:DF 0 "nonimmediate_operand"
2443 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2444 (match_operand:DF 1 "general_operand"
2445 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2446 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2447 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2448 && (reload_in_progress || reload_completed
2449 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2450 || GET_CODE (operands[1]) != CONST_DOUBLE
2451 || memory_operand (operands[0], DFmode))"
2453 switch (which_alternative)
2456 return output_387_reg_move (insn, operands);
2459 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2460 return "fstp%z0\t%y0";
2462 return "fst%z0\t%y0";
2465 return standard_80387_constant_opcode (operands[1]);
2471 switch (get_attr_mode (insn))
2474 return "xorps\t%0, %0";
2476 return "xorpd\t%0, %0";
2478 return "pxor\t%0, %0";
2485 switch (get_attr_mode (insn))
2488 return "movaps\t{%1, %0|%0, %1}";
2490 return "movapd\t{%1, %0|%0, %1}";
2492 return "movdqa\t{%1, %0|%0, %1}";
2494 return "movq\t{%1, %0|%0, %1}";
2496 return "movsd\t{%1, %0|%0, %1}";
2498 return "movlpd\t{%1, %0|%0, %1}";
2500 return "movlps\t{%1, %0|%0, %1}";
2509 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2511 (cond [(eq_attr "alternative" "0,1,2")
2513 (eq_attr "alternative" "3,4")
2516 /* For SSE1, we have many fewer alternatives. */
2517 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2518 (cond [(eq_attr "alternative" "5,6")
2519 (const_string "V4SF")
2521 (const_string "V2SF"))
2523 /* xorps is one byte shorter. */
2524 (eq_attr "alternative" "5")
2525 (cond [(ne (symbol_ref "optimize_size")
2527 (const_string "V4SF")
2528 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2532 (const_string "V2DF"))
2534 /* For architectures resolving dependencies on
2535 whole SSE registers use APD move to break dependency
2536 chains, otherwise use short move to avoid extra work.
2538 movaps encodes one byte shorter. */
2539 (eq_attr "alternative" "6")
2541 [(ne (symbol_ref "optimize_size")
2543 (const_string "V4SF")
2544 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2546 (const_string "V2DF")
2548 (const_string "DF"))
2549 /* For architectures resolving dependencies on register
2550 parts we may avoid extra work to zero out upper part
2552 (eq_attr "alternative" "7")
2554 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2556 (const_string "V1DF")
2557 (const_string "DF"))
2559 (const_string "DF")))])
2561 (define_insn "*movdf_integer"
2562 [(set (match_operand:DF 0 "nonimmediate_operand"
2563 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2564 (match_operand:DF 1 "general_operand"
2565 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2566 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2567 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2568 && (reload_in_progress || reload_completed
2569 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2570 || GET_CODE (operands[1]) != CONST_DOUBLE
2571 || memory_operand (operands[0], DFmode))"
2573 switch (which_alternative)
2576 return output_387_reg_move (insn, operands);
2579 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2580 return "fstp%z0\t%y0";
2582 return "fst%z0\t%y0";
2585 return standard_80387_constant_opcode (operands[1]);
2592 switch (get_attr_mode (insn))
2595 return "xorps\t%0, %0";
2597 return "xorpd\t%0, %0";
2599 return "pxor\t%0, %0";
2606 switch (get_attr_mode (insn))
2609 return "movaps\t{%1, %0|%0, %1}";
2611 return "movapd\t{%1, %0|%0, %1}";
2613 return "movdqa\t{%1, %0|%0, %1}";
2615 return "movq\t{%1, %0|%0, %1}";
2617 return "movsd\t{%1, %0|%0, %1}";
2619 return "movlpd\t{%1, %0|%0, %1}";
2621 return "movlps\t{%1, %0|%0, %1}";
2630 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2632 (cond [(eq_attr "alternative" "0,1,2")
2634 (eq_attr "alternative" "3,4")
2637 /* For SSE1, we have many fewer alternatives. */
2638 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2639 (cond [(eq_attr "alternative" "5,6")
2640 (const_string "V4SF")
2642 (const_string "V2SF"))
2644 /* xorps is one byte shorter. */
2645 (eq_attr "alternative" "5")
2646 (cond [(ne (symbol_ref "optimize_size")
2648 (const_string "V4SF")
2649 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2653 (const_string "V2DF"))
2655 /* For architectures resolving dependencies on
2656 whole SSE registers use APD move to break dependency
2657 chains, otherwise use short move to avoid extra work.
2659 movaps encodes one byte shorter. */
2660 (eq_attr "alternative" "6")
2662 [(ne (symbol_ref "optimize_size")
2664 (const_string "V4SF")
2665 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2667 (const_string "V2DF")
2669 (const_string "DF"))
2670 /* For architectures resolving dependencies on register
2671 parts we may avoid extra work to zero out upper part
2673 (eq_attr "alternative" "7")
2675 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677 (const_string "V1DF")
2678 (const_string "DF"))
2680 (const_string "DF")))])
2683 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2684 (match_operand:DF 1 "general_operand" ""))]
2686 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2687 && ! (ANY_FP_REG_P (operands[0]) ||
2688 (GET_CODE (operands[0]) == SUBREG
2689 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2690 && ! (ANY_FP_REG_P (operands[1]) ||
2691 (GET_CODE (operands[1]) == SUBREG
2692 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2694 "ix86_split_long_move (operands); DONE;")
2696 (define_insn "*swapdf"
2697 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2698 (match_operand:DF 1 "fp_register_operand" "+f"))
2701 "reload_completed || TARGET_80387"
2703 if (STACK_TOP_P (operands[0]))
2708 [(set_attr "type" "fxch")
2709 (set_attr "mode" "DF")])
2711 (define_expand "movxf"
2712 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2713 (match_operand:XF 1 "general_operand" ""))]
2715 "ix86_expand_move (XFmode, operands); DONE;")
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2719 ;; Pushing using integer instructions is longer except for constants
2720 ;; and direct memory references.
2721 ;; (assuming that any given constant is pushed only once, but this ought to be
2722 ;; handled elsewhere).
2724 (define_insn "*pushxf_nointeger"
2725 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2726 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2729 /* This insn should be already split before reg-stack. */
2732 [(set_attr "type" "multi")
2733 (set_attr "unit" "i387,*,*")
2734 (set_attr "mode" "XF,SI,SI")])
2736 (define_insn "*pushxf_integer"
2737 [(set (match_operand:XF 0 "push_operand" "=<,<")
2738 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2741 /* This insn should be already split before reg-stack. */
2744 [(set_attr "type" "multi")
2745 (set_attr "unit" "i387,*")
2746 (set_attr "mode" "XF,SI")])
2749 [(set (match_operand 0 "push_operand" "")
2750 (match_operand 1 "general_operand" ""))]
2752 && (GET_MODE (operands[0]) == XFmode
2753 || GET_MODE (operands[0]) == DFmode)
2754 && !ANY_FP_REG_P (operands[1])"
2756 "ix86_split_long_move (operands); DONE;")
2759 [(set (match_operand:XF 0 "push_operand" "")
2760 (match_operand:XF 1 "any_fp_register_operand" ""))]
2762 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2763 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2764 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2767 [(set (match_operand:XF 0 "push_operand" "")
2768 (match_operand:XF 1 "any_fp_register_operand" ""))]
2770 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2771 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2772 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2774 ;; Do not use integer registers when optimizing for size
2775 (define_insn "*movxf_nointeger"
2776 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2777 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2779 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2780 && (reload_in_progress || reload_completed
2781 || GET_CODE (operands[1]) != CONST_DOUBLE
2782 || memory_operand (operands[0], XFmode))"
2784 switch (which_alternative)
2787 return output_387_reg_move (insn, operands);
2790 /* There is no non-popping store to memory for XFmode. So if
2791 we need one, follow the store with a load. */
2792 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2793 return "fstp%z0\t%y0\;fld%z0\t%y0";
2795 return "fstp%z0\t%y0";
2798 return standard_80387_constant_opcode (operands[1]);
2806 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2807 (set_attr "mode" "XF,XF,XF,SI,SI")])
2809 (define_insn "*movxf_integer"
2810 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2811 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2813 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2814 && (reload_in_progress || reload_completed
2815 || GET_CODE (operands[1]) != CONST_DOUBLE
2816 || memory_operand (operands[0], XFmode))"
2818 switch (which_alternative)
2821 return output_387_reg_move (insn, operands);
2824 /* There is no non-popping store to memory for XFmode. So if
2825 we need one, follow the store with a load. */
2826 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2827 return "fstp%z0\t%y0\;fld%z0\t%y0";
2829 return "fstp%z0\t%y0";
2832 return standard_80387_constant_opcode (operands[1]);
2841 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842 (set_attr "mode" "XF,XF,XF,SI,SI")])
2845 [(set (match_operand 0 "nonimmediate_operand" "")
2846 (match_operand 1 "general_operand" ""))]
2848 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2849 && GET_MODE (operands[0]) == XFmode
2850 && ! (ANY_FP_REG_P (operands[0]) ||
2851 (GET_CODE (operands[0]) == SUBREG
2852 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2853 && ! (ANY_FP_REG_P (operands[1]) ||
2854 (GET_CODE (operands[1]) == SUBREG
2855 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2857 "ix86_split_long_move (operands); DONE;")
2860 [(set (match_operand 0 "register_operand" "")
2861 (match_operand 1 "memory_operand" ""))]
2863 && GET_CODE (operands[1]) == MEM
2864 && (GET_MODE (operands[0]) == XFmode
2865 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2866 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2867 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2868 [(set (match_dup 0) (match_dup 1))]
2870 rtx c = get_pool_constant (XEXP (operands[1], 0));
2871 rtx r = operands[0];
2873 if (GET_CODE (r) == SUBREG)
2878 if (!standard_sse_constant_p (c))
2881 else if (FP_REG_P (r))
2883 if (!standard_80387_constant_p (c))
2886 else if (MMX_REG_P (r))
2892 (define_insn "swapxf"
2893 [(set (match_operand:XF 0 "register_operand" "+f")
2894 (match_operand:XF 1 "register_operand" "+f"))
2899 if (STACK_TOP_P (operands[0]))
2904 [(set_attr "type" "fxch")
2905 (set_attr "mode" "XF")])
2907 (define_expand "movtf"
2908 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909 (match_operand:TF 1 "nonimmediate_operand" ""))]
2912 ix86_expand_move (TFmode, operands);
2916 (define_insn "*movtf_internal"
2917 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2920 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2922 switch (which_alternative)
2928 if (get_attr_mode (insn) == MODE_V4SF)
2929 return "xorps\t%0, %0";
2931 return "pxor\t%0, %0";
2934 if (get_attr_mode (insn) == MODE_V4SF)
2935 return "movaps\t{%1, %0|%0, %1}";
2937 return "movdqa\t{%1, %0|%0, %1}";
2942 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2944 (cond [(eq_attr "alternative" "2,3")
2946 (ne (symbol_ref "optimize_size")
2948 (const_string "V4SF")
2949 (const_string "TI"))
2950 (eq_attr "alternative" "4")
2952 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2954 (ne (symbol_ref "optimize_size")
2956 (const_string "V4SF")
2957 (const_string "TI"))]
2958 (const_string "DI")))])
2961 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962 (match_operand:TF 1 "general_operand" ""))]
2963 "reload_completed && !SSE_REG_P (operands[0])
2964 && !SSE_REG_P (operands[1])"
2966 "ix86_split_long_move (operands); DONE;")
2968 ;; Zero extension instructions
2970 (define_expand "zero_extendhisi2"
2971 [(set (match_operand:SI 0 "register_operand" "")
2972 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2975 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2977 operands[1] = force_reg (HImode, operands[1]);
2978 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2983 (define_insn "zero_extendhisi2_and"
2984 [(set (match_operand:SI 0 "register_operand" "=r")
2985 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986 (clobber (reg:CC FLAGS_REG))]
2987 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2989 [(set_attr "type" "alu1")
2990 (set_attr "mode" "SI")])
2993 [(set (match_operand:SI 0 "register_operand" "")
2994 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995 (clobber (reg:CC FLAGS_REG))]
2996 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998 (clobber (reg:CC FLAGS_REG))])]
3001 (define_insn "*zero_extendhisi2_movzwl"
3002 [(set (match_operand:SI 0 "register_operand" "=r")
3003 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005 "movz{wl|x}\t{%1, %0|%0, %1}"
3006 [(set_attr "type" "imovx")
3007 (set_attr "mode" "SI")])
3009 (define_expand "zero_extendqihi2"
3011 [(set (match_operand:HI 0 "register_operand" "")
3012 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013 (clobber (reg:CC FLAGS_REG))])]
3017 (define_insn "*zero_extendqihi2_and"
3018 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020 (clobber (reg:CC FLAGS_REG))]
3021 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3023 [(set_attr "type" "alu1")
3024 (set_attr "mode" "HI")])
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027 [(set (match_operand:HI 0 "register_operand" "=r,r")
3028 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029 (clobber (reg:CC FLAGS_REG))]
3030 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032 [(set_attr "type" "imovx,alu1")
3033 (set_attr "mode" "HI")])
3035 (define_insn "*zero_extendqihi2_movzbw"
3036 [(set (match_operand:HI 0 "register_operand" "=r")
3037 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3038 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3039 "movz{bw|x}\t{%1, %0|%0, %1}"
3040 [(set_attr "type" "imovx")
3041 (set_attr "mode" "HI")])
3043 ;; For the movzbw case strip only the clobber
3045 [(set (match_operand:HI 0 "register_operand" "")
3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3047 (clobber (reg:CC FLAGS_REG))]
3049 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3050 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3051 [(set (match_operand:HI 0 "register_operand" "")
3052 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3054 ;; When source and destination does not overlap, clear destination
3055 ;; first and then do the movb
3057 [(set (match_operand:HI 0 "register_operand" "")
3058 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3059 (clobber (reg:CC FLAGS_REG))]
3061 && ANY_QI_REG_P (operands[0])
3062 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3063 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3064 [(set (match_dup 0) (const_int 0))
3065 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3066 "operands[2] = gen_lowpart (QImode, operands[0]);")
3068 ;; Rest is handled by single and.
3070 [(set (match_operand:HI 0 "register_operand" "")
3071 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3072 (clobber (reg:CC FLAGS_REG))]
3074 && true_regnum (operands[0]) == true_regnum (operands[1])"
3075 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3076 (clobber (reg:CC FLAGS_REG))])]
3079 (define_expand "zero_extendqisi2"
3081 [(set (match_operand:SI 0 "register_operand" "")
3082 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3083 (clobber (reg:CC FLAGS_REG))])]
3087 (define_insn "*zero_extendqisi2_and"
3088 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3089 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3090 (clobber (reg:CC FLAGS_REG))]
3091 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3093 [(set_attr "type" "alu1")
3094 (set_attr "mode" "SI")])
3096 (define_insn "*zero_extendqisi2_movzbw_and"
3097 [(set (match_operand:SI 0 "register_operand" "=r,r")
3098 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3099 (clobber (reg:CC FLAGS_REG))]
3100 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3102 [(set_attr "type" "imovx,alu1")
3103 (set_attr "mode" "SI")])
3105 (define_insn "*zero_extendqisi2_movzbw"
3106 [(set (match_operand:SI 0 "register_operand" "=r")
3107 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3108 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3109 "movz{bl|x}\t{%1, %0|%0, %1}"
3110 [(set_attr "type" "imovx")
3111 (set_attr "mode" "SI")])
3113 ;; For the movzbl case strip only the clobber
3115 [(set (match_operand:SI 0 "register_operand" "")
3116 (zero_extend:SI (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]))"
3122 (zero_extend:SI (match_dup 1)))])
3124 ;; When source and destination does not overlap, clear destination
3125 ;; first and then do the movb
3127 [(set (match_operand:SI 0 "register_operand" "")
3128 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3129 (clobber (reg:CC FLAGS_REG))]
3131 && ANY_QI_REG_P (operands[0])
3132 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3133 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3134 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3135 [(set (match_dup 0) (const_int 0))
3136 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3137 "operands[2] = gen_lowpart (QImode, operands[0]);")
3139 ;; Rest is handled by single and.
3141 [(set (match_operand:SI 0 "register_operand" "")
3142 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3143 (clobber (reg:CC FLAGS_REG))]
3145 && true_regnum (operands[0]) == true_regnum (operands[1])"
3146 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3147 (clobber (reg:CC FLAGS_REG))])]
3150 ;; %%% Kill me once multi-word ops are sane.
3151 (define_expand "zero_extendsidi2"
3152 [(set (match_operand:DI 0 "register_operand" "=r")
3153 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3157 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3162 (define_insn "zero_extendsidi2_32"
3163 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3164 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3165 (clobber (reg:CC FLAGS_REG))]
3171 movd\t{%1, %0|%0, %1}
3172 movd\t{%1, %0|%0, %1}"
3173 [(set_attr "mode" "SI,SI,SI,DI,TI")
3174 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3176 (define_insn "zero_extendsidi2_rex64"
3177 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3178 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3181 mov\t{%k1, %k0|%k0, %k1}
3183 movd\t{%1, %0|%0, %1}
3184 movd\t{%1, %0|%0, %1}"
3185 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3186 (set_attr "mode" "SI,DI,SI,SI")])
3189 [(set (match_operand:DI 0 "memory_operand" "")
3190 (zero_extend:DI (match_dup 0)))]
3192 [(set (match_dup 4) (const_int 0))]
3193 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3196 [(set (match_operand:DI 0 "register_operand" "")
3197 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3198 (clobber (reg:CC FLAGS_REG))]
3199 "!TARGET_64BIT && reload_completed
3200 && true_regnum (operands[0]) == true_regnum (operands[1])"
3201 [(set (match_dup 4) (const_int 0))]
3202 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3205 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3206 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3207 (clobber (reg:CC FLAGS_REG))]
3208 "!TARGET_64BIT && reload_completed
3209 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3210 [(set (match_dup 3) (match_dup 1))
3211 (set (match_dup 4) (const_int 0))]
3212 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3214 (define_insn "zero_extendhidi2"
3215 [(set (match_operand:DI 0 "register_operand" "=r")
3216 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3218 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3219 [(set_attr "type" "imovx")
3220 (set_attr "mode" "DI")])
3222 (define_insn "zero_extendqidi2"
3223 [(set (match_operand:DI 0 "register_operand" "=r")
3224 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3226 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3227 [(set_attr "type" "imovx")
3228 (set_attr "mode" "DI")])
3230 ;; Sign extension instructions
3232 (define_expand "extendsidi2"
3233 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3234 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3235 (clobber (reg:CC FLAGS_REG))
3236 (clobber (match_scratch:SI 2 ""))])]
3241 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3246 (define_insn "*extendsidi2_1"
3247 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3248 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3249 (clobber (reg:CC FLAGS_REG))
3250 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3254 (define_insn "extendsidi2_rex64"
3255 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3256 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3260 movs{lq|x}\t{%1,%0|%0, %1}"
3261 [(set_attr "type" "imovx")
3262 (set_attr "mode" "DI")
3263 (set_attr "prefix_0f" "0")
3264 (set_attr "modrm" "0,1")])
3266 (define_insn "extendhidi2"
3267 [(set (match_operand:DI 0 "register_operand" "=r")
3268 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3270 "movs{wq|x}\t{%1,%0|%0, %1}"
3271 [(set_attr "type" "imovx")
3272 (set_attr "mode" "DI")])
3274 (define_insn "extendqidi2"
3275 [(set (match_operand:DI 0 "register_operand" "=r")
3276 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278 "movs{bq|x}\t{%1,%0|%0, %1}"
3279 [(set_attr "type" "imovx")
3280 (set_attr "mode" "DI")])
3282 ;; Extend to memory case when source register does die.
3284 [(set (match_operand:DI 0 "memory_operand" "")
3285 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3286 (clobber (reg:CC FLAGS_REG))
3287 (clobber (match_operand:SI 2 "register_operand" ""))]
3289 && dead_or_set_p (insn, operands[1])
3290 && !reg_mentioned_p (operands[1], operands[0]))"
3291 [(set (match_dup 3) (match_dup 1))
3292 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3293 (clobber (reg:CC FLAGS_REG))])
3294 (set (match_dup 4) (match_dup 1))]
3295 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3297 ;; Extend to memory case when source register does not die.
3299 [(set (match_operand:DI 0 "memory_operand" "")
3300 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3301 (clobber (reg:CC FLAGS_REG))
3302 (clobber (match_operand:SI 2 "register_operand" ""))]
3306 split_di (&operands[0], 1, &operands[3], &operands[4]);
3308 emit_move_insn (operands[3], operands[1]);
3310 /* Generate a cltd if possible and doing so it profitable. */
3311 if (true_regnum (operands[1]) == 0
3312 && true_regnum (operands[2]) == 1
3313 && (optimize_size || TARGET_USE_CLTD))
3315 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3319 emit_move_insn (operands[2], operands[1]);
3320 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3322 emit_move_insn (operands[4], operands[2]);
3326 ;; Extend to register case. Optimize case where source and destination
3327 ;; registers match and cases where we can use cltd.
3329 [(set (match_operand:DI 0 "register_operand" "")
3330 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3331 (clobber (reg:CC FLAGS_REG))
3332 (clobber (match_scratch:SI 2 ""))]
3336 split_di (&operands[0], 1, &operands[3], &operands[4]);
3338 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3339 emit_move_insn (operands[3], operands[1]);
3341 /* Generate a cltd if possible and doing so it profitable. */
3342 if (true_regnum (operands[3]) == 0
3343 && (optimize_size || TARGET_USE_CLTD))
3345 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3349 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3350 emit_move_insn (operands[4], operands[1]);
3352 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3356 (define_insn "extendhisi2"
3357 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3358 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3361 switch (get_attr_prefix_0f (insn))
3364 return "{cwtl|cwde}";
3366 return "movs{wl|x}\t{%1,%0|%0, %1}";
3369 [(set_attr "type" "imovx")
3370 (set_attr "mode" "SI")
3371 (set (attr "prefix_0f")
3372 ;; movsx is short decodable while cwtl is vector decoded.
3373 (if_then_else (and (eq_attr "cpu" "!k6")
3374 (eq_attr "alternative" "0"))
3376 (const_string "1")))
3378 (if_then_else (eq_attr "prefix_0f" "0")