1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
77 ; Other random patterns
87 ; For SSE/MMX support:
88 (UNSPEC_FIX_NOTRUNC 30)
96 (UNSPEC_NOP 38) ; prevents combiner cleverness
107 ; Generic math support
109 (UNSPEC_IEEE_MIN 51) ; not commutative
110 (UNSPEC_IEEE_MAX 52) ; not commutative
123 (UNSPEC_FRNDINT_FLOOR 70)
124 (UNSPEC_FRNDINT_CEIL 71)
125 (UNSPEC_FRNDINT_TRUNC 72)
126 (UNSPEC_FRNDINT_MASK_PM 73)
127 (UNSPEC_FIST_FLOOR 74)
128 (UNSPEC_FIST_CEIL 75)
130 ; x87 Double output FP
131 (UNSPEC_SINCOS_COS 80)
132 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_XTRACT_FRACT 84)
136 (UNSPEC_XTRACT_EXP 85)
137 (UNSPEC_FSCALE_FRACT 86)
138 (UNSPEC_FSCALE_EXP 87)
147 (UNSPEC_SP_TLS_SET 102)
148 (UNSPEC_SP_TLS_TEST 103)
152 [(UNSPECV_BLOCKAGE 0)
153 (UNSPECV_STACK_PROBE 1)
162 (UNSPECV_CMPXCHG_1 10)
163 (UNSPECV_CMPXCHG_2 11)
168 ;; Registers by name.
177 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
180 ;; In C guard expressions, put expressions which may be compile-time
181 ;; constants first. This allows for better optimization. For
182 ;; example, write "TARGET_64BIT && reload_completed", not
183 ;; "reload_completed && TARGET_64BIT".
186 ;; Processor type. This attribute must exactly match the processor_type
187 ;; enumeration in i386.h.
188 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
189 (const (symbol_ref "ix86_tune")))
191 ;; A basic instruction type. Refinements due to arguments to be
192 ;; provided in other attributes.
195 alu,alu1,negnot,imov,imovx,lea,
196 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
197 icmp,test,ibr,setcc,icmov,
198 push,pop,call,callv,leave,
200 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
201 sselog,sselog1,sseiadd,sseishft,sseimul,
202 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
203 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
204 (const_string "other"))
206 ;; Main data type used by the insn
208 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
209 (const_string "unknown"))
211 ;; The CPU unit operations uses.
212 (define_attr "unit" "integer,i387,sse,mmx,unknown"
213 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
214 (const_string "i387")
215 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
216 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
218 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
220 (eq_attr "type" "other")
221 (const_string "unknown")]
222 (const_string "integer")))
224 ;; The (bounding maximum) length of an instruction immediate.
225 (define_attr "length_immediate" ""
226 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
228 (eq_attr "unit" "i387,sse,mmx")
230 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
232 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
233 (eq_attr "type" "imov,test")
234 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
235 (eq_attr "type" "call")
236 (if_then_else (match_operand 0 "constant_call_address_operand" "")
239 (eq_attr "type" "callv")
240 (if_then_else (match_operand 1 "constant_call_address_operand" "")
243 ;; We don't know the size before shorten_branches. Expect
244 ;; the instruction to fit for better scheduling.
245 (eq_attr "type" "ibr")
248 (symbol_ref "/* Update immediate_length and other attributes! */
249 gcc_unreachable (),1")))
251 ;; The (bounding maximum) length of an instruction address.
252 (define_attr "length_address" ""
253 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
255 (and (eq_attr "type" "call")
256 (match_operand 0 "constant_call_address_operand" ""))
258 (and (eq_attr "type" "callv")
259 (match_operand 1 "constant_call_address_operand" ""))
262 (symbol_ref "ix86_attr_length_address_default (insn)")))
264 ;; Set when length prefix is used.
265 (define_attr "prefix_data16" ""
266 (if_then_else (ior (eq_attr "mode" "HI")
267 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
271 ;; Set when string REP prefix is used.
272 (define_attr "prefix_rep" ""
273 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
277 ;; Set when 0f opcode prefix is used.
278 (define_attr "prefix_0f" ""
280 (ior (eq_attr "type" "imovx,setcc,icmov")
281 (eq_attr "unit" "sse,mmx"))
285 ;; Set when REX opcode prefix is used.
286 (define_attr "prefix_rex" ""
287 (cond [(and (eq_attr "mode" "DI")
288 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
290 (and (eq_attr "mode" "QI")
291 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
294 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
300 ;; Set when modrm byte is used.
301 (define_attr "modrm" ""
302 (cond [(eq_attr "type" "str,cld,leave")
304 (eq_attr "unit" "i387")
306 (and (eq_attr "type" "incdec")
307 (ior (match_operand:SI 1 "register_operand" "")
308 (match_operand:HI 1 "register_operand" "")))
310 (and (eq_attr "type" "push")
311 (not (match_operand 1 "memory_operand" "")))
313 (and (eq_attr "type" "pop")
314 (not (match_operand 0 "memory_operand" "")))
316 (and (eq_attr "type" "imov")
317 (ior (and (match_operand 0 "register_operand" "")
318 (match_operand 1 "immediate_operand" ""))
319 (ior (and (match_operand 0 "ax_reg_operand" "")
320 (match_operand 1 "memory_displacement_only_operand" ""))
321 (and (match_operand 0 "memory_displacement_only_operand" "")
322 (match_operand 1 "ax_reg_operand" "")))))
324 (and (eq_attr "type" "call")
325 (match_operand 0 "constant_call_address_operand" ""))
327 (and (eq_attr "type" "callv")
328 (match_operand 1 "constant_call_address_operand" ""))
333 ;; The (bounding maximum) length of an instruction in bytes.
334 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
335 ;; Later we may want to split them and compute proper length as for
337 (define_attr "length" ""
338 (cond [(eq_attr "type" "other,multi,fistp,frndint")
340 (eq_attr "type" "fcmp")
342 (eq_attr "unit" "i387")
344 (plus (attr "prefix_data16")
345 (attr "length_address")))]
346 (plus (plus (attr "modrm")
347 (plus (attr "prefix_0f")
348 (plus (attr "prefix_rex")
350 (plus (attr "prefix_rep")
351 (plus (attr "prefix_data16")
352 (plus (attr "length_immediate")
353 (attr "length_address")))))))
355 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
356 ;; `store' if there is a simple memory reference therein, or `unknown'
357 ;; if the instruction is complex.
359 (define_attr "memory" "none,load,store,both,unknown"
360 (cond [(eq_attr "type" "other,multi,str")
361 (const_string "unknown")
362 (eq_attr "type" "lea,fcmov,fpspc,cld")
363 (const_string "none")
364 (eq_attr "type" "fistp,leave")
365 (const_string "both")
366 (eq_attr "type" "frndint")
367 (const_string "load")
368 (eq_attr "type" "push")
369 (if_then_else (match_operand 1 "memory_operand" "")
370 (const_string "both")
371 (const_string "store"))
372 (eq_attr "type" "pop")
373 (if_then_else (match_operand 0 "memory_operand" "")
374 (const_string "both")
375 (const_string "load"))
376 (eq_attr "type" "setcc")
377 (if_then_else (match_operand 0 "memory_operand" "")
378 (const_string "store")
379 (const_string "none"))
380 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
381 (if_then_else (ior (match_operand 0 "memory_operand" "")
382 (match_operand 1 "memory_operand" ""))
383 (const_string "load")
384 (const_string "none"))
385 (eq_attr "type" "ibr")
386 (if_then_else (match_operand 0 "memory_operand" "")
387 (const_string "load")
388 (const_string "none"))
389 (eq_attr "type" "call")
390 (if_then_else (match_operand 0 "constant_call_address_operand" "")
391 (const_string "none")
392 (const_string "load"))
393 (eq_attr "type" "callv")
394 (if_then_else (match_operand 1 "constant_call_address_operand" "")
395 (const_string "none")
396 (const_string "load"))
397 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
398 (match_operand 1 "memory_operand" ""))
399 (const_string "both")
400 (and (match_operand 0 "memory_operand" "")
401 (match_operand 1 "memory_operand" ""))
402 (const_string "both")
403 (match_operand 0 "memory_operand" "")
404 (const_string "store")
405 (match_operand 1 "memory_operand" "")
406 (const_string "load")
408 "!alu1,negnot,ishift1,
409 imov,imovx,icmp,test,
411 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
412 mmx,mmxmov,mmxcmp,mmxcvt")
413 (match_operand 2 "memory_operand" ""))
414 (const_string "load")
415 (and (eq_attr "type" "icmov")
416 (match_operand 3 "memory_operand" ""))
417 (const_string "load")
419 (const_string "none")))
421 ;; Indicates if an instruction has both an immediate and a displacement.
423 (define_attr "imm_disp" "false,true,unknown"
424 (cond [(eq_attr "type" "other,multi")
425 (const_string "unknown")
426 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
427 (and (match_operand 0 "memory_displacement_operand" "")
428 (match_operand 1 "immediate_operand" "")))
429 (const_string "true")
430 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
431 (and (match_operand 0 "memory_displacement_operand" "")
432 (match_operand 2 "immediate_operand" "")))
433 (const_string "true")
435 (const_string "false")))
437 ;; Indicates if an FP operation has an integer source.
439 (define_attr "fp_int_src" "false,true"
440 (const_string "false"))
442 ;; Defines rounding mode of an FP operation.
444 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
445 (const_string "any"))
447 ;; Describe a user's asm statement.
448 (define_asm_attributes
449 [(set_attr "length" "128")
450 (set_attr "type" "multi")])
452 ;; All x87 floating point modes
453 (define_mode_macro X87MODEF [SF DF XF])
455 ;; All integer modes handled by x87 fisttp operator.
456 (define_mode_macro X87MODEI [HI SI DI])
458 ;; All integer modes handled by integer x87 operators.
459 (define_mode_macro X87MODEI12 [HI SI])
461 ;; All SSE floating point modes
462 (define_mode_macro SSEMODEF [SF DF])
464 ;; All integer modes handled by SSE cvtts?2si* operators.
465 (define_mode_macro SSEMODEI24 [SI DI])
468 ;; Scheduling descriptions
470 (include "pentium.md")
473 (include "athlon.md")
476 ;; Operand and operator predicates
478 (include "predicates.md")
481 ;; Compare instructions.
483 ;; All compare insns have expanders that save the operands away without
484 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
485 ;; after the cmp) will actually emit the cmpM.
487 (define_expand "cmpti"
488 [(set (reg:CC FLAGS_REG)
489 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
490 (match_operand:TI 1 "x86_64_general_operand" "")))]
493 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
494 operands[0] = force_reg (TImode, operands[0]);
495 ix86_compare_op0 = operands[0];
496 ix86_compare_op1 = operands[1];
500 (define_expand "cmpdi"
501 [(set (reg:CC FLAGS_REG)
502 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
503 (match_operand:DI 1 "x86_64_general_operand" "")))]
506 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
507 operands[0] = force_reg (DImode, operands[0]);
508 ix86_compare_op0 = operands[0];
509 ix86_compare_op1 = operands[1];
513 (define_expand "cmpsi"
514 [(set (reg:CC FLAGS_REG)
515 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
516 (match_operand:SI 1 "general_operand" "")))]
519 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
520 operands[0] = force_reg (SImode, operands[0]);
521 ix86_compare_op0 = operands[0];
522 ix86_compare_op1 = operands[1];
526 (define_expand "cmphi"
527 [(set (reg:CC FLAGS_REG)
528 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
529 (match_operand:HI 1 "general_operand" "")))]
532 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
533 operands[0] = force_reg (HImode, operands[0]);
534 ix86_compare_op0 = operands[0];
535 ix86_compare_op1 = operands[1];
539 (define_expand "cmpqi"
540 [(set (reg:CC FLAGS_REG)
541 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
542 (match_operand:QI 1 "general_operand" "")))]
545 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
546 operands[0] = force_reg (QImode, operands[0]);
547 ix86_compare_op0 = operands[0];
548 ix86_compare_op1 = operands[1];
552 (define_insn "cmpdi_ccno_1_rex64"
553 [(set (reg FLAGS_REG)
554 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
555 (match_operand:DI 1 "const0_operand" "n,n")))]
556 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
558 test{q}\t{%0, %0|%0, %0}
559 cmp{q}\t{%1, %0|%0, %1}"
560 [(set_attr "type" "test,icmp")
561 (set_attr "length_immediate" "0,1")
562 (set_attr "mode" "DI")])
564 (define_insn "*cmpdi_minus_1_rex64"
565 [(set (reg FLAGS_REG)
566 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
567 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
569 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
570 "cmp{q}\t{%1, %0|%0, %1}"
571 [(set_attr "type" "icmp")
572 (set_attr "mode" "DI")])
574 (define_expand "cmpdi_1_rex64"
575 [(set (reg:CC FLAGS_REG)
576 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
577 (match_operand:DI 1 "general_operand" "")))]
581 (define_insn "cmpdi_1_insn_rex64"
582 [(set (reg FLAGS_REG)
583 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
584 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
585 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
586 "cmp{q}\t{%1, %0|%0, %1}"
587 [(set_attr "type" "icmp")
588 (set_attr "mode" "DI")])
591 (define_insn "*cmpsi_ccno_1"
592 [(set (reg FLAGS_REG)
593 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
594 (match_operand:SI 1 "const0_operand" "n,n")))]
595 "ix86_match_ccmode (insn, CCNOmode)"
597 test{l}\t{%0, %0|%0, %0}
598 cmp{l}\t{%1, %0|%0, %1}"
599 [(set_attr "type" "test,icmp")
600 (set_attr "length_immediate" "0,1")
601 (set_attr "mode" "SI")])
603 (define_insn "*cmpsi_minus_1"
604 [(set (reg FLAGS_REG)
605 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
606 (match_operand:SI 1 "general_operand" "ri,mr"))
608 "ix86_match_ccmode (insn, CCGOCmode)"
609 "cmp{l}\t{%1, %0|%0, %1}"
610 [(set_attr "type" "icmp")
611 (set_attr "mode" "SI")])
613 (define_expand "cmpsi_1"
614 [(set (reg:CC FLAGS_REG)
615 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
616 (match_operand:SI 1 "general_operand" "ri,mr")))]
620 (define_insn "*cmpsi_1_insn"
621 [(set (reg FLAGS_REG)
622 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623 (match_operand:SI 1 "general_operand" "ri,mr")))]
624 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
625 && ix86_match_ccmode (insn, CCmode)"
626 "cmp{l}\t{%1, %0|%0, %1}"
627 [(set_attr "type" "icmp")
628 (set_attr "mode" "SI")])
630 (define_insn "*cmphi_ccno_1"
631 [(set (reg FLAGS_REG)
632 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
633 (match_operand:HI 1 "const0_operand" "n,n")))]
634 "ix86_match_ccmode (insn, CCNOmode)"
636 test{w}\t{%0, %0|%0, %0}
637 cmp{w}\t{%1, %0|%0, %1}"
638 [(set_attr "type" "test,icmp")
639 (set_attr "length_immediate" "0,1")
640 (set_attr "mode" "HI")])
642 (define_insn "*cmphi_minus_1"
643 [(set (reg FLAGS_REG)
644 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
645 (match_operand:HI 1 "general_operand" "ri,mr"))
647 "ix86_match_ccmode (insn, CCGOCmode)"
648 "cmp{w}\t{%1, %0|%0, %1}"
649 [(set_attr "type" "icmp")
650 (set_attr "mode" "HI")])
652 (define_insn "*cmphi_1"
653 [(set (reg FLAGS_REG)
654 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
655 (match_operand:HI 1 "general_operand" "ri,mr")))]
656 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
657 && ix86_match_ccmode (insn, CCmode)"
658 "cmp{w}\t{%1, %0|%0, %1}"
659 [(set_attr "type" "icmp")
660 (set_attr "mode" "HI")])
662 (define_insn "*cmpqi_ccno_1"
663 [(set (reg FLAGS_REG)
664 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
665 (match_operand:QI 1 "const0_operand" "n,n")))]
666 "ix86_match_ccmode (insn, CCNOmode)"
668 test{b}\t{%0, %0|%0, %0}
669 cmp{b}\t{$0, %0|%0, 0}"
670 [(set_attr "type" "test,icmp")
671 (set_attr "length_immediate" "0,1")
672 (set_attr "mode" "QI")])
674 (define_insn "*cmpqi_1"
675 [(set (reg FLAGS_REG)
676 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
677 (match_operand:QI 1 "general_operand" "qi,mq")))]
678 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
679 && ix86_match_ccmode (insn, CCmode)"
680 "cmp{b}\t{%1, %0|%0, %1}"
681 [(set_attr "type" "icmp")
682 (set_attr "mode" "QI")])
684 (define_insn "*cmpqi_minus_1"
685 [(set (reg FLAGS_REG)
686 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
687 (match_operand:QI 1 "general_operand" "qi,mq"))
689 "ix86_match_ccmode (insn, CCGOCmode)"
690 "cmp{b}\t{%1, %0|%0, %1}"
691 [(set_attr "type" "icmp")
692 (set_attr "mode" "QI")])
694 (define_insn "*cmpqi_ext_1"
695 [(set (reg FLAGS_REG)
697 (match_operand:QI 0 "general_operand" "Qm")
700 (match_operand 1 "ext_register_operand" "Q")
703 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
704 "cmp{b}\t{%h1, %0|%0, %h1}"
705 [(set_attr "type" "icmp")
706 (set_attr "mode" "QI")])
708 (define_insn "*cmpqi_ext_1_rex64"
709 [(set (reg FLAGS_REG)
711 (match_operand:QI 0 "register_operand" "Q")
714 (match_operand 1 "ext_register_operand" "Q")
717 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
718 "cmp{b}\t{%h1, %0|%0, %h1}"
719 [(set_attr "type" "icmp")
720 (set_attr "mode" "QI")])
722 (define_insn "*cmpqi_ext_2"
723 [(set (reg FLAGS_REG)
727 (match_operand 0 "ext_register_operand" "Q")
730 (match_operand:QI 1 "const0_operand" "n")))]
731 "ix86_match_ccmode (insn, CCNOmode)"
733 [(set_attr "type" "test")
734 (set_attr "length_immediate" "0")
735 (set_attr "mode" "QI")])
737 (define_expand "cmpqi_ext_3"
738 [(set (reg:CC FLAGS_REG)
742 (match_operand 0 "ext_register_operand" "")
745 (match_operand:QI 1 "general_operand" "")))]
749 (define_insn "cmpqi_ext_3_insn"
750 [(set (reg FLAGS_REG)
754 (match_operand 0 "ext_register_operand" "Q")
757 (match_operand:QI 1 "general_operand" "Qmn")))]
758 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
759 "cmp{b}\t{%1, %h0|%h0, %1}"
760 [(set_attr "type" "icmp")
761 (set_attr "mode" "QI")])
763 (define_insn "cmpqi_ext_3_insn_rex64"
764 [(set (reg FLAGS_REG)
768 (match_operand 0 "ext_register_operand" "Q")
771 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
772 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
773 "cmp{b}\t{%1, %h0|%h0, %1}"
774 [(set_attr "type" "icmp")
775 (set_attr "mode" "QI")])
777 (define_insn "*cmpqi_ext_4"
778 [(set (reg FLAGS_REG)
782 (match_operand 0 "ext_register_operand" "Q")
787 (match_operand 1 "ext_register_operand" "Q")
790 "ix86_match_ccmode (insn, CCmode)"
791 "cmp{b}\t{%h1, %h0|%h0, %h1}"
792 [(set_attr "type" "icmp")
793 (set_attr "mode" "QI")])
795 ;; These implement float point compares.
796 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
797 ;; which would allow mix and match FP modes on the compares. Which is what
798 ;; the old patterns did, but with many more of them.
800 (define_expand "cmpxf"
801 [(set (reg:CC FLAGS_REG)
802 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
803 (match_operand:XF 1 "nonmemory_operand" "")))]
806 ix86_compare_op0 = operands[0];
807 ix86_compare_op1 = operands[1];
811 (define_expand "cmpdf"
812 [(set (reg:CC FLAGS_REG)
813 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
814 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
815 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
817 ix86_compare_op0 = operands[0];
818 ix86_compare_op1 = operands[1];
822 (define_expand "cmpsf"
823 [(set (reg:CC FLAGS_REG)
824 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
825 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
826 "TARGET_80387 || TARGET_SSE_MATH"
828 ix86_compare_op0 = operands[0];
829 ix86_compare_op1 = operands[1];
833 ;; FP compares, step 1:
834 ;; Set the FP condition codes.
836 ;; CCFPmode compare with exceptions
837 ;; CCFPUmode compare with no exceptions
839 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
840 ;; used to manage the reg stack popping would not be preserved.
842 (define_insn "*cmpfp_0"
843 [(set (match_operand:HI 0 "register_operand" "=a")
846 (match_operand 1 "register_operand" "f")
847 (match_operand 2 "const0_operand" "X"))]
850 && FLOAT_MODE_P (GET_MODE (operands[1]))
851 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
852 "* return output_fp_compare (insn, operands, 0, 0);"
853 [(set_attr "type" "multi")
854 (set_attr "unit" "i387")
856 (cond [(match_operand:SF 1 "" "")
858 (match_operand:DF 1 "" "")
861 (const_string "XF")))])
863 (define_insn "*cmpfp_sf"
864 [(set (match_operand:HI 0 "register_operand" "=a")
867 (match_operand:SF 1 "register_operand" "f")
868 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
871 "* return output_fp_compare (insn, operands, 0, 0);"
872 [(set_attr "type" "multi")
873 (set_attr "unit" "i387")
874 (set_attr "mode" "SF")])
876 (define_insn "*cmpfp_df"
877 [(set (match_operand:HI 0 "register_operand" "=a")
880 (match_operand:DF 1 "register_operand" "f")
881 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
884 "* return output_fp_compare (insn, operands, 0, 0);"
885 [(set_attr "type" "multi")
886 (set_attr "unit" "i387")
887 (set_attr "mode" "DF")])
889 (define_insn "*cmpfp_xf"
890 [(set (match_operand:HI 0 "register_operand" "=a")
893 (match_operand:XF 1 "register_operand" "f")
894 (match_operand:XF 2 "register_operand" "f"))]
897 "* return output_fp_compare (insn, operands, 0, 0);"
898 [(set_attr "type" "multi")
899 (set_attr "unit" "i387")
900 (set_attr "mode" "XF")])
902 (define_insn "*cmpfp_u"
903 [(set (match_operand:HI 0 "register_operand" "=a")
906 (match_operand 1 "register_operand" "f")
907 (match_operand 2 "register_operand" "f"))]
910 && FLOAT_MODE_P (GET_MODE (operands[1]))
911 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
912 "* return output_fp_compare (insn, operands, 0, 1);"
913 [(set_attr "type" "multi")
914 (set_attr "unit" "i387")
916 (cond [(match_operand:SF 1 "" "")
918 (match_operand:DF 1 "" "")
921 (const_string "XF")))])
923 (define_insn "*cmpfp_<mode>"
924 [(set (match_operand:HI 0 "register_operand" "=a")
927 (match_operand 1 "register_operand" "f")
928 (match_operator 3 "float_operator"
929 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
931 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
932 && FLOAT_MODE_P (GET_MODE (operands[1]))
933 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
934 "* return output_fp_compare (insn, operands, 0, 0);"
935 [(set_attr "type" "multi")
936 (set_attr "unit" "i387")
937 (set_attr "fp_int_src" "true")
938 (set_attr "mode" "<MODE>")])
940 ;; FP compares, step 2
941 ;; Move the fpsw to ax.
943 (define_insn "x86_fnstsw_1"
944 [(set (match_operand:HI 0 "register_operand" "=a")
945 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
948 [(set_attr "length" "2")
949 (set_attr "mode" "SI")
950 (set_attr "unit" "i387")])
952 ;; FP compares, step 3
953 ;; Get ax into flags, general case.
955 (define_insn "x86_sahf_1"
956 [(set (reg:CC FLAGS_REG)
957 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
960 [(set_attr "length" "1")
961 (set_attr "athlon_decode" "vector")
962 (set_attr "mode" "SI")])
964 ;; Pentium Pro can do steps 1 through 3 in one go.
966 (define_insn "*cmpfp_i_mixed"
967 [(set (reg:CCFP FLAGS_REG)
968 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
969 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
971 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
972 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
973 "* return output_fp_compare (insn, operands, 1, 0);"
974 [(set_attr "type" "fcmp,ssecomi")
976 (if_then_else (match_operand:SF 1 "" "")
978 (const_string "DF")))
979 (set_attr "athlon_decode" "vector")])
981 (define_insn "*cmpfp_i_sse"
982 [(set (reg:CCFP FLAGS_REG)
983 (compare:CCFP (match_operand 0 "register_operand" "x")
984 (match_operand 1 "nonimmediate_operand" "xm")))]
986 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
987 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
988 "* return output_fp_compare (insn, operands, 1, 0);"
989 [(set_attr "type" "ssecomi")
991 (if_then_else (match_operand:SF 1 "" "")
993 (const_string "DF")))
994 (set_attr "athlon_decode" "vector")])
996 (define_insn "*cmpfp_i_i387"
997 [(set (reg:CCFP FLAGS_REG)
998 (compare:CCFP (match_operand 0 "register_operand" "f")
999 (match_operand 1 "register_operand" "f")))]
1000 "TARGET_80387 && TARGET_CMOVE
1001 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1002 && FLOAT_MODE_P (GET_MODE (operands[0]))
1003 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1004 "* return output_fp_compare (insn, operands, 1, 0);"
1005 [(set_attr "type" "fcmp")
1007 (cond [(match_operand:SF 1 "" "")
1009 (match_operand:DF 1 "" "")
1012 (const_string "XF")))
1013 (set_attr "athlon_decode" "vector")])
1015 (define_insn "*cmpfp_iu_mixed"
1016 [(set (reg:CCFPU FLAGS_REG)
1017 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1018 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1019 "TARGET_MIX_SSE_I387
1020 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022 "* return output_fp_compare (insn, operands, 1, 1);"
1023 [(set_attr "type" "fcmp,ssecomi")
1025 (if_then_else (match_operand:SF 1 "" "")
1027 (const_string "DF")))
1028 (set_attr "athlon_decode" "vector")])
1030 (define_insn "*cmpfp_iu_sse"
1031 [(set (reg:CCFPU FLAGS_REG)
1032 (compare:CCFPU (match_operand 0 "register_operand" "x")
1033 (match_operand 1 "nonimmediate_operand" "xm")))]
1035 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1036 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1037 "* return output_fp_compare (insn, operands, 1, 1);"
1038 [(set_attr "type" "ssecomi")
1040 (if_then_else (match_operand:SF 1 "" "")
1042 (const_string "DF")))
1043 (set_attr "athlon_decode" "vector")])
1045 (define_insn "*cmpfp_iu_387"
1046 [(set (reg:CCFPU FLAGS_REG)
1047 (compare:CCFPU (match_operand 0 "register_operand" "f")
1048 (match_operand 1 "register_operand" "f")))]
1049 "TARGET_80387 && TARGET_CMOVE
1050 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1051 && FLOAT_MODE_P (GET_MODE (operands[0]))
1052 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1053 "* return output_fp_compare (insn, operands, 1, 1);"
1054 [(set_attr "type" "fcmp")
1056 (cond [(match_operand:SF 1 "" "")
1058 (match_operand:DF 1 "" "")
1061 (const_string "XF")))
1062 (set_attr "athlon_decode" "vector")])
1064 ;; Move instructions.
1066 ;; General case of fullword move.
1068 (define_expand "movsi"
1069 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1070 (match_operand:SI 1 "general_operand" ""))]
1072 "ix86_expand_move (SImode, operands); DONE;")
1074 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1077 ;; %%% We don't use a post-inc memory reference because x86 is not a
1078 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1079 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1080 ;; targets without our curiosities, and it is just as easy to represent
1081 ;; this differently.
1083 (define_insn "*pushsi2"
1084 [(set (match_operand:SI 0 "push_operand" "=<")
1085 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1088 [(set_attr "type" "push")
1089 (set_attr "mode" "SI")])
1091 ;; For 64BIT abi we always round up to 8 bytes.
1092 (define_insn "*pushsi2_rex64"
1093 [(set (match_operand:SI 0 "push_operand" "=X")
1094 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1097 [(set_attr "type" "push")
1098 (set_attr "mode" "SI")])
1100 (define_insn "*pushsi2_prologue"
1101 [(set (match_operand:SI 0 "push_operand" "=<")
1102 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1103 (clobber (mem:BLK (scratch)))]
1106 [(set_attr "type" "push")
1107 (set_attr "mode" "SI")])
1109 (define_insn "*popsi1_epilogue"
1110 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1111 (mem:SI (reg:SI SP_REG)))
1112 (set (reg:SI SP_REG)
1113 (plus:SI (reg:SI SP_REG) (const_int 4)))
1114 (clobber (mem:BLK (scratch)))]
1117 [(set_attr "type" "pop")
1118 (set_attr "mode" "SI")])
1120 (define_insn "popsi1"
1121 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1122 (mem:SI (reg:SI SP_REG)))
1123 (set (reg:SI SP_REG)
1124 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1127 [(set_attr "type" "pop")
1128 (set_attr "mode" "SI")])
1130 (define_insn "*movsi_xor"
1131 [(set (match_operand:SI 0 "register_operand" "=r")
1132 (match_operand:SI 1 "const0_operand" "i"))
1133 (clobber (reg:CC FLAGS_REG))]
1134 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1135 "xor{l}\t{%0, %0|%0, %0}"
1136 [(set_attr "type" "alu1")
1137 (set_attr "mode" "SI")
1138 (set_attr "length_immediate" "0")])
1140 (define_insn "*movsi_or"
1141 [(set (match_operand:SI 0 "register_operand" "=r")
1142 (match_operand:SI 1 "immediate_operand" "i"))
1143 (clobber (reg:CC FLAGS_REG))]
1145 && operands[1] == constm1_rtx
1146 && (TARGET_PENTIUM || optimize_size)"
1148 operands[1] = constm1_rtx;
1149 return "or{l}\t{%1, %0|%0, %1}";
1151 [(set_attr "type" "alu1")
1152 (set_attr "mode" "SI")
1153 (set_attr "length_immediate" "1")])
1155 (define_insn "*movsi_1"
1156 [(set (match_operand:SI 0 "nonimmediate_operand"
1157 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1158 (match_operand:SI 1 "general_operand"
1159 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1160 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1162 switch (get_attr_type (insn))
1165 if (get_attr_mode (insn) == MODE_TI)
1166 return "pxor\t%0, %0";
1167 return "xorps\t%0, %0";
1170 switch (get_attr_mode (insn))
1173 return "movdqa\t{%1, %0|%0, %1}";
1175 return "movaps\t{%1, %0|%0, %1}";
1177 return "movd\t{%1, %0|%0, %1}";
1179 return "movss\t{%1, %0|%0, %1}";
1185 return "pxor\t%0, %0";
1188 if (get_attr_mode (insn) == MODE_DI)
1189 return "movq\t{%1, %0|%0, %1}";
1190 return "movd\t{%1, %0|%0, %1}";
1193 return "lea{l}\t{%1, %0|%0, %1}";
1196 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1197 return "mov{l}\t{%1, %0|%0, %1}";
1201 (cond [(eq_attr "alternative" "2")
1202 (const_string "mmxadd")
1203 (eq_attr "alternative" "3,4,5")
1204 (const_string "mmxmov")
1205 (eq_attr "alternative" "6")
1206 (const_string "sselog1")
1207 (eq_attr "alternative" "7,8,9,10,11")
1208 (const_string "ssemov")
1209 (match_operand:DI 1 "pic_32bit_operand" "")
1210 (const_string "lea")
1212 (const_string "imov")))
1214 (cond [(eq_attr "alternative" "2,3")
1216 (eq_attr "alternative" "6,7")
1218 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1219 (const_string "V4SF")
1220 (const_string "TI"))
1221 (and (eq_attr "alternative" "8,9,10,11")
1222 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1225 (const_string "SI")))])
1227 ;; Stores and loads of ax to arbitrary constant address.
1228 ;; We fake an second form of instruction to force reload to load address
1229 ;; into register when rax is not available
1230 (define_insn "*movabssi_1_rex64"
1231 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1232 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1233 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1235 movabs{l}\t{%1, %P0|%P0, %1}
1236 mov{l}\t{%1, %a0|%a0, %1}"
1237 [(set_attr "type" "imov")
1238 (set_attr "modrm" "0,*")
1239 (set_attr "length_address" "8,0")
1240 (set_attr "length_immediate" "0,*")
1241 (set_attr "memory" "store")
1242 (set_attr "mode" "SI")])
1244 (define_insn "*movabssi_2_rex64"
1245 [(set (match_operand:SI 0 "register_operand" "=a,r")
1246 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1247 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1249 movabs{l}\t{%P1, %0|%0, %P1}
1250 mov{l}\t{%a1, %0|%0, %a1}"
1251 [(set_attr "type" "imov")
1252 (set_attr "modrm" "0,*")
1253 (set_attr "length_address" "8,0")
1254 (set_attr "length_immediate" "0")
1255 (set_attr "memory" "load")
1256 (set_attr "mode" "SI")])
1258 (define_insn "*swapsi"
1259 [(set (match_operand:SI 0 "register_operand" "+r")
1260 (match_operand:SI 1 "register_operand" "+r"))
1265 [(set_attr "type" "imov")
1266 (set_attr "mode" "SI")
1267 (set_attr "pent_pair" "np")
1268 (set_attr "athlon_decode" "vector")])
1270 (define_expand "movhi"
1271 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1272 (match_operand:HI 1 "general_operand" ""))]
1274 "ix86_expand_move (HImode, operands); DONE;")
1276 (define_insn "*pushhi2"
1277 [(set (match_operand:HI 0 "push_operand" "=<,<")
1278 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1281 push{w}\t{|WORD PTR }%1
1283 [(set_attr "type" "push")
1284 (set_attr "mode" "HI")])
1286 ;; For 64BIT abi we always round up to 8 bytes.
1287 (define_insn "*pushhi2_rex64"
1288 [(set (match_operand:HI 0 "push_operand" "=X")
1289 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1292 [(set_attr "type" "push")
1293 (set_attr "mode" "QI")])
1295 (define_insn "*movhi_1"
1296 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1297 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1298 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1300 switch (get_attr_type (insn))
1303 /* movzwl is faster than movw on p2 due to partial word stalls,
1304 though not as fast as an aligned movl. */
1305 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1307 if (get_attr_mode (insn) == MODE_SI)
1308 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1310 return "mov{w}\t{%1, %0|%0, %1}";
1314 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1315 (const_string "imov")
1316 (and (eq_attr "alternative" "0")
1317 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1319 (eq (symbol_ref "TARGET_HIMODE_MATH")
1321 (const_string "imov")
1322 (and (eq_attr "alternative" "1,2")
1323 (match_operand:HI 1 "aligned_operand" ""))
1324 (const_string "imov")
1325 (and (ne (symbol_ref "TARGET_MOVX")
1327 (eq_attr "alternative" "0,2"))
1328 (const_string "imovx")
1330 (const_string "imov")))
1332 (cond [(eq_attr "type" "imovx")
1334 (and (eq_attr "alternative" "1,2")
1335 (match_operand:HI 1 "aligned_operand" ""))
1337 (and (eq_attr "alternative" "0")
1338 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1340 (eq (symbol_ref "TARGET_HIMODE_MATH")
1344 (const_string "HI")))])
1346 ;; Stores and loads of ax to arbitrary constant address.
1347 ;; We fake an second form of instruction to force reload to load address
1348 ;; into register when rax is not available
1349 (define_insn "*movabshi_1_rex64"
1350 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1351 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1352 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1354 movabs{w}\t{%1, %P0|%P0, %1}
1355 mov{w}\t{%1, %a0|%a0, %1}"
1356 [(set_attr "type" "imov")
1357 (set_attr "modrm" "0,*")
1358 (set_attr "length_address" "8,0")
1359 (set_attr "length_immediate" "0,*")
1360 (set_attr "memory" "store")
1361 (set_attr "mode" "HI")])
1363 (define_insn "*movabshi_2_rex64"
1364 [(set (match_operand:HI 0 "register_operand" "=a,r")
1365 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1366 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1368 movabs{w}\t{%P1, %0|%0, %P1}
1369 mov{w}\t{%a1, %0|%0, %a1}"
1370 [(set_attr "type" "imov")
1371 (set_attr "modrm" "0,*")
1372 (set_attr "length_address" "8,0")
1373 (set_attr "length_immediate" "0")
1374 (set_attr "memory" "load")
1375 (set_attr "mode" "HI")])
1377 (define_insn "*swaphi_1"
1378 [(set (match_operand:HI 0 "register_operand" "+r")
1379 (match_operand:HI 1 "register_operand" "+r"))
1382 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1384 [(set_attr "type" "imov")
1385 (set_attr "mode" "SI")
1386 (set_attr "pent_pair" "np")
1387 (set_attr "athlon_decode" "vector")])
1389 (define_insn "*swaphi_2"
1390 [(set (match_operand:HI 0 "register_operand" "+r")
1391 (match_operand:HI 1 "register_operand" "+r"))
1394 "TARGET_PARTIAL_REG_STALL"
1396 [(set_attr "type" "imov")
1397 (set_attr "mode" "HI")
1398 (set_attr "pent_pair" "np")
1399 (set_attr "athlon_decode" "vector")])
1401 (define_expand "movstricthi"
1402 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1403 (match_operand:HI 1 "general_operand" ""))]
1404 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1406 /* Don't generate memory->memory moves, go through a register */
1407 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1408 operands[1] = force_reg (HImode, operands[1]);
1411 (define_insn "*movstricthi_1"
1412 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1413 (match_operand:HI 1 "general_operand" "rn,m"))]
1414 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1415 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1416 "mov{w}\t{%1, %0|%0, %1}"
1417 [(set_attr "type" "imov")
1418 (set_attr "mode" "HI")])
1420 (define_insn "*movstricthi_xor"
1421 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1422 (match_operand:HI 1 "const0_operand" "i"))
1423 (clobber (reg:CC FLAGS_REG))]
1425 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1426 "xor{w}\t{%0, %0|%0, %0}"
1427 [(set_attr "type" "alu1")
1428 (set_attr "mode" "HI")
1429 (set_attr "length_immediate" "0")])
1431 (define_expand "movqi"
1432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1433 (match_operand:QI 1 "general_operand" ""))]
1435 "ix86_expand_move (QImode, operands); DONE;")
1437 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1438 ;; "push a byte". But actually we use pushw, which has the effect
1439 ;; of rounding the amount pushed up to a halfword.
1441 (define_insn "*pushqi2"
1442 [(set (match_operand:QI 0 "push_operand" "=X,X")
1443 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1446 push{w}\t{|word ptr }%1
1448 [(set_attr "type" "push")
1449 (set_attr "mode" "HI")])
1451 ;; For 64BIT abi we always round up to 8 bytes.
1452 (define_insn "*pushqi2_rex64"
1453 [(set (match_operand:QI 0 "push_operand" "=X")
1454 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1457 [(set_attr "type" "push")
1458 (set_attr "mode" "QI")])
1460 ;; Situation is quite tricky about when to choose full sized (SImode) move
1461 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1462 ;; partial register dependency machines (such as AMD Athlon), where QImode
1463 ;; moves issue extra dependency and for partial register stalls machines
1464 ;; that don't use QImode patterns (and QImode move cause stall on the next
1467 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1468 ;; register stall machines with, where we use QImode instructions, since
1469 ;; partial register stall can be caused there. Then we use movzx.
1470 (define_insn "*movqi_1"
1471 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1472 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1473 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1475 switch (get_attr_type (insn))
1478 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1479 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1481 if (get_attr_mode (insn) == MODE_SI)
1482 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1484 return "mov{b}\t{%1, %0|%0, %1}";
1488 (cond [(and (eq_attr "alternative" "5")
1489 (not (match_operand:QI 1 "aligned_operand" "")))
1490 (const_string "imovx")
1491 (ne (symbol_ref "optimize_size") (const_int 0))
1492 (const_string "imov")
1493 (and (eq_attr "alternative" "3")
1494 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1496 (eq (symbol_ref "TARGET_QIMODE_MATH")
1498 (const_string "imov")
1499 (eq_attr "alternative" "3,5")
1500 (const_string "imovx")
1501 (and (ne (symbol_ref "TARGET_MOVX")
1503 (eq_attr "alternative" "2"))
1504 (const_string "imovx")
1506 (const_string "imov")))
1508 (cond [(eq_attr "alternative" "3,4,5")
1510 (eq_attr "alternative" "6")
1512 (eq_attr "type" "imovx")
1514 (and (eq_attr "type" "imov")
1515 (and (eq_attr "alternative" "0,1")
1516 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1519 ;; Avoid partial register stalls when not using QImode arithmetic
1520 (and (eq_attr "type" "imov")
1521 (and (eq_attr "alternative" "0,1")
1522 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1524 (eq (symbol_ref "TARGET_QIMODE_MATH")
1528 (const_string "QI")))])
1530 (define_expand "reload_outqi"
1531 [(parallel [(match_operand:QI 0 "" "=m")
1532 (match_operand:QI 1 "register_operand" "r")
1533 (match_operand:QI 2 "register_operand" "=&q")])]
1537 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1539 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1540 if (! q_regs_operand (op1, QImode))
1542 emit_insn (gen_movqi (op2, op1));
1545 emit_insn (gen_movqi (op0, op1));
1549 (define_insn "*swapqi_1"
1550 [(set (match_operand:QI 0 "register_operand" "+r")
1551 (match_operand:QI 1 "register_operand" "+r"))
1554 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1556 [(set_attr "type" "imov")
1557 (set_attr "mode" "SI")
1558 (set_attr "pent_pair" "np")
1559 (set_attr "athlon_decode" "vector")])
1561 (define_insn "*swapqi_2"
1562 [(set (match_operand:QI 0 "register_operand" "+q")
1563 (match_operand:QI 1 "register_operand" "+q"))
1566 "TARGET_PARTIAL_REG_STALL"
1568 [(set_attr "type" "imov")
1569 (set_attr "mode" "QI")
1570 (set_attr "pent_pair" "np")
1571 (set_attr "athlon_decode" "vector")])
1573 (define_expand "movstrictqi"
1574 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1575 (match_operand:QI 1 "general_operand" ""))]
1576 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1578 /* Don't generate memory->memory moves, go through a register. */
1579 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1580 operands[1] = force_reg (QImode, operands[1]);
1583 (define_insn "*movstrictqi_1"
1584 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1585 (match_operand:QI 1 "general_operand" "*qn,m"))]
1586 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1587 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1588 "mov{b}\t{%1, %0|%0, %1}"
1589 [(set_attr "type" "imov")
1590 (set_attr "mode" "QI")])
1592 (define_insn "*movstrictqi_xor"
1593 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1594 (match_operand:QI 1 "const0_operand" "i"))
1595 (clobber (reg:CC FLAGS_REG))]
1596 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1597 "xor{b}\t{%0, %0|%0, %0}"
1598 [(set_attr "type" "alu1")
1599 (set_attr "mode" "QI")
1600 (set_attr "length_immediate" "0")])
1602 (define_insn "*movsi_extv_1"
1603 [(set (match_operand:SI 0 "register_operand" "=R")
1604 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1608 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1609 [(set_attr "type" "imovx")
1610 (set_attr "mode" "SI")])
1612 (define_insn "*movhi_extv_1"
1613 [(set (match_operand:HI 0 "register_operand" "=R")
1614 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1618 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1619 [(set_attr "type" "imovx")
1620 (set_attr "mode" "SI")])
1622 (define_insn "*movqi_extv_1"
1623 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1624 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1629 switch (get_attr_type (insn))
1632 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1634 return "mov{b}\t{%h1, %0|%0, %h1}";
1638 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1639 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1640 (ne (symbol_ref "TARGET_MOVX")
1642 (const_string "imovx")
1643 (const_string "imov")))
1645 (if_then_else (eq_attr "type" "imovx")
1647 (const_string "QI")))])
1649 (define_insn "*movqi_extv_1_rex64"
1650 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1651 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1656 switch (get_attr_type (insn))
1659 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1661 return "mov{b}\t{%h1, %0|%0, %h1}";
1665 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1666 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1667 (ne (symbol_ref "TARGET_MOVX")
1669 (const_string "imovx")
1670 (const_string "imov")))
1672 (if_then_else (eq_attr "type" "imovx")
1674 (const_string "QI")))])
1676 ;; Stores and loads of ax to arbitrary constant address.
1677 ;; We fake an second form of instruction to force reload to load address
1678 ;; into register when rax is not available
1679 (define_insn "*movabsqi_1_rex64"
1680 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1681 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1682 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1684 movabs{b}\t{%1, %P0|%P0, %1}
1685 mov{b}\t{%1, %a0|%a0, %1}"
1686 [(set_attr "type" "imov")
1687 (set_attr "modrm" "0,*")
1688 (set_attr "length_address" "8,0")
1689 (set_attr "length_immediate" "0,*")
1690 (set_attr "memory" "store")
1691 (set_attr "mode" "QI")])
1693 (define_insn "*movabsqi_2_rex64"
1694 [(set (match_operand:QI 0 "register_operand" "=a,r")
1695 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1696 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1698 movabs{b}\t{%P1, %0|%0, %P1}
1699 mov{b}\t{%a1, %0|%0, %a1}"
1700 [(set_attr "type" "imov")
1701 (set_attr "modrm" "0,*")
1702 (set_attr "length_address" "8,0")
1703 (set_attr "length_immediate" "0")
1704 (set_attr "memory" "load")
1705 (set_attr "mode" "QI")])
1707 (define_insn "*movdi_extzv_1"
1708 [(set (match_operand:DI 0 "register_operand" "=R")
1709 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1713 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1714 [(set_attr "type" "imovx")
1715 (set_attr "mode" "DI")])
1717 (define_insn "*movsi_extzv_1"
1718 [(set (match_operand:SI 0 "register_operand" "=R")
1719 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1723 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1724 [(set_attr "type" "imovx")
1725 (set_attr "mode" "SI")])
1727 (define_insn "*movqi_extzv_2"
1728 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1729 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1734 switch (get_attr_type (insn))
1737 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1739 return "mov{b}\t{%h1, %0|%0, %h1}";
1743 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1744 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1745 (ne (symbol_ref "TARGET_MOVX")
1747 (const_string "imovx")
1748 (const_string "imov")))
1750 (if_then_else (eq_attr "type" "imovx")
1752 (const_string "QI")))])
1754 (define_insn "*movqi_extzv_2_rex64"
1755 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1756 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1761 switch (get_attr_type (insn))
1764 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1766 return "mov{b}\t{%h1, %0|%0, %h1}";
1770 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1771 (ne (symbol_ref "TARGET_MOVX")
1773 (const_string "imovx")
1774 (const_string "imov")))
1776 (if_then_else (eq_attr "type" "imovx")
1778 (const_string "QI")))])
1780 (define_insn "movsi_insv_1"
1781 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1784 (match_operand:SI 1 "general_operand" "Qmn"))]
1786 "mov{b}\t{%b1, %h0|%h0, %b1}"
1787 [(set_attr "type" "imov")
1788 (set_attr "mode" "QI")])
1790 (define_insn "movdi_insv_1_rex64"
1791 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1794 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1796 "mov{b}\t{%b1, %h0|%h0, %b1}"
1797 [(set_attr "type" "imov")
1798 (set_attr "mode" "QI")])
1800 (define_insn "*movqi_insv_2"
1801 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1804 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1807 "mov{b}\t{%h1, %h0|%h0, %h1}"
1808 [(set_attr "type" "imov")
1809 (set_attr "mode" "QI")])
1811 (define_expand "movdi"
1812 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1813 (match_operand:DI 1 "general_operand" ""))]
1815 "ix86_expand_move (DImode, operands); DONE;")
1817 (define_insn "*pushdi"
1818 [(set (match_operand:DI 0 "push_operand" "=<")
1819 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1823 (define_insn "*pushdi2_rex64"
1824 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1825 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1830 [(set_attr "type" "push,multi")
1831 (set_attr "mode" "DI")])
1833 ;; Convert impossible pushes of immediate to existing instructions.
1834 ;; First try to get scratch register and go through it. In case this
1835 ;; fails, push sign extended lower part first and then overwrite
1836 ;; upper part by 32bit move.
1838 [(match_scratch:DI 2 "r")
1839 (set (match_operand:DI 0 "push_operand" "")
1840 (match_operand:DI 1 "immediate_operand" ""))]
1841 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1842 && !x86_64_immediate_operand (operands[1], DImode)"
1843 [(set (match_dup 2) (match_dup 1))
1844 (set (match_dup 0) (match_dup 2))]
1847 ;; We need to define this as both peepholer and splitter for case
1848 ;; peephole2 pass is not run.
1849 ;; "&& 1" is needed to keep it from matching the previous pattern.
1851 [(set (match_operand:DI 0 "push_operand" "")
1852 (match_operand:DI 1 "immediate_operand" ""))]
1853 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1854 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1855 [(set (match_dup 0) (match_dup 1))
1856 (set (match_dup 2) (match_dup 3))]
1857 "split_di (operands + 1, 1, operands + 2, operands + 3);
1858 operands[1] = gen_lowpart (DImode, operands[2]);
1859 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1864 [(set (match_operand:DI 0 "push_operand" "")
1865 (match_operand:DI 1 "immediate_operand" ""))]
1866 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1867 ? flow2_completed : reload_completed)
1868 && !symbolic_operand (operands[1], DImode)
1869 && !x86_64_immediate_operand (operands[1], DImode)"
1870 [(set (match_dup 0) (match_dup 1))
1871 (set (match_dup 2) (match_dup 3))]
1872 "split_di (operands + 1, 1, operands + 2, operands + 3);
1873 operands[1] = gen_lowpart (DImode, operands[2]);
1874 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1878 (define_insn "*pushdi2_prologue_rex64"
1879 [(set (match_operand:DI 0 "push_operand" "=<")
1880 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1881 (clobber (mem:BLK (scratch)))]
1884 [(set_attr "type" "push")
1885 (set_attr "mode" "DI")])
1887 (define_insn "*popdi1_epilogue_rex64"
1888 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1889 (mem:DI (reg:DI SP_REG)))
1890 (set (reg:DI SP_REG)
1891 (plus:DI (reg:DI SP_REG) (const_int 8)))
1892 (clobber (mem:BLK (scratch)))]
1895 [(set_attr "type" "pop")
1896 (set_attr "mode" "DI")])
1898 (define_insn "popdi1"
1899 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1900 (mem:DI (reg:DI SP_REG)))
1901 (set (reg:DI SP_REG)
1902 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1905 [(set_attr "type" "pop")
1906 (set_attr "mode" "DI")])
1908 (define_insn "*movdi_xor_rex64"
1909 [(set (match_operand:DI 0 "register_operand" "=r")
1910 (match_operand:DI 1 "const0_operand" "i"))
1911 (clobber (reg:CC FLAGS_REG))]
1912 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1913 && reload_completed"
1914 "xor{l}\t{%k0, %k0|%k0, %k0}"
1915 [(set_attr "type" "alu1")
1916 (set_attr "mode" "SI")
1917 (set_attr "length_immediate" "0")])
1919 (define_insn "*movdi_or_rex64"
1920 [(set (match_operand:DI 0 "register_operand" "=r")
1921 (match_operand:DI 1 "const_int_operand" "i"))
1922 (clobber (reg:CC FLAGS_REG))]
1923 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1925 && operands[1] == constm1_rtx"
1927 operands[1] = constm1_rtx;
1928 return "or{q}\t{%1, %0|%0, %1}";
1930 [(set_attr "type" "alu1")
1931 (set_attr "mode" "DI")
1932 (set_attr "length_immediate" "1")])
1934 (define_insn "*movdi_2"
1935 [(set (match_operand:DI 0 "nonimmediate_operand"
1936 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1937 (match_operand:DI 1 "general_operand"
1938 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1939 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1944 movq\t{%1, %0|%0, %1}
1945 movq\t{%1, %0|%0, %1}
1947 movq\t{%1, %0|%0, %1}
1948 movdqa\t{%1, %0|%0, %1}
1949 movq\t{%1, %0|%0, %1}
1951 movlps\t{%1, %0|%0, %1}
1952 movaps\t{%1, %0|%0, %1}
1953 movlps\t{%1, %0|%0, %1}"
1954 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1955 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1958 [(set (match_operand:DI 0 "push_operand" "")
1959 (match_operand:DI 1 "general_operand" ""))]
1960 "!TARGET_64BIT && reload_completed
1961 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1963 "ix86_split_long_move (operands); DONE;")
1965 ;; %%% This multiword shite has got to go.
1967 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1968 (match_operand:DI 1 "general_operand" ""))]
1969 "!TARGET_64BIT && reload_completed
1970 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1971 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1973 "ix86_split_long_move (operands); DONE;")
1975 (define_insn "*movdi_1_rex64"
1976 [(set (match_operand:DI 0 "nonimmediate_operand"
1977 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1978 (match_operand:DI 1 "general_operand"
1979 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1980 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1982 switch (get_attr_type (insn))
1985 if (which_alternative == 13)
1986 return "movq2dq\t{%1, %0|%0, %1}";
1988 return "movdq2q\t{%1, %0|%0, %1}";
1990 if (get_attr_mode (insn) == MODE_TI)
1991 return "movdqa\t{%1, %0|%0, %1}";
1994 /* Moves from and into integer register is done using movd opcode with
1996 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1997 return "movd\t{%1, %0|%0, %1}";
1998 return "movq\t{%1, %0|%0, %1}";
2001 return "pxor\t%0, %0";
2005 return "lea{q}\t{%a1, %0|%0, %a1}";
2007 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2008 if (get_attr_mode (insn) == MODE_SI)
2009 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2010 else if (which_alternative == 2)
2011 return "movabs{q}\t{%1, %0|%0, %1}";
2013 return "mov{q}\t{%1, %0|%0, %1}";
2017 (cond [(eq_attr "alternative" "5")
2018 (const_string "mmxadd")
2019 (eq_attr "alternative" "6,7,8")
2020 (const_string "mmxmov")
2021 (eq_attr "alternative" "9")
2022 (const_string "sselog1")
2023 (eq_attr "alternative" "10,11,12")
2024 (const_string "ssemov")
2025 (eq_attr "alternative" "13,14")
2026 (const_string "ssecvt")
2027 (eq_attr "alternative" "4")
2028 (const_string "multi")
2029 (match_operand:DI 1 "pic_32bit_operand" "")
2030 (const_string "lea")
2032 (const_string "imov")))
2033 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2034 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2035 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2037 ;; Stores and loads of ax to arbitrary constant address.
2038 ;; We fake an second form of instruction to force reload to load address
2039 ;; into register when rax is not available
2040 (define_insn "*movabsdi_1_rex64"
2041 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2042 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2043 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2045 movabs{q}\t{%1, %P0|%P0, %1}
2046 mov{q}\t{%1, %a0|%a0, %1}"
2047 [(set_attr "type" "imov")
2048 (set_attr "modrm" "0,*")
2049 (set_attr "length_address" "8,0")
2050 (set_attr "length_immediate" "0,*")
2051 (set_attr "memory" "store")
2052 (set_attr "mode" "DI")])
2054 (define_insn "*movabsdi_2_rex64"
2055 [(set (match_operand:DI 0 "register_operand" "=a,r")
2056 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2057 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2059 movabs{q}\t{%P1, %0|%0, %P1}
2060 mov{q}\t{%a1, %0|%0, %a1}"
2061 [(set_attr "type" "imov")
2062 (set_attr "modrm" "0,*")
2063 (set_attr "length_address" "8,0")
2064 (set_attr "length_immediate" "0")
2065 (set_attr "memory" "load")
2066 (set_attr "mode" "DI")])
2068 ;; Convert impossible stores of immediate to existing instructions.
2069 ;; First try to get scratch register and go through it. In case this
2070 ;; fails, move by 32bit parts.
2072 [(match_scratch:DI 2 "r")
2073 (set (match_operand:DI 0 "memory_operand" "")
2074 (match_operand:DI 1 "immediate_operand" ""))]
2075 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2076 && !x86_64_immediate_operand (operands[1], DImode)"
2077 [(set (match_dup 2) (match_dup 1))
2078 (set (match_dup 0) (match_dup 2))]
2081 ;; We need to define this as both peepholer and splitter for case
2082 ;; peephole2 pass is not run.
2083 ;; "&& 1" is needed to keep it from matching the previous pattern.
2085 [(set (match_operand:DI 0 "memory_operand" "")
2086 (match_operand:DI 1 "immediate_operand" ""))]
2087 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2088 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2089 [(set (match_dup 2) (match_dup 3))
2090 (set (match_dup 4) (match_dup 5))]
2091 "split_di (operands, 2, operands + 2, operands + 4);")
2094 [(set (match_operand:DI 0 "memory_operand" "")
2095 (match_operand:DI 1 "immediate_operand" ""))]
2096 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2097 ? flow2_completed : reload_completed)
2098 && !symbolic_operand (operands[1], DImode)
2099 && !x86_64_immediate_operand (operands[1], DImode)"
2100 [(set (match_dup 2) (match_dup 3))
2101 (set (match_dup 4) (match_dup 5))]
2102 "split_di (operands, 2, operands + 2, operands + 4);")
2104 (define_insn "*swapdi_rex64"
2105 [(set (match_operand:DI 0 "register_operand" "+r")
2106 (match_operand:DI 1 "register_operand" "+r"))
2111 [(set_attr "type" "imov")
2112 (set_attr "mode" "DI")
2113 (set_attr "pent_pair" "np")
2114 (set_attr "athlon_decode" "vector")])
2116 (define_expand "movti"
2117 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2118 (match_operand:TI 1 "nonimmediate_operand" ""))]
2119 "TARGET_SSE || TARGET_64BIT"
2122 ix86_expand_move (TImode, operands);
2124 ix86_expand_vector_move (TImode, operands);
2128 (define_insn "*movti_internal"
2129 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2130 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2131 "TARGET_SSE && !TARGET_64BIT
2132 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2134 switch (which_alternative)
2137 if (get_attr_mode (insn) == MODE_V4SF)
2138 return "xorps\t%0, %0";
2140 return "pxor\t%0, %0";
2143 if (get_attr_mode (insn) == MODE_V4SF)
2144 return "movaps\t{%1, %0|%0, %1}";
2146 return "movdqa\t{%1, %0|%0, %1}";
2151 [(set_attr "type" "sselog1,ssemov,ssemov")
2153 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2154 (ne (symbol_ref "optimize_size") (const_int 0)))
2155 (const_string "V4SF")
2156 (and (eq_attr "alternative" "2")
2157 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2159 (const_string "V4SF")]
2160 (const_string "TI")))])
2162 (define_insn "*movti_rex64"
2163 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2164 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2166 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2168 switch (which_alternative)
2174 if (get_attr_mode (insn) == MODE_V4SF)
2175 return "xorps\t%0, %0";
2177 return "pxor\t%0, %0";
2180 if (get_attr_mode (insn) == MODE_V4SF)
2181 return "movaps\t{%1, %0|%0, %1}";
2183 return "movdqa\t{%1, %0|%0, %1}";
2188 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2190 (cond [(eq_attr "alternative" "2,3")
2192 (ne (symbol_ref "optimize_size")
2194 (const_string "V4SF")
2195 (const_string "TI"))
2196 (eq_attr "alternative" "4")
2198 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2200 (ne (symbol_ref "optimize_size")
2202 (const_string "V4SF")
2203 (const_string "TI"))]
2204 (const_string "DI")))])
2207 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2208 (match_operand:TI 1 "general_operand" ""))]
2209 "reload_completed && !SSE_REG_P (operands[0])
2210 && !SSE_REG_P (operands[1])"
2212 "ix86_split_long_move (operands); DONE;")
2214 (define_expand "movsf"
2215 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2216 (match_operand:SF 1 "general_operand" ""))]
2218 "ix86_expand_move (SFmode, operands); DONE;")
2220 (define_insn "*pushsf"
2221 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2222 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2225 /* Anything else should be already split before reg-stack. */
2226 gcc_assert (which_alternative == 1);
2227 return "push{l}\t%1";
2229 [(set_attr "type" "multi,push,multi")
2230 (set_attr "unit" "i387,*,*")
2231 (set_attr "mode" "SF,SI,SF")])
2233 (define_insn "*pushsf_rex64"
2234 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2235 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2238 /* Anything else should be already split before reg-stack. */
2239 gcc_assert (which_alternative == 1);
2240 return "push{q}\t%q1";
2242 [(set_attr "type" "multi,push,multi")
2243 (set_attr "unit" "i387,*,*")
2244 (set_attr "mode" "SF,DI,SF")])
2247 [(set (match_operand:SF 0 "push_operand" "")
2248 (match_operand:SF 1 "memory_operand" ""))]
2250 && GET_CODE (operands[1]) == MEM
2251 && constant_pool_reference_p (operands[1])"
2254 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2257 ;; %%% Kill this when call knows how to work this out.
2259 [(set (match_operand:SF 0 "push_operand" "")
2260 (match_operand:SF 1 "any_fp_register_operand" ""))]
2262 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2263 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2266 [(set (match_operand:SF 0 "push_operand" "")
2267 (match_operand:SF 1 "any_fp_register_operand" ""))]
2269 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2270 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2272 (define_insn "*movsf_1"
2273 [(set (match_operand:SF 0 "nonimmediate_operand"
2274 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2275 (match_operand:SF 1 "general_operand"
2276 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2277 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2278 && (reload_in_progress || reload_completed
2279 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2280 || GET_CODE (operands[1]) != CONST_DOUBLE
2281 || memory_operand (operands[0], SFmode))"
2283 switch (which_alternative)
2286 return output_387_reg_move (insn, operands);
2289 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2290 return "fstp%z0\t%y0";
2292 return "fst%z0\t%y0";
2295 return standard_80387_constant_opcode (operands[1]);
2299 return "mov{l}\t{%1, %0|%0, %1}";
2301 if (get_attr_mode (insn) == MODE_TI)
2302 return "pxor\t%0, %0";
2304 return "xorps\t%0, %0";
2306 if (get_attr_mode (insn) == MODE_V4SF)
2307 return "movaps\t{%1, %0|%0, %1}";
2309 return "movss\t{%1, %0|%0, %1}";
2312 return "movss\t{%1, %0|%0, %1}";
2316 return "movd\t{%1, %0|%0, %1}";
2319 return "movq\t{%1, %0|%0, %1}";
2325 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2327 (cond [(eq_attr "alternative" "3,4,9,10")
2329 (eq_attr "alternative" "5")
2331 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2333 (ne (symbol_ref "TARGET_SSE2")
2335 (eq (symbol_ref "optimize_size")
2338 (const_string "V4SF"))
2339 /* For architectures resolving dependencies on
2340 whole SSE registers use APS move to break dependency
2341 chains, otherwise use short move to avoid extra work.
2343 Do the same for architectures resolving dependencies on
2344 the parts. While in DF mode it is better to always handle
2345 just register parts, the SF mode is different due to lack
2346 of instructions to load just part of the register. It is
2347 better to maintain the whole registers in single format
2348 to avoid problems on using packed logical operations. */
2349 (eq_attr "alternative" "6")
2351 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2353 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2355 (const_string "V4SF")
2356 (const_string "SF"))
2357 (eq_attr "alternative" "11")
2358 (const_string "DI")]
2359 (const_string "SF")))])
2361 (define_insn "*swapsf"
2362 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2363 (match_operand:SF 1 "fp_register_operand" "+f"))
2366 "reload_completed || TARGET_80387"
2368 if (STACK_TOP_P (operands[0]))
2373 [(set_attr "type" "fxch")
2374 (set_attr "mode" "SF")])
2376 (define_expand "movdf"
2377 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2378 (match_operand:DF 1 "general_operand" ""))]
2380 "ix86_expand_move (DFmode, operands); DONE;")
2382 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2383 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2384 ;; On the average, pushdf using integers can be still shorter. Allow this
2385 ;; pattern for optimize_size too.
2387 (define_insn "*pushdf_nointeger"
2388 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2389 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2390 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2392 /* This insn should be already split before reg-stack. */
2395 [(set_attr "type" "multi")
2396 (set_attr "unit" "i387,*,*,*")
2397 (set_attr "mode" "DF,SI,SI,DF")])
2399 (define_insn "*pushdf_integer"
2400 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2401 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2402 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2404 /* This insn should be already split before reg-stack. */
2407 [(set_attr "type" "multi")
2408 (set_attr "unit" "i387,*,*")
2409 (set_attr "mode" "DF,SI,DF")])
2411 ;; %%% Kill this when call knows how to work this out.
2413 [(set (match_operand:DF 0 "push_operand" "")
2414 (match_operand:DF 1 "any_fp_register_operand" ""))]
2415 "!TARGET_64BIT && reload_completed"
2416 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2417 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2421 [(set (match_operand:DF 0 "push_operand" "")
2422 (match_operand:DF 1 "any_fp_register_operand" ""))]
2423 "TARGET_64BIT && reload_completed"
2424 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2425 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2429 [(set (match_operand:DF 0 "push_operand" "")
2430 (match_operand:DF 1 "general_operand" ""))]
2433 "ix86_split_long_move (operands); DONE;")
2435 ;; Moving is usually shorter when only FP registers are used. This separate
2436 ;; movdf pattern avoids the use of integer registers for FP operations
2437 ;; when optimizing for size.
2439 (define_insn "*movdf_nointeger"
2440 [(set (match_operand:DF 0 "nonimmediate_operand"
2441 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2442 (match_operand:DF 1 "general_operand"
2443 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2444 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2445 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2446 && (reload_in_progress || reload_completed
2447 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2448 || GET_CODE (operands[1]) != CONST_DOUBLE
2449 || memory_operand (operands[0], DFmode))"
2451 switch (which_alternative)
2454 return output_387_reg_move (insn, operands);
2457 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2458 return "fstp%z0\t%y0";
2460 return "fst%z0\t%y0";
2463 return standard_80387_constant_opcode (operands[1]);
2469 switch (get_attr_mode (insn))
2472 return "xorps\t%0, %0";
2474 return "xorpd\t%0, %0";
2476 return "pxor\t%0, %0";
2483 switch (get_attr_mode (insn))
2486 return "movaps\t{%1, %0|%0, %1}";
2488 return "movapd\t{%1, %0|%0, %1}";
2490 return "movdqa\t{%1, %0|%0, %1}";
2492 return "movq\t{%1, %0|%0, %1}";
2494 return "movsd\t{%1, %0|%0, %1}";
2496 return "movlpd\t{%1, %0|%0, %1}";
2498 return "movlps\t{%1, %0|%0, %1}";
2507 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2509 (cond [(eq_attr "alternative" "0,1,2")
2511 (eq_attr "alternative" "3,4")
2514 /* For SSE1, we have many fewer alternatives. */
2515 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2516 (cond [(eq_attr "alternative" "5,6")
2517 (const_string "V4SF")
2519 (const_string "V2SF"))
2521 /* xorps is one byte shorter. */
2522 (eq_attr "alternative" "5")
2523 (cond [(ne (symbol_ref "optimize_size")
2525 (const_string "V4SF")
2526 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2530 (const_string "V2DF"))
2532 /* For architectures resolving dependencies on
2533 whole SSE registers use APD move to break dependency
2534 chains, otherwise use short move to avoid extra work.
2536 movaps encodes one byte shorter. */
2537 (eq_attr "alternative" "6")
2539 [(ne (symbol_ref "optimize_size")
2541 (const_string "V4SF")
2542 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2544 (const_string "V2DF")
2546 (const_string "DF"))
2547 /* For architectures resolving dependencies on register
2548 parts we may avoid extra work to zero out upper part
2550 (eq_attr "alternative" "7")
2552 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2554 (const_string "V1DF")
2555 (const_string "DF"))
2557 (const_string "DF")))])
2559 (define_insn "*movdf_integer"
2560 [(set (match_operand:DF 0 "nonimmediate_operand"
2561 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2562 (match_operand:DF 1 "general_operand"
2563 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2564 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2565 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2566 && (reload_in_progress || reload_completed
2567 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2568 || GET_CODE (operands[1]) != CONST_DOUBLE
2569 || memory_operand (operands[0], DFmode))"
2571 switch (which_alternative)
2574 return output_387_reg_move (insn, operands);
2577 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2578 return "fstp%z0\t%y0";
2580 return "fst%z0\t%y0";
2583 return standard_80387_constant_opcode (operands[1]);
2590 switch (get_attr_mode (insn))
2593 return "xorps\t%0, %0";
2595 return "xorpd\t%0, %0";
2597 return "pxor\t%0, %0";
2604 switch (get_attr_mode (insn))
2607 return "movaps\t{%1, %0|%0, %1}";
2609 return "movapd\t{%1, %0|%0, %1}";
2611 return "movdqa\t{%1, %0|%0, %1}";
2613 return "movq\t{%1, %0|%0, %1}";
2615 return "movsd\t{%1, %0|%0, %1}";
2617 return "movlpd\t{%1, %0|%0, %1}";
2619 return "movlps\t{%1, %0|%0, %1}";
2628 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2630 (cond [(eq_attr "alternative" "0,1,2")
2632 (eq_attr "alternative" "3,4")
2635 /* For SSE1, we have many fewer alternatives. */
2636 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2637 (cond [(eq_attr "alternative" "5,6")
2638 (const_string "V4SF")
2640 (const_string "V2SF"))
2642 /* xorps is one byte shorter. */
2643 (eq_attr "alternative" "5")
2644 (cond [(ne (symbol_ref "optimize_size")
2646 (const_string "V4SF")
2647 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2651 (const_string "V2DF"))
2653 /* For architectures resolving dependencies on
2654 whole SSE registers use APD move to break dependency
2655 chains, otherwise use short move to avoid extra work.
2657 movaps encodes one byte shorter. */
2658 (eq_attr "alternative" "6")
2660 [(ne (symbol_ref "optimize_size")
2662 (const_string "V4SF")
2663 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2665 (const_string "V2DF")
2667 (const_string "DF"))
2668 /* For architectures resolving dependencies on register
2669 parts we may avoid extra work to zero out upper part
2671 (eq_attr "alternative" "7")
2673 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2675 (const_string "V1DF")
2676 (const_string "DF"))
2678 (const_string "DF")))])
2681 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2682 (match_operand:DF 1 "general_operand" ""))]
2684 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2685 && ! (ANY_FP_REG_P (operands[0]) ||
2686 (GET_CODE (operands[0]) == SUBREG
2687 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2688 && ! (ANY_FP_REG_P (operands[1]) ||
2689 (GET_CODE (operands[1]) == SUBREG
2690 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2692 "ix86_split_long_move (operands); DONE;")
2694 (define_insn "*swapdf"
2695 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2696 (match_operand:DF 1 "fp_register_operand" "+f"))
2699 "reload_completed || TARGET_80387"
2701 if (STACK_TOP_P (operands[0]))
2706 [(set_attr "type" "fxch")
2707 (set_attr "mode" "DF")])
2709 (define_expand "movxf"
2710 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2711 (match_operand:XF 1 "general_operand" ""))]
2713 "ix86_expand_move (XFmode, operands); DONE;")
2715 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2716 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2717 ;; Pushing using integer instructions is longer except for constants
2718 ;; and direct memory references.
2719 ;; (assuming that any given constant is pushed only once, but this ought to be
2720 ;; handled elsewhere).
2722 (define_insn "*pushxf_nointeger"
2723 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2724 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2727 /* This insn should be already split before reg-stack. */
2730 [(set_attr "type" "multi")
2731 (set_attr "unit" "i387,*,*")
2732 (set_attr "mode" "XF,SI,SI")])
2734 (define_insn "*pushxf_integer"
2735 [(set (match_operand:XF 0 "push_operand" "=<,<")
2736 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2739 /* This insn should be already split before reg-stack. */
2742 [(set_attr "type" "multi")
2743 (set_attr "unit" "i387,*")
2744 (set_attr "mode" "XF,SI")])
2747 [(set (match_operand 0 "push_operand" "")
2748 (match_operand 1 "general_operand" ""))]
2750 && (GET_MODE (operands[0]) == XFmode
2751 || GET_MODE (operands[0]) == DFmode)
2752 && !ANY_FP_REG_P (operands[1])"
2754 "ix86_split_long_move (operands); DONE;")
2757 [(set (match_operand:XF 0 "push_operand" "")
2758 (match_operand:XF 1 "any_fp_register_operand" ""))]
2760 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2761 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2762 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2765 [(set (match_operand:XF 0 "push_operand" "")
2766 (match_operand:XF 1 "any_fp_register_operand" ""))]
2768 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2769 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2770 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2772 ;; Do not use integer registers when optimizing for size
2773 (define_insn "*movxf_nointeger"
2774 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2775 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2777 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2778 && (reload_in_progress || reload_completed
2779 || GET_CODE (operands[1]) != CONST_DOUBLE
2780 || memory_operand (operands[0], XFmode))"
2782 switch (which_alternative)
2785 return output_387_reg_move (insn, operands);
2788 /* There is no non-popping store to memory for XFmode. So if
2789 we need one, follow the store with a load. */
2790 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2791 return "fstp%z0\t%y0\;fld%z0\t%y0";
2793 return "fstp%z0\t%y0";
2796 return standard_80387_constant_opcode (operands[1]);
2804 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2805 (set_attr "mode" "XF,XF,XF,SI,SI")])
2807 (define_insn "*movxf_integer"
2808 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2809 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2811 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2812 && (reload_in_progress || reload_completed
2813 || GET_CODE (operands[1]) != CONST_DOUBLE
2814 || memory_operand (operands[0], XFmode))"
2816 switch (which_alternative)
2819 return output_387_reg_move (insn, operands);
2822 /* There is no non-popping store to memory for XFmode. So if
2823 we need one, follow the store with a load. */
2824 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825 return "fstp%z0\t%y0\;fld%z0\t%y0";
2827 return "fstp%z0\t%y0";
2830 return standard_80387_constant_opcode (operands[1]);
2839 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2840 (set_attr "mode" "XF,XF,XF,SI,SI")])
2843 [(set (match_operand 0 "nonimmediate_operand" "")
2844 (match_operand 1 "general_operand" ""))]
2846 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2847 && GET_MODE (operands[0]) == XFmode
2848 && ! (ANY_FP_REG_P (operands[0]) ||
2849 (GET_CODE (operands[0]) == SUBREG
2850 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2851 && ! (ANY_FP_REG_P (operands[1]) ||
2852 (GET_CODE (operands[1]) == SUBREG
2853 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2855 "ix86_split_long_move (operands); DONE;")
2858 [(set (match_operand 0 "register_operand" "")
2859 (match_operand 1 "memory_operand" ""))]
2861 && GET_CODE (operands[1]) == MEM
2862 && (GET_MODE (operands[0]) == XFmode
2863 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2864 && constant_pool_reference_p (operands[1])"
2865 [(set (match_dup 0) (match_dup 1))]
2867 rtx c = avoid_constant_pool_reference (operands[1]);
2868 rtx r = operands[0];
2870 if (GET_CODE (r) == SUBREG)
2875 if (!standard_sse_constant_p (c))
2878 else if (FP_REG_P (r))
2880 if (!standard_80387_constant_p (c))
2883 else if (MMX_REG_P (r))
2889 (define_insn "swapxf"
2890 [(set (match_operand:XF 0 "register_operand" "+f")
2891 (match_operand:XF 1 "register_operand" "+f"))
2896 if (STACK_TOP_P (operands[0]))
2901 [(set_attr "type" "fxch")
2902 (set_attr "mode" "XF")])
2904 (define_expand "movtf"
2905 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2906 (match_operand:TF 1 "nonimmediate_operand" ""))]
2909 ix86_expand_move (TFmode, operands);
2913 (define_insn "*movtf_internal"
2914 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2915 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2917 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2919 switch (which_alternative)
2925 if (get_attr_mode (insn) == MODE_V4SF)
2926 return "xorps\t%0, %0";
2928 return "pxor\t%0, %0";
2931 if (get_attr_mode (insn) == MODE_V4SF)
2932 return "movaps\t{%1, %0|%0, %1}";
2934 return "movdqa\t{%1, %0|%0, %1}";
2939 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2941 (cond [(eq_attr "alternative" "2,3")
2943 (ne (symbol_ref "optimize_size")
2945 (const_string "V4SF")
2946 (const_string "TI"))
2947 (eq_attr "alternative" "4")
2949 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2951 (ne (symbol_ref "optimize_size")
2953 (const_string "V4SF")
2954 (const_string "TI"))]
2955 (const_string "DI")))])
2958 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2959 (match_operand:TF 1 "general_operand" ""))]
2960 "reload_completed && !SSE_REG_P (operands[0])
2961 && !SSE_REG_P (operands[1])"
2963 "ix86_split_long_move (operands); DONE;")
2965 ;; Zero extension instructions
2967 (define_expand "zero_extendhisi2"
2968 [(set (match_operand:SI 0 "register_operand" "")
2969 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2972 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2974 operands[1] = force_reg (HImode, operands[1]);
2975 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2980 (define_insn "zero_extendhisi2_and"
2981 [(set (match_operand:SI 0 "register_operand" "=r")
2982 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2983 (clobber (reg:CC FLAGS_REG))]
2984 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2986 [(set_attr "type" "alu1")
2987 (set_attr "mode" "SI")])
2990 [(set (match_operand:SI 0 "register_operand" "")
2991 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2992 (clobber (reg:CC FLAGS_REG))]
2993 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2994 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2995 (clobber (reg:CC FLAGS_REG))])]
2998 (define_insn "*zero_extendhisi2_movzwl"
2999 [(set (match_operand:SI 0 "register_operand" "=r")
3000 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3001 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3002 "movz{wl|x}\t{%1, %0|%0, %1}"
3003 [(set_attr "type" "imovx")
3004 (set_attr "mode" "SI")])
3006 (define_expand "zero_extendqihi2"
3008 [(set (match_operand:HI 0 "register_operand" "")
3009 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3010 (clobber (reg:CC FLAGS_REG))])]
3014 (define_insn "*zero_extendqihi2_and"
3015 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3016 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3017 (clobber (reg:CC FLAGS_REG))]
3018 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3020 [(set_attr "type" "alu1")
3021 (set_attr "mode" "HI")])
3023 (define_insn "*zero_extendqihi2_movzbw_and"
3024 [(set (match_operand:HI 0 "register_operand" "=r,r")
3025 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3026 (clobber (reg:CC FLAGS_REG))]
3027 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3029 [(set_attr "type" "imovx,alu1")
3030 (set_attr "mode" "HI")])
3032 ; zero extend to SImode here to avoid partial register stalls
3033 (define_insn "*zero_extendqihi2_movzbl"
3034 [(set (match_operand:HI 0 "register_operand" "=r")
3035 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3036 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3037 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3038 [(set_attr "type" "imovx")
3039 (set_attr "mode" "SI")])
3041 ;; For the movzbw case strip only the clobber
3043 [(set (match_operand:HI 0 "register_operand" "")
3044 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3045 (clobber (reg:CC FLAGS_REG))]
3047 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3048 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3049 [(set (match_operand:HI 0 "register_operand" "")
3050 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3052 ;; When source and destination does not overlap, clear destination
3053 ;; first and then do the movb
3055 [(set (match_operand:HI 0 "register_operand" "")
3056 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3057 (clobber (reg:CC FLAGS_REG))]
3059 && ANY_QI_REG_P (operands[0])
3060 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3061 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3062 [(set (match_dup 0) (const_int 0))
3063 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3064 "operands[2] = gen_lowpart (QImode, operands[0]);")
3066 ;; Rest is handled by single and.
3068 [(set (match_operand:HI 0 "register_operand" "")
3069 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3070 (clobber (reg:CC FLAGS_REG))]
3072 && true_regnum (operands[0]) == true_regnum (operands[1])"
3073 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3074 (clobber (reg:CC FLAGS_REG))])]
3077 (define_expand "zero_extendqisi2"
3079 [(set (match_operand:SI 0 "register_operand" "")
3080 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3081 (clobber (reg:CC FLAGS_REG))])]
3085 (define_insn "*zero_extendqisi2_and"
3086 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3087 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3088 (clobber (reg:CC FLAGS_REG))]
3089 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3091 [(set_attr "type" "alu1")
3092 (set_attr "mode" "SI")])
3094 (define_insn "*zero_extendqisi2_movzbw_and"
3095 [(set (match_operand:SI 0 "register_operand" "=r,r")
3096 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3097 (clobber (reg:CC FLAGS_REG))]
3098 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3100 [(set_attr "type" "imovx,alu1")
3101 (set_attr "mode" "SI")])
3103 (define_insn "*zero_extendqisi2_movzbw"
3104 [(set (match_operand:SI 0 "register_operand" "=r")
3105 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3106 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3107 "movz{bl|x}\t{%1, %0|%0, %1}"
3108 [(set_attr "type" "imovx")
3109 (set_attr "mode" "SI")])
3111 ;; For the movzbl case strip only the clobber
3113 [(set (match_operand:SI 0 "register_operand" "")
3114 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3115 (clobber (reg:CC FLAGS_REG))]
3117 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3118 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3120 (zero_extend:SI (match_dup 1)))])
3122 ;; When source and destination does not overlap, clear destination
3123 ;; first and then do the movb
3125 [(set (match_operand:SI 0 "register_operand" "")
3126 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3127 (clobber (reg:CC FLAGS_REG))]
3129 && ANY_QI_REG_P (operands[0])
3130 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3131 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3132 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3133 [(set (match_dup 0) (const_int 0))
3134 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3135 "operands[2] = gen_lowpart (QImode, operands[0]);")
3137 ;; Rest is handled by single and.
3139 [(set (match_operand:SI 0 "register_operand" "")
3140 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3141 (clobber (reg:CC FLAGS_REG))]
3143 && true_regnum (operands[0]) == true_regnum (operands[1])"
3144 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3145 (clobber (reg:CC FLAGS_REG))])]
3148 ;; %%% Kill me once multi-word ops are sane.
3149 (define_expand "zero_extendsidi2"
3150 [(set (match_operand:DI 0 "register_operand" "=r")
3151 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3155 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3160 (define_insn "zero_extendsidi2_32"
3161 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3162 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3163 (clobber (reg:CC FLAGS_REG))]
3169 movd\t{%1, %0|%0, %1}
3170 movd\t{%1, %0|%0, %1}"
3171 [(set_attr "mode" "SI,SI,SI,DI,TI")
3172 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3174 (define_insn "zero_extendsidi2_rex64"
3175 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3176 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3179 mov\t{%k1, %k0|%k0, %k1}
3181 movd\t{%1, %0|%0, %1}
3182 movd\t{%1, %0|%0, %1}"
3183 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3184 (set_attr "mode" "SI,DI,SI,SI")])
3187 [(set (match_operand:DI 0 "memory_operand" "")
3188 (zero_extend:DI (match_dup 0)))]
3190 [(set (match_dup 4) (const_int 0))]
3191 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3194 [(set (match_operand:DI 0 "register_operand" "")
3195 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3196 (clobber (reg:CC FLAGS_REG))]
3197 "!TARGET_64BIT && reload_completed
3198 && true_regnum (operands[0]) == true_regnum (operands[1])"
3199 [(set (match_dup 4) (const_int 0))]
3200 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3203 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3204 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3205 (clobber (reg:CC FLAGS_REG))]
3206 "!TARGET_64BIT && reload_completed
3207 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3208 [(set (match_dup 3) (match_dup 1))
3209 (set (match_dup 4) (const_int 0))]
3210 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3212 (define_insn "zero_extendhidi2"
3213 [(set (match_operand:DI 0 "register_operand" "=r")
3214 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3216 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3217 [(set_attr "type" "imovx")
3218 (set_attr "mode" "DI")])
3220 (define_insn "zero_extendqidi2"
3221 [(set (match_operand:DI 0 "register_operand" "=r")
3222 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3224 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3225 [(set_attr "type" "imovx")
3226 (set_attr "mode" "DI")])
3228 ;; Sign extension instructions
3230 (define_expand "extendsidi2"
3231 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3232 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3233 (clobber (reg:CC FLAGS_REG))
3234 (clobber (match_scratch:SI 2 ""))])]
3239 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3244 (define_insn "*extendsidi2_1"
3245 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3246 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3247 (clobber (reg:CC FLAGS_REG))
3248 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3252 (define_insn "extendsidi2_rex64"
3253 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3254 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3258 movs{lq|x}\t{%1,%0|%0, %1}"
3259 [(set_attr "type" "imovx")
3260 (set_attr "mode" "DI")
3261 (set_attr "prefix_0f" "0")
3262 (set_attr "modrm" "0,1")])
3264 (define_insn "extendhidi2"
3265 [(set (match_operand:DI 0 "register_operand" "=r")
3266 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3268 "movs{wq|x}\t{%1,%0|%0, %1}"
3269 [(set_attr "type" "imovx")
3270 (set_attr "mode" "DI")])
3272 (define_insn "extendqidi2"
3273 [(set (match_operand:DI 0 "register_operand" "=r")
3274 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3276 "movs{bq|x}\t{%1,%0|%0, %1}"
3277 [(set_attr "type" "imovx")
3278 (set_attr "mode" "DI")])
3280 ;; Extend to memory case when source register does die.
3282 [(set (match_operand:DI 0 "memory_operand" "")
3283 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3284 (clobber (reg:CC FLAGS_REG))
3285 (clobber (match_operand:SI 2 "register_operand" ""))]
3287 && dead_or_set_p (insn, operands[1])
3288 && !reg_mentioned_p (operands[1], operands[0]))"
3289 [(set (match_dup 3) (match_dup 1))
3290 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3291 (clobber (reg:CC FLAGS_REG))])
3292 (set (match_dup 4) (match_dup 1))]
3293 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3295 ;; Extend to memory case when source register does not die.
3297 [(set (match_operand:DI 0 "memory_operand" "")
3298 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3299 (clobber (reg:CC FLAGS_REG))
3300 (clobber (match_operand:SI 2 "register_operand" ""))]
3304 split_di (&operands[0], 1, &operands[3], &operands[4]);
3306 emit_move_insn (operands[3], operands[1]);
3308 /* Generate a cltd if possible and doing so it profitable. */
3309 if (true_regnum (operands[1]) == 0
3310 && true_regnum (operands[2]) == 1
3311 && (optimize_size || TARGET_USE_CLTD))
3313 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3317 emit_move_insn (operands[2], operands[1]);
3318 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3320 emit_move_insn (operands[4], operands[2]);
3324 ;; Extend to register case. Optimize case where source and destination
3325 ;; registers match and cases where we can use cltd.
3327 [(set (match_operand:DI 0 "register_operand" "")
3328 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3329 (clobber (reg:CC FLAGS_REG))
3330 (clobber (match_scratch:SI 2 ""))]
3334 split_di (&operands[0], 1, &operands[3], &operands[4]);
3336 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3337 emit_move_insn (operands[3], operands[1]);
3339 /* Generate a cltd if possible and doing so it profitable. */
3340 if (true_regnum (operands[3]) == 0
3341 && (optimize_size || TARGET_USE_CLTD))
3343 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3347 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3348 emit_move_insn (operands[4], operands[1]);
3350 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3354 (define_insn "extendhisi2"
3355 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3356 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3359 switch (get_attr_prefix_0f (insn))
3362 return "{cwtl|cwde}";
3364 return "movs{wl|x}\t{%1,%0|%0, %1}";
3367 [(set_attr "type" "imovx")
3368 (set_attr "mode" "SI")
3369 (set (attr "prefix_0f")
3370 ;; movsx is short decodable while cwtl is vector decoded.
3371 (if_then_else (and (eq_attr "cpu" "!k6")
3372 (eq_attr "alternative" "0"))
3374 (const_string "1")))
3376 (if_then_else (eq_attr "prefix_0f" "0")